1*67e74705SXin Li //===--- ToolChains.cpp - ToolChain Implementations -------------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "ToolChains.h"
11*67e74705SXin Li #include "clang/Basic/Cuda.h"
12*67e74705SXin Li #include "clang/Basic/ObjCRuntime.h"
13*67e74705SXin Li #include "clang/Basic/Version.h"
14*67e74705SXin Li #include "clang/Basic/VirtualFileSystem.h"
15*67e74705SXin Li #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
16*67e74705SXin Li #include "clang/Driver/Compilation.h"
17*67e74705SXin Li #include "clang/Driver/Driver.h"
18*67e74705SXin Li #include "clang/Driver/DriverDiagnostic.h"
19*67e74705SXin Li #include "clang/Driver/Options.h"
20*67e74705SXin Li #include "clang/Driver/SanitizerArgs.h"
21*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
22*67e74705SXin Li #include "llvm/ADT/SmallString.h"
23*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
24*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
25*67e74705SXin Li #include "llvm/Option/Arg.h"
26*67e74705SXin Li #include "llvm/Option/ArgList.h"
27*67e74705SXin Li #include "llvm/Option/OptTable.h"
28*67e74705SXin Li #include "llvm/Option/Option.h"
29*67e74705SXin Li #include "llvm/ProfileData/InstrProf.h"
30*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
31*67e74705SXin Li #include "llvm/Support/FileSystem.h"
32*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
33*67e74705SXin Li #include "llvm/Support/Path.h"
34*67e74705SXin Li #include "llvm/Support/Program.h"
35*67e74705SXin Li #include "llvm/Support/TargetParser.h"
36*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
37*67e74705SXin Li #include <cstdlib> // ::getenv
38*67e74705SXin Li #include <system_error>
39*67e74705SXin Li
40*67e74705SXin Li using namespace clang::driver;
41*67e74705SXin Li using namespace clang::driver::toolchains;
42*67e74705SXin Li using namespace clang;
43*67e74705SXin Li using namespace llvm::opt;
44*67e74705SXin Li
MachO(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)45*67e74705SXin Li MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
46*67e74705SXin Li : ToolChain(D, Triple, Args) {
47*67e74705SXin Li // We expect 'as', 'ld', etc. to be adjacent to our install dir.
48*67e74705SXin Li getProgramPaths().push_back(getDriver().getInstalledDir());
49*67e74705SXin Li if (getDriver().getInstalledDir() != getDriver().Dir)
50*67e74705SXin Li getProgramPaths().push_back(getDriver().Dir);
51*67e74705SXin Li }
52*67e74705SXin Li
53*67e74705SXin Li /// Darwin - Darwin tool chain for i386 and x86_64.
Darwin(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)54*67e74705SXin Li Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
55*67e74705SXin Li : MachO(D, Triple, Args), TargetInitialized(false) {}
56*67e74705SXin Li
LookupTypeForExtension(const char * Ext) const57*67e74705SXin Li types::ID MachO::LookupTypeForExtension(const char *Ext) const {
58*67e74705SXin Li types::ID Ty = types::lookupTypeForExtension(Ext);
59*67e74705SXin Li
60*67e74705SXin Li // Darwin always preprocesses assembly files (unless -x is used explicitly).
61*67e74705SXin Li if (Ty == types::TY_PP_Asm)
62*67e74705SXin Li return types::TY_Asm;
63*67e74705SXin Li
64*67e74705SXin Li return Ty;
65*67e74705SXin Li }
66*67e74705SXin Li
HasNativeLLVMSupport() const67*67e74705SXin Li bool MachO::HasNativeLLVMSupport() const { return true; }
68*67e74705SXin Li
GetDefaultCXXStdlibType() const69*67e74705SXin Li ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
70*67e74705SXin Li // Default to use libc++ on OS X 10.9+ and iOS 7+.
71*67e74705SXin Li if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
72*67e74705SXin Li (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
73*67e74705SXin Li isTargetWatchOSBased())
74*67e74705SXin Li return ToolChain::CST_Libcxx;
75*67e74705SXin Li
76*67e74705SXin Li return ToolChain::CST_Libstdcxx;
77*67e74705SXin Li }
78*67e74705SXin Li
79*67e74705SXin Li /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
getDefaultObjCRuntime(bool isNonFragile) const80*67e74705SXin Li ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
81*67e74705SXin Li if (isTargetWatchOSBased())
82*67e74705SXin Li return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
83*67e74705SXin Li if (isTargetIOSBased())
84*67e74705SXin Li return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
85*67e74705SXin Li if (isNonFragile)
86*67e74705SXin Li return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
87*67e74705SXin Li return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
88*67e74705SXin Li }
89*67e74705SXin Li
90*67e74705SXin Li /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
hasBlocksRuntime() const91*67e74705SXin Li bool Darwin::hasBlocksRuntime() const {
92*67e74705SXin Li if (isTargetWatchOSBased())
93*67e74705SXin Li return true;
94*67e74705SXin Li else if (isTargetIOSBased())
95*67e74705SXin Li return !isIPhoneOSVersionLT(3, 2);
96*67e74705SXin Li else {
97*67e74705SXin Li assert(isTargetMacOS() && "unexpected darwin target");
98*67e74705SXin Li return !isMacosxVersionLT(10, 6);
99*67e74705SXin Li }
100*67e74705SXin Li }
101*67e74705SXin Li
102*67e74705SXin Li // This is just a MachO name translation routine and there's no
103*67e74705SXin Li // way to join this into ARMTargetParser without breaking all
104*67e74705SXin Li // other assumptions. Maybe MachO should consider standardising
105*67e74705SXin Li // their nomenclature.
ArmMachOArchName(StringRef Arch)106*67e74705SXin Li static const char *ArmMachOArchName(StringRef Arch) {
107*67e74705SXin Li return llvm::StringSwitch<const char *>(Arch)
108*67e74705SXin Li .Case("armv6k", "armv6")
109*67e74705SXin Li .Case("armv6m", "armv6m")
110*67e74705SXin Li .Case("armv5tej", "armv5")
111*67e74705SXin Li .Case("xscale", "xscale")
112*67e74705SXin Li .Case("armv4t", "armv4t")
113*67e74705SXin Li .Case("armv7", "armv7")
114*67e74705SXin Li .Cases("armv7a", "armv7-a", "armv7")
115*67e74705SXin Li .Cases("armv7r", "armv7-r", "armv7")
116*67e74705SXin Li .Cases("armv7em", "armv7e-m", "armv7em")
117*67e74705SXin Li .Cases("armv7k", "armv7-k", "armv7k")
118*67e74705SXin Li .Cases("armv7m", "armv7-m", "armv7m")
119*67e74705SXin Li .Cases("armv7s", "armv7-s", "armv7s")
120*67e74705SXin Li .Default(nullptr);
121*67e74705SXin Li }
122*67e74705SXin Li
ArmMachOArchNameCPU(StringRef CPU)123*67e74705SXin Li static const char *ArmMachOArchNameCPU(StringRef CPU) {
124*67e74705SXin Li unsigned ArchKind = llvm::ARM::parseCPUArch(CPU);
125*67e74705SXin Li if (ArchKind == llvm::ARM::AK_INVALID)
126*67e74705SXin Li return nullptr;
127*67e74705SXin Li StringRef Arch = llvm::ARM::getArchName(ArchKind);
128*67e74705SXin Li
129*67e74705SXin Li // FIXME: Make sure this MachO triple mangling is really necessary.
130*67e74705SXin Li // ARMv5* normalises to ARMv5.
131*67e74705SXin Li if (Arch.startswith("armv5"))
132*67e74705SXin Li Arch = Arch.substr(0, 5);
133*67e74705SXin Li // ARMv6*, except ARMv6M, normalises to ARMv6.
134*67e74705SXin Li else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
135*67e74705SXin Li Arch = Arch.substr(0, 5);
136*67e74705SXin Li // ARMv7A normalises to ARMv7.
137*67e74705SXin Li else if (Arch.endswith("v7a"))
138*67e74705SXin Li Arch = Arch.substr(0, 5);
139*67e74705SXin Li return Arch.data();
140*67e74705SXin Li }
141*67e74705SXin Li
isSoftFloatABI(const ArgList & Args)142*67e74705SXin Li static bool isSoftFloatABI(const ArgList &Args) {
143*67e74705SXin Li Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
144*67e74705SXin Li options::OPT_mfloat_abi_EQ);
145*67e74705SXin Li if (!A)
146*67e74705SXin Li return false;
147*67e74705SXin Li
148*67e74705SXin Li return A->getOption().matches(options::OPT_msoft_float) ||
149*67e74705SXin Li (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
150*67e74705SXin Li A->getValue() == StringRef("soft"));
151*67e74705SXin Li }
152*67e74705SXin Li
getMachOArchName(const ArgList & Args) const153*67e74705SXin Li StringRef MachO::getMachOArchName(const ArgList &Args) const {
154*67e74705SXin Li switch (getTriple().getArch()) {
155*67e74705SXin Li default:
156*67e74705SXin Li return getDefaultUniversalArchName();
157*67e74705SXin Li
158*67e74705SXin Li case llvm::Triple::aarch64:
159*67e74705SXin Li return "arm64";
160*67e74705SXin Li
161*67e74705SXin Li case llvm::Triple::thumb:
162*67e74705SXin Li case llvm::Triple::arm:
163*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
164*67e74705SXin Li if (const char *Arch = ArmMachOArchName(A->getValue()))
165*67e74705SXin Li return Arch;
166*67e74705SXin Li
167*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
168*67e74705SXin Li if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
169*67e74705SXin Li return Arch;
170*67e74705SXin Li
171*67e74705SXin Li return "arm";
172*67e74705SXin Li }
173*67e74705SXin Li }
174*67e74705SXin Li
~Darwin()175*67e74705SXin Li Darwin::~Darwin() {}
176*67e74705SXin Li
~MachO()177*67e74705SXin Li MachO::~MachO() {}
178*67e74705SXin Li
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const179*67e74705SXin Li std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args,
180*67e74705SXin Li types::ID InputType) const {
181*67e74705SXin Li llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
182*67e74705SXin Li
183*67e74705SXin Li return Triple.getTriple();
184*67e74705SXin Li }
185*67e74705SXin Li
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const186*67e74705SXin Li std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
187*67e74705SXin Li types::ID InputType) const {
188*67e74705SXin Li llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
189*67e74705SXin Li
190*67e74705SXin Li // If the target isn't initialized (e.g., an unknown Darwin platform, return
191*67e74705SXin Li // the default triple).
192*67e74705SXin Li if (!isTargetInitialized())
193*67e74705SXin Li return Triple.getTriple();
194*67e74705SXin Li
195*67e74705SXin Li SmallString<16> Str;
196*67e74705SXin Li if (isTargetWatchOSBased())
197*67e74705SXin Li Str += "watchos";
198*67e74705SXin Li else if (isTargetTvOSBased())
199*67e74705SXin Li Str += "tvos";
200*67e74705SXin Li else if (isTargetIOSBased())
201*67e74705SXin Li Str += "ios";
202*67e74705SXin Li else
203*67e74705SXin Li Str += "macosx";
204*67e74705SXin Li Str += getTargetVersion().getAsString();
205*67e74705SXin Li Triple.setOSName(Str);
206*67e74705SXin Li
207*67e74705SXin Li return Triple.getTriple();
208*67e74705SXin Li }
209*67e74705SXin Li
anchor()210*67e74705SXin Li void Generic_ELF::anchor() {}
211*67e74705SXin Li
getTool(Action::ActionClass AC) const212*67e74705SXin Li Tool *MachO::getTool(Action::ActionClass AC) const {
213*67e74705SXin Li switch (AC) {
214*67e74705SXin Li case Action::LipoJobClass:
215*67e74705SXin Li if (!Lipo)
216*67e74705SXin Li Lipo.reset(new tools::darwin::Lipo(*this));
217*67e74705SXin Li return Lipo.get();
218*67e74705SXin Li case Action::DsymutilJobClass:
219*67e74705SXin Li if (!Dsymutil)
220*67e74705SXin Li Dsymutil.reset(new tools::darwin::Dsymutil(*this));
221*67e74705SXin Li return Dsymutil.get();
222*67e74705SXin Li case Action::VerifyDebugInfoJobClass:
223*67e74705SXin Li if (!VerifyDebug)
224*67e74705SXin Li VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
225*67e74705SXin Li return VerifyDebug.get();
226*67e74705SXin Li default:
227*67e74705SXin Li return ToolChain::getTool(AC);
228*67e74705SXin Li }
229*67e74705SXin Li }
230*67e74705SXin Li
buildLinker() const231*67e74705SXin Li Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
232*67e74705SXin Li
buildAssembler() const233*67e74705SXin Li Tool *MachO::buildAssembler() const {
234*67e74705SXin Li return new tools::darwin::Assembler(*this);
235*67e74705SXin Li }
236*67e74705SXin Li
DarwinClang(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)237*67e74705SXin Li DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
238*67e74705SXin Li const ArgList &Args)
239*67e74705SXin Li : Darwin(D, Triple, Args) {}
240*67e74705SXin Li
addClangWarningOptions(ArgStringList & CC1Args) const241*67e74705SXin Li void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
242*67e74705SXin Li // For modern targets, promote certain warnings to errors.
243*67e74705SXin Li if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
244*67e74705SXin Li // Always enable -Wdeprecated-objc-isa-usage and promote it
245*67e74705SXin Li // to an error.
246*67e74705SXin Li CC1Args.push_back("-Wdeprecated-objc-isa-usage");
247*67e74705SXin Li CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
248*67e74705SXin Li
249*67e74705SXin Li // For iOS and watchOS, also error about implicit function declarations,
250*67e74705SXin Li // as that can impact calling conventions.
251*67e74705SXin Li if (!isTargetMacOS())
252*67e74705SXin Li CC1Args.push_back("-Werror=implicit-function-declaration");
253*67e74705SXin Li }
254*67e74705SXin Li }
255*67e74705SXin Li
256*67e74705SXin Li /// \brief Determine whether Objective-C automated reference counting is
257*67e74705SXin Li /// enabled.
isObjCAutoRefCount(const ArgList & Args)258*67e74705SXin Li static bool isObjCAutoRefCount(const ArgList &Args) {
259*67e74705SXin Li return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
260*67e74705SXin Li }
261*67e74705SXin Li
AddLinkARCArgs(const ArgList & Args,ArgStringList & CmdArgs) const262*67e74705SXin Li void DarwinClang::AddLinkARCArgs(const ArgList &Args,
263*67e74705SXin Li ArgStringList &CmdArgs) const {
264*67e74705SXin Li // Avoid linking compatibility stubs on i386 mac.
265*67e74705SXin Li if (isTargetMacOS() && getArch() == llvm::Triple::x86)
266*67e74705SXin Li return;
267*67e74705SXin Li
268*67e74705SXin Li ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
269*67e74705SXin Li
270*67e74705SXin Li if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
271*67e74705SXin Li runtime.hasSubscripting())
272*67e74705SXin Li return;
273*67e74705SXin Li
274*67e74705SXin Li CmdArgs.push_back("-force_load");
275*67e74705SXin Li SmallString<128> P(getDriver().ClangExecutable);
276*67e74705SXin Li llvm::sys::path::remove_filename(P); // 'clang'
277*67e74705SXin Li llvm::sys::path::remove_filename(P); // 'bin'
278*67e74705SXin Li llvm::sys::path::append(P, "lib", "arc", "libarclite_");
279*67e74705SXin Li // Mash in the platform.
280*67e74705SXin Li if (isTargetWatchOSSimulator())
281*67e74705SXin Li P += "watchsimulator";
282*67e74705SXin Li else if (isTargetWatchOS())
283*67e74705SXin Li P += "watchos";
284*67e74705SXin Li else if (isTargetTvOSSimulator())
285*67e74705SXin Li P += "appletvsimulator";
286*67e74705SXin Li else if (isTargetTvOS())
287*67e74705SXin Li P += "appletvos";
288*67e74705SXin Li else if (isTargetIOSSimulator())
289*67e74705SXin Li P += "iphonesimulator";
290*67e74705SXin Li else if (isTargetIPhoneOS())
291*67e74705SXin Li P += "iphoneos";
292*67e74705SXin Li else
293*67e74705SXin Li P += "macosx";
294*67e74705SXin Li P += ".a";
295*67e74705SXin Li
296*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(P));
297*67e74705SXin Li }
298*67e74705SXin Li
AddLinkRuntimeLib(const ArgList & Args,ArgStringList & CmdArgs,StringRef DarwinLibName,bool AlwaysLink,bool IsEmbedded,bool AddRPath) const299*67e74705SXin Li void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
300*67e74705SXin Li StringRef DarwinLibName, bool AlwaysLink,
301*67e74705SXin Li bool IsEmbedded, bool AddRPath) const {
302*67e74705SXin Li SmallString<128> Dir(getDriver().ResourceDir);
303*67e74705SXin Li llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
304*67e74705SXin Li
305*67e74705SXin Li SmallString<128> P(Dir);
306*67e74705SXin Li llvm::sys::path::append(P, DarwinLibName);
307*67e74705SXin Li
308*67e74705SXin Li // For now, allow missing resource libraries to support developers who may
309*67e74705SXin Li // not have compiler-rt checked out or integrated into their build (unless
310*67e74705SXin Li // we explicitly force linking with this library).
311*67e74705SXin Li if (AlwaysLink || getVFS().exists(P))
312*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(P));
313*67e74705SXin Li
314*67e74705SXin Li // Adding the rpaths might negatively interact when other rpaths are involved,
315*67e74705SXin Li // so we should make sure we add the rpaths last, after all user-specified
316*67e74705SXin Li // rpaths. This is currently true from this place, but we need to be
317*67e74705SXin Li // careful if this function is ever called before user's rpaths are emitted.
318*67e74705SXin Li if (AddRPath) {
319*67e74705SXin Li assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
320*67e74705SXin Li
321*67e74705SXin Li // Add @executable_path to rpath to support having the dylib copied with
322*67e74705SXin Li // the executable.
323*67e74705SXin Li CmdArgs.push_back("-rpath");
324*67e74705SXin Li CmdArgs.push_back("@executable_path");
325*67e74705SXin Li
326*67e74705SXin Li // Add the path to the resource dir to rpath to support using the dylib
327*67e74705SXin Li // from the default location without copying.
328*67e74705SXin Li CmdArgs.push_back("-rpath");
329*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(Dir));
330*67e74705SXin Li }
331*67e74705SXin Li }
332*67e74705SXin Li
getPlatformFamily() const333*67e74705SXin Li StringRef Darwin::getPlatformFamily() const {
334*67e74705SXin Li switch (TargetPlatform) {
335*67e74705SXin Li case DarwinPlatformKind::MacOS:
336*67e74705SXin Li return "MacOSX";
337*67e74705SXin Li case DarwinPlatformKind::IPhoneOS:
338*67e74705SXin Li case DarwinPlatformKind::IPhoneOSSimulator:
339*67e74705SXin Li return "iPhone";
340*67e74705SXin Li case DarwinPlatformKind::TvOS:
341*67e74705SXin Li case DarwinPlatformKind::TvOSSimulator:
342*67e74705SXin Li return "AppleTV";
343*67e74705SXin Li case DarwinPlatformKind::WatchOS:
344*67e74705SXin Li case DarwinPlatformKind::WatchOSSimulator:
345*67e74705SXin Li return "Watch";
346*67e74705SXin Li }
347*67e74705SXin Li llvm_unreachable("Unsupported platform");
348*67e74705SXin Li }
349*67e74705SXin Li
getSDKName(StringRef isysroot)350*67e74705SXin Li StringRef Darwin::getSDKName(StringRef isysroot) {
351*67e74705SXin Li // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
352*67e74705SXin Li llvm::sys::path::const_iterator SDKDir;
353*67e74705SXin Li auto BeginSDK = llvm::sys::path::begin(isysroot);
354*67e74705SXin Li auto EndSDK = llvm::sys::path::end(isysroot);
355*67e74705SXin Li for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
356*67e74705SXin Li StringRef SDK = *IT;
357*67e74705SXin Li if (SDK.endswith(".sdk"))
358*67e74705SXin Li return SDK.slice(0, SDK.size() - 4);
359*67e74705SXin Li }
360*67e74705SXin Li return "";
361*67e74705SXin Li }
362*67e74705SXin Li
getOSLibraryNameSuffix() const363*67e74705SXin Li StringRef Darwin::getOSLibraryNameSuffix() const {
364*67e74705SXin Li switch(TargetPlatform) {
365*67e74705SXin Li case DarwinPlatformKind::MacOS:
366*67e74705SXin Li return "osx";
367*67e74705SXin Li case DarwinPlatformKind::IPhoneOS:
368*67e74705SXin Li return "ios";
369*67e74705SXin Li case DarwinPlatformKind::IPhoneOSSimulator:
370*67e74705SXin Li return "iossim";
371*67e74705SXin Li case DarwinPlatformKind::TvOS:
372*67e74705SXin Li return "tvos";
373*67e74705SXin Li case DarwinPlatformKind::TvOSSimulator:
374*67e74705SXin Li return "tvossim";
375*67e74705SXin Li case DarwinPlatformKind::WatchOS:
376*67e74705SXin Li return "watchos";
377*67e74705SXin Li case DarwinPlatformKind::WatchOSSimulator:
378*67e74705SXin Li return "watchossim";
379*67e74705SXin Li }
380*67e74705SXin Li llvm_unreachable("Unsupported platform");
381*67e74705SXin Li }
382*67e74705SXin Li
addProfileRTLibs(const ArgList & Args,ArgStringList & CmdArgs) const383*67e74705SXin Li void Darwin::addProfileRTLibs(const ArgList &Args,
384*67e74705SXin Li ArgStringList &CmdArgs) const {
385*67e74705SXin Li if (!needsProfileRT(Args)) return;
386*67e74705SXin Li
387*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
388*67e74705SXin Li getOSLibraryNameSuffix() + ".a").str(),
389*67e74705SXin Li /*AlwaysLink*/ true);
390*67e74705SXin Li }
391*67e74705SXin Li
AddLinkSanitizerLibArgs(const ArgList & Args,ArgStringList & CmdArgs,StringRef Sanitizer) const392*67e74705SXin Li void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
393*67e74705SXin Li ArgStringList &CmdArgs,
394*67e74705SXin Li StringRef Sanitizer) const {
395*67e74705SXin Li AddLinkRuntimeLib(
396*67e74705SXin Li Args, CmdArgs,
397*67e74705SXin Li (Twine("libclang_rt.") + Sanitizer + "_" +
398*67e74705SXin Li getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
399*67e74705SXin Li /*AlwaysLink*/ true, /*IsEmbedded*/ false,
400*67e74705SXin Li /*AddRPath*/ true);
401*67e74705SXin Li }
402*67e74705SXin Li
AddLinkRuntimeLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const403*67e74705SXin Li void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
404*67e74705SXin Li ArgStringList &CmdArgs) const {
405*67e74705SXin Li // Darwin only supports the compiler-rt based runtime libraries.
406*67e74705SXin Li switch (GetRuntimeLibType(Args)) {
407*67e74705SXin Li case ToolChain::RLT_CompilerRT:
408*67e74705SXin Li break;
409*67e74705SXin Li default:
410*67e74705SXin Li getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
411*67e74705SXin Li << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
412*67e74705SXin Li return;
413*67e74705SXin Li }
414*67e74705SXin Li
415*67e74705SXin Li // Darwin doesn't support real static executables, don't link any runtime
416*67e74705SXin Li // libraries with -static.
417*67e74705SXin Li if (Args.hasArg(options::OPT_static) ||
418*67e74705SXin Li Args.hasArg(options::OPT_fapple_kext) ||
419*67e74705SXin Li Args.hasArg(options::OPT_mkernel))
420*67e74705SXin Li return;
421*67e74705SXin Li
422*67e74705SXin Li // Reject -static-libgcc for now, we can deal with this when and if someone
423*67e74705SXin Li // cares. This is useful in situations where someone wants to statically link
424*67e74705SXin Li // something like libstdc++, and needs its runtime support routines.
425*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
426*67e74705SXin Li getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
427*67e74705SXin Li return;
428*67e74705SXin Li }
429*67e74705SXin Li
430*67e74705SXin Li const SanitizerArgs &Sanitize = getSanitizerArgs();
431*67e74705SXin Li if (Sanitize.needsAsanRt())
432*67e74705SXin Li AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
433*67e74705SXin Li if (Sanitize.needsUbsanRt())
434*67e74705SXin Li AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
435*67e74705SXin Li if (Sanitize.needsTsanRt())
436*67e74705SXin Li AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
437*67e74705SXin Li if (Sanitize.needsStatsRt()) {
438*67e74705SXin Li StringRef OS = isTargetMacOS() ? "osx" : "iossim";
439*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs,
440*67e74705SXin Li (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
441*67e74705SXin Li /*AlwaysLink=*/true);
442*67e74705SXin Li AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
443*67e74705SXin Li }
444*67e74705SXin Li if (Sanitize.needsEsanRt())
445*67e74705SXin Li AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
446*67e74705SXin Li
447*67e74705SXin Li // Otherwise link libSystem, then the dynamic runtime library, and finally any
448*67e74705SXin Li // target specific static runtime library.
449*67e74705SXin Li CmdArgs.push_back("-lSystem");
450*67e74705SXin Li
451*67e74705SXin Li // Select the dynamic runtime library and the target specific static library.
452*67e74705SXin Li if (isTargetWatchOSBased()) {
453*67e74705SXin Li // We currently always need a static runtime library for watchOS.
454*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
455*67e74705SXin Li } else if (isTargetTvOSBased()) {
456*67e74705SXin Li // We currently always need a static runtime library for tvOS.
457*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
458*67e74705SXin Li } else if (isTargetIOSBased()) {
459*67e74705SXin Li // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
460*67e74705SXin Li // it never went into the SDK.
461*67e74705SXin Li // Linking against libgcc_s.1 isn't needed for iOS 5.0+
462*67e74705SXin Li if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
463*67e74705SXin Li getTriple().getArch() != llvm::Triple::aarch64)
464*67e74705SXin Li CmdArgs.push_back("-lgcc_s.1");
465*67e74705SXin Li
466*67e74705SXin Li // We currently always need a static runtime library for iOS.
467*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
468*67e74705SXin Li } else {
469*67e74705SXin Li assert(isTargetMacOS() && "unexpected non MacOS platform");
470*67e74705SXin Li // The dynamic runtime library was merged with libSystem for 10.6 and
471*67e74705SXin Li // beyond; only 10.4 and 10.5 need an additional runtime library.
472*67e74705SXin Li if (isMacosxVersionLT(10, 5))
473*67e74705SXin Li CmdArgs.push_back("-lgcc_s.10.4");
474*67e74705SXin Li else if (isMacosxVersionLT(10, 6))
475*67e74705SXin Li CmdArgs.push_back("-lgcc_s.10.5");
476*67e74705SXin Li
477*67e74705SXin Li // For OS X, we thought we would only need a static runtime library when
478*67e74705SXin Li // targeting 10.4, to provide versions of the static functions which were
479*67e74705SXin Li // omitted from 10.4.dylib.
480*67e74705SXin Li //
481*67e74705SXin Li // Unfortunately, that turned out to not be true, because Darwin system
482*67e74705SXin Li // headers can still use eprintf on i386, and it is not exported from
483*67e74705SXin Li // libSystem. Therefore, we still must provide a runtime library just for
484*67e74705SXin Li // the tiny tiny handful of projects that *might* use that symbol.
485*67e74705SXin Li if (isMacosxVersionLT(10, 5)) {
486*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
487*67e74705SXin Li } else {
488*67e74705SXin Li if (getTriple().getArch() == llvm::Triple::x86)
489*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
490*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
491*67e74705SXin Li }
492*67e74705SXin Li }
493*67e74705SXin Li }
494*67e74705SXin Li
AddDeploymentTarget(DerivedArgList & Args) const495*67e74705SXin Li void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
496*67e74705SXin Li const OptTable &Opts = getDriver().getOpts();
497*67e74705SXin Li
498*67e74705SXin Li // Support allowing the SDKROOT environment variable used by xcrun and other
499*67e74705SXin Li // Xcode tools to define the default sysroot, by making it the default for
500*67e74705SXin Li // isysroot.
501*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
502*67e74705SXin Li // Warn if the path does not exist.
503*67e74705SXin Li if (!getVFS().exists(A->getValue()))
504*67e74705SXin Li getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
505*67e74705SXin Li } else {
506*67e74705SXin Li if (char *env = ::getenv("SDKROOT")) {
507*67e74705SXin Li // We only use this value as the default if it is an absolute path,
508*67e74705SXin Li // exists, and it is not the root path.
509*67e74705SXin Li if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
510*67e74705SXin Li StringRef(env) != "/") {
511*67e74705SXin Li Args.append(Args.MakeSeparateArg(
512*67e74705SXin Li nullptr, Opts.getOption(options::OPT_isysroot), env));
513*67e74705SXin Li }
514*67e74705SXin Li }
515*67e74705SXin Li }
516*67e74705SXin Li
517*67e74705SXin Li Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
518*67e74705SXin Li Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
519*67e74705SXin Li Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
520*67e74705SXin Li Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
521*67e74705SXin Li
522*67e74705SXin Li if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
523*67e74705SXin Li getDriver().Diag(diag::err_drv_argument_not_allowed_with)
524*67e74705SXin Li << OSXVersion->getAsString(Args)
525*67e74705SXin Li << (iOSVersion ? iOSVersion :
526*67e74705SXin Li TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
527*67e74705SXin Li iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
528*67e74705SXin Li } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
529*67e74705SXin Li getDriver().Diag(diag::err_drv_argument_not_allowed_with)
530*67e74705SXin Li << iOSVersion->getAsString(Args)
531*67e74705SXin Li << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
532*67e74705SXin Li TvOSVersion = WatchOSVersion = nullptr;
533*67e74705SXin Li } else if (TvOSVersion && WatchOSVersion) {
534*67e74705SXin Li getDriver().Diag(diag::err_drv_argument_not_allowed_with)
535*67e74705SXin Li << TvOSVersion->getAsString(Args)
536*67e74705SXin Li << WatchOSVersion->getAsString(Args);
537*67e74705SXin Li WatchOSVersion = nullptr;
538*67e74705SXin Li } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
539*67e74705SXin Li // If no deployment target was specified on the command line, check for
540*67e74705SXin Li // environment defines.
541*67e74705SXin Li std::string OSXTarget;
542*67e74705SXin Li std::string iOSTarget;
543*67e74705SXin Li std::string TvOSTarget;
544*67e74705SXin Li std::string WatchOSTarget;
545*67e74705SXin Li
546*67e74705SXin Li if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
547*67e74705SXin Li OSXTarget = env;
548*67e74705SXin Li if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
549*67e74705SXin Li iOSTarget = env;
550*67e74705SXin Li if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
551*67e74705SXin Li TvOSTarget = env;
552*67e74705SXin Li if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
553*67e74705SXin Li WatchOSTarget = env;
554*67e74705SXin Li
555*67e74705SXin Li // If there is no command-line argument to specify the Target version and
556*67e74705SXin Li // no environment variable defined, see if we can set the default based
557*67e74705SXin Li // on -isysroot.
558*67e74705SXin Li if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
559*67e74705SXin Li TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
560*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
561*67e74705SXin Li StringRef isysroot = A->getValue();
562*67e74705SXin Li StringRef SDK = getSDKName(isysroot);
563*67e74705SXin Li if (SDK.size() > 0) {
564*67e74705SXin Li // Slice the version number out.
565*67e74705SXin Li // Version number is between the first and the last number.
566*67e74705SXin Li size_t StartVer = SDK.find_first_of("0123456789");
567*67e74705SXin Li size_t EndVer = SDK.find_last_of("0123456789");
568*67e74705SXin Li if (StartVer != StringRef::npos && EndVer > StartVer) {
569*67e74705SXin Li StringRef Version = SDK.slice(StartVer, EndVer + 1);
570*67e74705SXin Li if (SDK.startswith("iPhoneOS") ||
571*67e74705SXin Li SDK.startswith("iPhoneSimulator"))
572*67e74705SXin Li iOSTarget = Version;
573*67e74705SXin Li else if (SDK.startswith("MacOSX"))
574*67e74705SXin Li OSXTarget = Version;
575*67e74705SXin Li else if (SDK.startswith("WatchOS") ||
576*67e74705SXin Li SDK.startswith("WatchSimulator"))
577*67e74705SXin Li WatchOSTarget = Version;
578*67e74705SXin Li else if (SDK.startswith("AppleTVOS") ||
579*67e74705SXin Li SDK.startswith("AppleTVSimulator"))
580*67e74705SXin Li TvOSTarget = Version;
581*67e74705SXin Li }
582*67e74705SXin Li }
583*67e74705SXin Li }
584*67e74705SXin Li }
585*67e74705SXin Li
586*67e74705SXin Li // If no OSX or iOS target has been specified, try to guess platform
587*67e74705SXin Li // from arch name and compute the version from the triple.
588*67e74705SXin Li if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
589*67e74705SXin Li WatchOSTarget.empty()) {
590*67e74705SXin Li StringRef MachOArchName = getMachOArchName(Args);
591*67e74705SXin Li unsigned Major, Minor, Micro;
592*67e74705SXin Li if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
593*67e74705SXin Li MachOArchName == "arm64") {
594*67e74705SXin Li getTriple().getiOSVersion(Major, Minor, Micro);
595*67e74705SXin Li llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
596*67e74705SXin Li << Micro;
597*67e74705SXin Li } else if (MachOArchName == "armv7k") {
598*67e74705SXin Li getTriple().getWatchOSVersion(Major, Minor, Micro);
599*67e74705SXin Li llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
600*67e74705SXin Li << Micro;
601*67e74705SXin Li } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
602*67e74705SXin Li MachOArchName != "armv7em") {
603*67e74705SXin Li if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
604*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_darwin_version)
605*67e74705SXin Li << getTriple().getOSName();
606*67e74705SXin Li }
607*67e74705SXin Li llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
608*67e74705SXin Li << Micro;
609*67e74705SXin Li }
610*67e74705SXin Li }
611*67e74705SXin Li
612*67e74705SXin Li // Do not allow conflicts with the watchOS target.
613*67e74705SXin Li if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
614*67e74705SXin Li getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
615*67e74705SXin Li << "WATCHOS_DEPLOYMENT_TARGET"
616*67e74705SXin Li << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
617*67e74705SXin Li "TVOS_DEPLOYMENT_TARGET");
618*67e74705SXin Li }
619*67e74705SXin Li
620*67e74705SXin Li // Do not allow conflicts with the tvOS target.
621*67e74705SXin Li if (!TvOSTarget.empty() && !iOSTarget.empty()) {
622*67e74705SXin Li getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
623*67e74705SXin Li << "TVOS_DEPLOYMENT_TARGET"
624*67e74705SXin Li << "IPHONEOS_DEPLOYMENT_TARGET";
625*67e74705SXin Li }
626*67e74705SXin Li
627*67e74705SXin Li // Allow conflicts among OSX and iOS for historical reasons, but choose the
628*67e74705SXin Li // default platform.
629*67e74705SXin Li if (!OSXTarget.empty() && (!iOSTarget.empty() ||
630*67e74705SXin Li !WatchOSTarget.empty() ||
631*67e74705SXin Li !TvOSTarget.empty())) {
632*67e74705SXin Li if (getTriple().getArch() == llvm::Triple::arm ||
633*67e74705SXin Li getTriple().getArch() == llvm::Triple::aarch64 ||
634*67e74705SXin Li getTriple().getArch() == llvm::Triple::thumb)
635*67e74705SXin Li OSXTarget = "";
636*67e74705SXin Li else
637*67e74705SXin Li iOSTarget = WatchOSTarget = TvOSTarget = "";
638*67e74705SXin Li }
639*67e74705SXin Li
640*67e74705SXin Li if (!OSXTarget.empty()) {
641*67e74705SXin Li const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
642*67e74705SXin Li OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
643*67e74705SXin Li Args.append(OSXVersion);
644*67e74705SXin Li } else if (!iOSTarget.empty()) {
645*67e74705SXin Li const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
646*67e74705SXin Li iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
647*67e74705SXin Li Args.append(iOSVersion);
648*67e74705SXin Li } else if (!TvOSTarget.empty()) {
649*67e74705SXin Li const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
650*67e74705SXin Li TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
651*67e74705SXin Li Args.append(TvOSVersion);
652*67e74705SXin Li } else if (!WatchOSTarget.empty()) {
653*67e74705SXin Li const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
654*67e74705SXin Li WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
655*67e74705SXin Li Args.append(WatchOSVersion);
656*67e74705SXin Li }
657*67e74705SXin Li }
658*67e74705SXin Li
659*67e74705SXin Li DarwinPlatformKind Platform;
660*67e74705SXin Li if (OSXVersion)
661*67e74705SXin Li Platform = MacOS;
662*67e74705SXin Li else if (iOSVersion)
663*67e74705SXin Li Platform = IPhoneOS;
664*67e74705SXin Li else if (TvOSVersion)
665*67e74705SXin Li Platform = TvOS;
666*67e74705SXin Li else if (WatchOSVersion)
667*67e74705SXin Li Platform = WatchOS;
668*67e74705SXin Li else
669*67e74705SXin Li llvm_unreachable("Unable to infer Darwin variant");
670*67e74705SXin Li
671*67e74705SXin Li // Set the tool chain target information.
672*67e74705SXin Li unsigned Major, Minor, Micro;
673*67e74705SXin Li bool HadExtra;
674*67e74705SXin Li if (Platform == MacOS) {
675*67e74705SXin Li assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
676*67e74705SXin Li "Unknown target platform!");
677*67e74705SXin Li if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
678*67e74705SXin Li HadExtra) ||
679*67e74705SXin Li HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
680*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_version_number)
681*67e74705SXin Li << OSXVersion->getAsString(Args);
682*67e74705SXin Li } else if (Platform == IPhoneOS) {
683*67e74705SXin Li assert(iOSVersion && "Unknown target platform!");
684*67e74705SXin Li if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
685*67e74705SXin Li HadExtra) ||
686*67e74705SXin Li HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100)
687*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_version_number)
688*67e74705SXin Li << iOSVersion->getAsString(Args);
689*67e74705SXin Li } else if (Platform == TvOS) {
690*67e74705SXin Li if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
691*67e74705SXin Li Micro, HadExtra) || HadExtra ||
692*67e74705SXin Li Major >= 10 || Minor >= 100 || Micro >= 100)
693*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_version_number)
694*67e74705SXin Li << TvOSVersion->getAsString(Args);
695*67e74705SXin Li } else if (Platform == WatchOS) {
696*67e74705SXin Li if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
697*67e74705SXin Li Micro, HadExtra) || HadExtra ||
698*67e74705SXin Li Major >= 10 || Minor >= 100 || Micro >= 100)
699*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_version_number)
700*67e74705SXin Li << WatchOSVersion->getAsString(Args);
701*67e74705SXin Li } else
702*67e74705SXin Li llvm_unreachable("unknown kind of Darwin platform");
703*67e74705SXin Li
704*67e74705SXin Li // Recognize iOS targets with an x86 architecture as the iOS simulator.
705*67e74705SXin Li if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
706*67e74705SXin Li getTriple().getArch() == llvm::Triple::x86_64))
707*67e74705SXin Li Platform = IPhoneOSSimulator;
708*67e74705SXin Li if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
709*67e74705SXin Li getTriple().getArch() == llvm::Triple::x86_64))
710*67e74705SXin Li Platform = TvOSSimulator;
711*67e74705SXin Li if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
712*67e74705SXin Li getTriple().getArch() == llvm::Triple::x86_64))
713*67e74705SXin Li Platform = WatchOSSimulator;
714*67e74705SXin Li
715*67e74705SXin Li setTarget(Platform, Major, Minor, Micro);
716*67e74705SXin Li
717*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
718*67e74705SXin Li StringRef SDK = getSDKName(A->getValue());
719*67e74705SXin Li if (SDK.size() > 0) {
720*67e74705SXin Li size_t StartVer = SDK.find_first_of("0123456789");
721*67e74705SXin Li StringRef SDKName = SDK.slice(0, StartVer);
722*67e74705SXin Li if (!SDKName.startswith(getPlatformFamily()))
723*67e74705SXin Li getDriver().Diag(diag::warn_incompatible_sysroot)
724*67e74705SXin Li << SDKName << getPlatformFamily();
725*67e74705SXin Li }
726*67e74705SXin Li }
727*67e74705SXin Li }
728*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const729*67e74705SXin Li void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
730*67e74705SXin Li ArgStringList &CmdArgs) const {
731*67e74705SXin Li CXXStdlibType Type = GetCXXStdlibType(Args);
732*67e74705SXin Li
733*67e74705SXin Li switch (Type) {
734*67e74705SXin Li case ToolChain::CST_Libcxx:
735*67e74705SXin Li CmdArgs.push_back("-lc++");
736*67e74705SXin Li break;
737*67e74705SXin Li
738*67e74705SXin Li case ToolChain::CST_Libstdcxx:
739*67e74705SXin Li // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
740*67e74705SXin Li // it was previously found in the gcc lib dir. However, for all the Darwin
741*67e74705SXin Li // platforms we care about it was -lstdc++.6, so we search for that
742*67e74705SXin Li // explicitly if we can't see an obvious -lstdc++ candidate.
743*67e74705SXin Li
744*67e74705SXin Li // Check in the sysroot first.
745*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
746*67e74705SXin Li SmallString<128> P(A->getValue());
747*67e74705SXin Li llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
748*67e74705SXin Li
749*67e74705SXin Li if (!getVFS().exists(P)) {
750*67e74705SXin Li llvm::sys::path::remove_filename(P);
751*67e74705SXin Li llvm::sys::path::append(P, "libstdc++.6.dylib");
752*67e74705SXin Li if (getVFS().exists(P)) {
753*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(P));
754*67e74705SXin Li return;
755*67e74705SXin Li }
756*67e74705SXin Li }
757*67e74705SXin Li }
758*67e74705SXin Li
759*67e74705SXin Li // Otherwise, look in the root.
760*67e74705SXin Li // FIXME: This should be removed someday when we don't have to care about
761*67e74705SXin Li // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
762*67e74705SXin Li if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
763*67e74705SXin Li getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
764*67e74705SXin Li CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
765*67e74705SXin Li return;
766*67e74705SXin Li }
767*67e74705SXin Li
768*67e74705SXin Li // Otherwise, let the linker search.
769*67e74705SXin Li CmdArgs.push_back("-lstdc++");
770*67e74705SXin Li break;
771*67e74705SXin Li }
772*67e74705SXin Li }
773*67e74705SXin Li
AddCCKextLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const774*67e74705SXin Li void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
775*67e74705SXin Li ArgStringList &CmdArgs) const {
776*67e74705SXin Li // For Darwin platforms, use the compiler-rt-based support library
777*67e74705SXin Li // instead of the gcc-provided one (which is also incidentally
778*67e74705SXin Li // only present in the gcc lib dir, which makes it hard to find).
779*67e74705SXin Li
780*67e74705SXin Li SmallString<128> P(getDriver().ResourceDir);
781*67e74705SXin Li llvm::sys::path::append(P, "lib", "darwin");
782*67e74705SXin Li
783*67e74705SXin Li // Use the newer cc_kext for iOS ARM after 6.0.
784*67e74705SXin Li if (isTargetWatchOS()) {
785*67e74705SXin Li llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
786*67e74705SXin Li } else if (isTargetTvOS()) {
787*67e74705SXin Li llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
788*67e74705SXin Li } else if (isTargetIPhoneOS()) {
789*67e74705SXin Li llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
790*67e74705SXin Li } else {
791*67e74705SXin Li llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
792*67e74705SXin Li }
793*67e74705SXin Li
794*67e74705SXin Li // For now, allow missing resource libraries to support developers who may
795*67e74705SXin Li // not have compiler-rt checked out or integrated into their build.
796*67e74705SXin Li if (getVFS().exists(P))
797*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(P));
798*67e74705SXin Li }
799*67e74705SXin Li
TranslateArgs(const DerivedArgList & Args,const char * BoundArch) const800*67e74705SXin Li DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
801*67e74705SXin Li const char *BoundArch) const {
802*67e74705SXin Li DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
803*67e74705SXin Li const OptTable &Opts = getDriver().getOpts();
804*67e74705SXin Li
805*67e74705SXin Li // FIXME: We really want to get out of the tool chain level argument
806*67e74705SXin Li // translation business, as it makes the driver functionality much
807*67e74705SXin Li // more opaque. For now, we follow gcc closely solely for the
808*67e74705SXin Li // purpose of easily achieving feature parity & testability. Once we
809*67e74705SXin Li // have something that works, we should reevaluate each translation
810*67e74705SXin Li // and try to push it down into tool specific logic.
811*67e74705SXin Li
812*67e74705SXin Li for (Arg *A : Args) {
813*67e74705SXin Li if (A->getOption().matches(options::OPT_Xarch__)) {
814*67e74705SXin Li // Skip this argument unless the architecture matches either the toolchain
815*67e74705SXin Li // triple arch, or the arch being bound.
816*67e74705SXin Li llvm::Triple::ArchType XarchArch =
817*67e74705SXin Li tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
818*67e74705SXin Li if (!(XarchArch == getArch() ||
819*67e74705SXin Li (BoundArch &&
820*67e74705SXin Li XarchArch ==
821*67e74705SXin Li tools::darwin::getArchTypeForMachOArchName(BoundArch))))
822*67e74705SXin Li continue;
823*67e74705SXin Li
824*67e74705SXin Li Arg *OriginalArg = A;
825*67e74705SXin Li unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
826*67e74705SXin Li unsigned Prev = Index;
827*67e74705SXin Li std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
828*67e74705SXin Li
829*67e74705SXin Li // If the argument parsing failed or more than one argument was
830*67e74705SXin Li // consumed, the -Xarch_ argument's parameter tried to consume
831*67e74705SXin Li // extra arguments. Emit an error and ignore.
832*67e74705SXin Li //
833*67e74705SXin Li // We also want to disallow any options which would alter the
834*67e74705SXin Li // driver behavior; that isn't going to work in our model. We
835*67e74705SXin Li // use isDriverOption() as an approximation, although things
836*67e74705SXin Li // like -O4 are going to slip through.
837*67e74705SXin Li if (!XarchArg || Index > Prev + 1) {
838*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
839*67e74705SXin Li << A->getAsString(Args);
840*67e74705SXin Li continue;
841*67e74705SXin Li } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
842*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
843*67e74705SXin Li << A->getAsString(Args);
844*67e74705SXin Li continue;
845*67e74705SXin Li }
846*67e74705SXin Li
847*67e74705SXin Li XarchArg->setBaseArg(A);
848*67e74705SXin Li
849*67e74705SXin Li A = XarchArg.release();
850*67e74705SXin Li DAL->AddSynthesizedArg(A);
851*67e74705SXin Li
852*67e74705SXin Li // Linker input arguments require custom handling. The problem is that we
853*67e74705SXin Li // have already constructed the phase actions, so we can not treat them as
854*67e74705SXin Li // "input arguments".
855*67e74705SXin Li if (A->getOption().hasFlag(options::LinkerInput)) {
856*67e74705SXin Li // Convert the argument into individual Zlinker_input_args.
857*67e74705SXin Li for (const char *Value : A->getValues()) {
858*67e74705SXin Li DAL->AddSeparateArg(
859*67e74705SXin Li OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
860*67e74705SXin Li }
861*67e74705SXin Li continue;
862*67e74705SXin Li }
863*67e74705SXin Li }
864*67e74705SXin Li
865*67e74705SXin Li // Sob. These is strictly gcc compatible for the time being. Apple
866*67e74705SXin Li // gcc translates options twice, which means that self-expanding
867*67e74705SXin Li // options add duplicates.
868*67e74705SXin Li switch ((options::ID)A->getOption().getID()) {
869*67e74705SXin Li default:
870*67e74705SXin Li DAL->append(A);
871*67e74705SXin Li break;
872*67e74705SXin Li
873*67e74705SXin Li case options::OPT_mkernel:
874*67e74705SXin Li case options::OPT_fapple_kext:
875*67e74705SXin Li DAL->append(A);
876*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
877*67e74705SXin Li break;
878*67e74705SXin Li
879*67e74705SXin Li case options::OPT_dependency_file:
880*67e74705SXin Li DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
881*67e74705SXin Li break;
882*67e74705SXin Li
883*67e74705SXin Li case options::OPT_gfull:
884*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
885*67e74705SXin Li DAL->AddFlagArg(
886*67e74705SXin Li A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
887*67e74705SXin Li break;
888*67e74705SXin Li
889*67e74705SXin Li case options::OPT_gused:
890*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
891*67e74705SXin Li DAL->AddFlagArg(
892*67e74705SXin Li A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
893*67e74705SXin Li break;
894*67e74705SXin Li
895*67e74705SXin Li case options::OPT_shared:
896*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
897*67e74705SXin Li break;
898*67e74705SXin Li
899*67e74705SXin Li case options::OPT_fconstant_cfstrings:
900*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
901*67e74705SXin Li break;
902*67e74705SXin Li
903*67e74705SXin Li case options::OPT_fno_constant_cfstrings:
904*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
905*67e74705SXin Li break;
906*67e74705SXin Li
907*67e74705SXin Li case options::OPT_Wnonportable_cfstrings:
908*67e74705SXin Li DAL->AddFlagArg(A,
909*67e74705SXin Li Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
910*67e74705SXin Li break;
911*67e74705SXin Li
912*67e74705SXin Li case options::OPT_Wno_nonportable_cfstrings:
913*67e74705SXin Li DAL->AddFlagArg(
914*67e74705SXin Li A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
915*67e74705SXin Li break;
916*67e74705SXin Li
917*67e74705SXin Li case options::OPT_fpascal_strings:
918*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
919*67e74705SXin Li break;
920*67e74705SXin Li
921*67e74705SXin Li case options::OPT_fno_pascal_strings:
922*67e74705SXin Li DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
923*67e74705SXin Li break;
924*67e74705SXin Li }
925*67e74705SXin Li }
926*67e74705SXin Li
927*67e74705SXin Li if (getTriple().getArch() == llvm::Triple::x86 ||
928*67e74705SXin Li getTriple().getArch() == llvm::Triple::x86_64)
929*67e74705SXin Li if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
930*67e74705SXin Li DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
931*67e74705SXin Li "core2");
932*67e74705SXin Li
933*67e74705SXin Li // Add the arch options based on the particular spelling of -arch, to match
934*67e74705SXin Li // how the driver driver works.
935*67e74705SXin Li if (BoundArch) {
936*67e74705SXin Li StringRef Name = BoundArch;
937*67e74705SXin Li const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
938*67e74705SXin Li const Option MArch = Opts.getOption(options::OPT_march_EQ);
939*67e74705SXin Li
940*67e74705SXin Li // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
941*67e74705SXin Li // which defines the list of which architectures we accept.
942*67e74705SXin Li if (Name == "ppc")
943*67e74705SXin Li ;
944*67e74705SXin Li else if (Name == "ppc601")
945*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "601");
946*67e74705SXin Li else if (Name == "ppc603")
947*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "603");
948*67e74705SXin Li else if (Name == "ppc604")
949*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "604");
950*67e74705SXin Li else if (Name == "ppc604e")
951*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "604e");
952*67e74705SXin Li else if (Name == "ppc750")
953*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "750");
954*67e74705SXin Li else if (Name == "ppc7400")
955*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "7400");
956*67e74705SXin Li else if (Name == "ppc7450")
957*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "7450");
958*67e74705SXin Li else if (Name == "ppc970")
959*67e74705SXin Li DAL->AddJoinedArg(nullptr, MCpu, "970");
960*67e74705SXin Li
961*67e74705SXin Li else if (Name == "ppc64" || Name == "ppc64le")
962*67e74705SXin Li DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
963*67e74705SXin Li
964*67e74705SXin Li else if (Name == "i386")
965*67e74705SXin Li ;
966*67e74705SXin Li else if (Name == "i486")
967*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "i486");
968*67e74705SXin Li else if (Name == "i586")
969*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "i586");
970*67e74705SXin Li else if (Name == "i686")
971*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "i686");
972*67e74705SXin Li else if (Name == "pentium")
973*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "pentium");
974*67e74705SXin Li else if (Name == "pentium2")
975*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "pentium2");
976*67e74705SXin Li else if (Name == "pentpro")
977*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
978*67e74705SXin Li else if (Name == "pentIIm3")
979*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "pentium2");
980*67e74705SXin Li
981*67e74705SXin Li else if (Name == "x86_64")
982*67e74705SXin Li DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
983*67e74705SXin Li else if (Name == "x86_64h") {
984*67e74705SXin Li DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
985*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
986*67e74705SXin Li }
987*67e74705SXin Li
988*67e74705SXin Li else if (Name == "arm")
989*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv4t");
990*67e74705SXin Li else if (Name == "armv4t")
991*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv4t");
992*67e74705SXin Li else if (Name == "armv5")
993*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
994*67e74705SXin Li else if (Name == "xscale")
995*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "xscale");
996*67e74705SXin Li else if (Name == "armv6")
997*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv6k");
998*67e74705SXin Li else if (Name == "armv6m")
999*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv6m");
1000*67e74705SXin Li else if (Name == "armv7")
1001*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv7a");
1002*67e74705SXin Li else if (Name == "armv7em")
1003*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv7em");
1004*67e74705SXin Li else if (Name == "armv7k")
1005*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv7k");
1006*67e74705SXin Li else if (Name == "armv7m")
1007*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv7m");
1008*67e74705SXin Li else if (Name == "armv7s")
1009*67e74705SXin Li DAL->AddJoinedArg(nullptr, MArch, "armv7s");
1010*67e74705SXin Li }
1011*67e74705SXin Li
1012*67e74705SXin Li return DAL;
1013*67e74705SXin Li }
1014*67e74705SXin Li
AddLinkRuntimeLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const1015*67e74705SXin Li void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
1016*67e74705SXin Li ArgStringList &CmdArgs) const {
1017*67e74705SXin Li // Embedded targets are simple at the moment, not supporting sanitizers and
1018*67e74705SXin Li // with different libraries for each member of the product { static, PIC } x
1019*67e74705SXin Li // { hard-float, soft-float }
1020*67e74705SXin Li llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
1021*67e74705SXin Li CompilerRT +=
1022*67e74705SXin Li (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)
1023*67e74705SXin Li ? "hard"
1024*67e74705SXin Li : "soft";
1025*67e74705SXin Li CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
1026*67e74705SXin Li
1027*67e74705SXin Li AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
1028*67e74705SXin Li }
1029*67e74705SXin Li
TranslateArgs(const DerivedArgList & Args,const char * BoundArch) const1030*67e74705SXin Li DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
1031*67e74705SXin Li const char *BoundArch) const {
1032*67e74705SXin Li // First get the generic Apple args, before moving onto Darwin-specific ones.
1033*67e74705SXin Li DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch);
1034*67e74705SXin Li const OptTable &Opts = getDriver().getOpts();
1035*67e74705SXin Li
1036*67e74705SXin Li // If no architecture is bound, none of the translations here are relevant.
1037*67e74705SXin Li if (!BoundArch)
1038*67e74705SXin Li return DAL;
1039*67e74705SXin Li
1040*67e74705SXin Li // Add an explicit version min argument for the deployment target. We do this
1041*67e74705SXin Li // after argument translation because -Xarch_ arguments may add a version min
1042*67e74705SXin Li // argument.
1043*67e74705SXin Li AddDeploymentTarget(*DAL);
1044*67e74705SXin Li
1045*67e74705SXin Li // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
1046*67e74705SXin Li // FIXME: It would be far better to avoid inserting those -static arguments,
1047*67e74705SXin Li // but we can't check the deployment target in the translation code until
1048*67e74705SXin Li // it is set here.
1049*67e74705SXin Li if (isTargetWatchOSBased() ||
1050*67e74705SXin Li (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
1051*67e74705SXin Li for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
1052*67e74705SXin Li Arg *A = *it;
1053*67e74705SXin Li ++it;
1054*67e74705SXin Li if (A->getOption().getID() != options::OPT_mkernel &&
1055*67e74705SXin Li A->getOption().getID() != options::OPT_fapple_kext)
1056*67e74705SXin Li continue;
1057*67e74705SXin Li assert(it != ie && "unexpected argument translation");
1058*67e74705SXin Li A = *it;
1059*67e74705SXin Li assert(A->getOption().getID() == options::OPT_static &&
1060*67e74705SXin Li "missing expected -static argument");
1061*67e74705SXin Li it = DAL->getArgs().erase(it);
1062*67e74705SXin Li }
1063*67e74705SXin Li }
1064*67e74705SXin Li
1065*67e74705SXin Li if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
1066*67e74705SXin Li GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
1067*67e74705SXin Li DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
1068*67e74705SXin Li "libc++");
1069*67e74705SXin Li
1070*67e74705SXin Li // Validate the C++ standard library choice.
1071*67e74705SXin Li CXXStdlibType Type = GetCXXStdlibType(*DAL);
1072*67e74705SXin Li if (Type == ToolChain::CST_Libcxx) {
1073*67e74705SXin Li // Check whether the target provides libc++.
1074*67e74705SXin Li StringRef where;
1075*67e74705SXin Li
1076*67e74705SXin Li // Complain about targeting iOS < 5.0 in any way.
1077*67e74705SXin Li if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
1078*67e74705SXin Li where = "iOS 5.0";
1079*67e74705SXin Li
1080*67e74705SXin Li if (where != StringRef()) {
1081*67e74705SXin Li getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
1082*67e74705SXin Li }
1083*67e74705SXin Li }
1084*67e74705SXin Li
1085*67e74705SXin Li return DAL;
1086*67e74705SXin Li }
1087*67e74705SXin Li
IsUnwindTablesDefault() const1088*67e74705SXin Li bool MachO::IsUnwindTablesDefault() const {
1089*67e74705SXin Li return getArch() == llvm::Triple::x86_64;
1090*67e74705SXin Li }
1091*67e74705SXin Li
UseDwarfDebugFlags() const1092*67e74705SXin Li bool MachO::UseDwarfDebugFlags() const {
1093*67e74705SXin Li if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
1094*67e74705SXin Li return S[0] != '\0';
1095*67e74705SXin Li return false;
1096*67e74705SXin Li }
1097*67e74705SXin Li
UseSjLjExceptions(const ArgList & Args) const1098*67e74705SXin Li bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
1099*67e74705SXin Li // Darwin uses SjLj exceptions on ARM.
1100*67e74705SXin Li if (getTriple().getArch() != llvm::Triple::arm &&
1101*67e74705SXin Li getTriple().getArch() != llvm::Triple::thumb)
1102*67e74705SXin Li return false;
1103*67e74705SXin Li
1104*67e74705SXin Li // Only watchOS uses the new DWARF/Compact unwinding method.
1105*67e74705SXin Li llvm::Triple Triple(ComputeLLVMTriple(Args));
1106*67e74705SXin Li return !Triple.isWatchABI();
1107*67e74705SXin Li }
1108*67e74705SXin Li
SupportsEmbeddedBitcode() const1109*67e74705SXin Li bool Darwin::SupportsEmbeddedBitcode() const {
1110*67e74705SXin Li assert(TargetInitialized && "Target not initialized!");
1111*67e74705SXin Li if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
1112*67e74705SXin Li return false;
1113*67e74705SXin Li return true;
1114*67e74705SXin Li }
1115*67e74705SXin Li
isPICDefault() const1116*67e74705SXin Li bool MachO::isPICDefault() const { return true; }
1117*67e74705SXin Li
isPIEDefault() const1118*67e74705SXin Li bool MachO::isPIEDefault() const { return false; }
1119*67e74705SXin Li
isPICDefaultForced() const1120*67e74705SXin Li bool MachO::isPICDefaultForced() const {
1121*67e74705SXin Li return (getArch() == llvm::Triple::x86_64 ||
1122*67e74705SXin Li getArch() == llvm::Triple::aarch64);
1123*67e74705SXin Li }
1124*67e74705SXin Li
SupportsProfiling() const1125*67e74705SXin Li bool MachO::SupportsProfiling() const {
1126*67e74705SXin Li // Profiling instrumentation is only supported on x86.
1127*67e74705SXin Li return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
1128*67e74705SXin Li }
1129*67e74705SXin Li
addMinVersionArgs(const ArgList & Args,ArgStringList & CmdArgs) const1130*67e74705SXin Li void Darwin::addMinVersionArgs(const ArgList &Args,
1131*67e74705SXin Li ArgStringList &CmdArgs) const {
1132*67e74705SXin Li VersionTuple TargetVersion = getTargetVersion();
1133*67e74705SXin Li
1134*67e74705SXin Li if (isTargetWatchOS())
1135*67e74705SXin Li CmdArgs.push_back("-watchos_version_min");
1136*67e74705SXin Li else if (isTargetWatchOSSimulator())
1137*67e74705SXin Li CmdArgs.push_back("-watchos_simulator_version_min");
1138*67e74705SXin Li else if (isTargetTvOS())
1139*67e74705SXin Li CmdArgs.push_back("-tvos_version_min");
1140*67e74705SXin Li else if (isTargetTvOSSimulator())
1141*67e74705SXin Li CmdArgs.push_back("-tvos_simulator_version_min");
1142*67e74705SXin Li else if (isTargetIOSSimulator())
1143*67e74705SXin Li CmdArgs.push_back("-ios_simulator_version_min");
1144*67e74705SXin Li else if (isTargetIOSBased())
1145*67e74705SXin Li CmdArgs.push_back("-iphoneos_version_min");
1146*67e74705SXin Li else {
1147*67e74705SXin Li assert(isTargetMacOS() && "unexpected target");
1148*67e74705SXin Li CmdArgs.push_back("-macosx_version_min");
1149*67e74705SXin Li }
1150*67e74705SXin Li
1151*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
1152*67e74705SXin Li }
1153*67e74705SXin Li
addStartObjectFileArgs(const ArgList & Args,ArgStringList & CmdArgs) const1154*67e74705SXin Li void Darwin::addStartObjectFileArgs(const ArgList &Args,
1155*67e74705SXin Li ArgStringList &CmdArgs) const {
1156*67e74705SXin Li // Derived from startfile spec.
1157*67e74705SXin Li if (Args.hasArg(options::OPT_dynamiclib)) {
1158*67e74705SXin Li // Derived from darwin_dylib1 spec.
1159*67e74705SXin Li if (isTargetWatchOSBased()) {
1160*67e74705SXin Li ; // watchOS does not need dylib1.o.
1161*67e74705SXin Li } else if (isTargetIOSSimulator()) {
1162*67e74705SXin Li ; // iOS simulator does not need dylib1.o.
1163*67e74705SXin Li } else if (isTargetIPhoneOS()) {
1164*67e74705SXin Li if (isIPhoneOSVersionLT(3, 1))
1165*67e74705SXin Li CmdArgs.push_back("-ldylib1.o");
1166*67e74705SXin Li } else {
1167*67e74705SXin Li if (isMacosxVersionLT(10, 5))
1168*67e74705SXin Li CmdArgs.push_back("-ldylib1.o");
1169*67e74705SXin Li else if (isMacosxVersionLT(10, 6))
1170*67e74705SXin Li CmdArgs.push_back("-ldylib1.10.5.o");
1171*67e74705SXin Li }
1172*67e74705SXin Li } else {
1173*67e74705SXin Li if (Args.hasArg(options::OPT_bundle)) {
1174*67e74705SXin Li if (!Args.hasArg(options::OPT_static)) {
1175*67e74705SXin Li // Derived from darwin_bundle1 spec.
1176*67e74705SXin Li if (isTargetWatchOSBased()) {
1177*67e74705SXin Li ; // watchOS does not need bundle1.o.
1178*67e74705SXin Li } else if (isTargetIOSSimulator()) {
1179*67e74705SXin Li ; // iOS simulator does not need bundle1.o.
1180*67e74705SXin Li } else if (isTargetIPhoneOS()) {
1181*67e74705SXin Li if (isIPhoneOSVersionLT(3, 1))
1182*67e74705SXin Li CmdArgs.push_back("-lbundle1.o");
1183*67e74705SXin Li } else {
1184*67e74705SXin Li if (isMacosxVersionLT(10, 6))
1185*67e74705SXin Li CmdArgs.push_back("-lbundle1.o");
1186*67e74705SXin Li }
1187*67e74705SXin Li }
1188*67e74705SXin Li } else {
1189*67e74705SXin Li if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
1190*67e74705SXin Li if (Args.hasArg(options::OPT_static) ||
1191*67e74705SXin Li Args.hasArg(options::OPT_object) ||
1192*67e74705SXin Li Args.hasArg(options::OPT_preload)) {
1193*67e74705SXin Li CmdArgs.push_back("-lgcrt0.o");
1194*67e74705SXin Li } else {
1195*67e74705SXin Li CmdArgs.push_back("-lgcrt1.o");
1196*67e74705SXin Li
1197*67e74705SXin Li // darwin_crt2 spec is empty.
1198*67e74705SXin Li }
1199*67e74705SXin Li // By default on OS X 10.8 and later, we don't link with a crt1.o
1200*67e74705SXin Li // file and the linker knows to use _main as the entry point. But,
1201*67e74705SXin Li // when compiling with -pg, we need to link with the gcrt1.o file,
1202*67e74705SXin Li // so pass the -no_new_main option to tell the linker to use the
1203*67e74705SXin Li // "start" symbol as the entry point.
1204*67e74705SXin Li if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
1205*67e74705SXin Li CmdArgs.push_back("-no_new_main");
1206*67e74705SXin Li } else {
1207*67e74705SXin Li if (Args.hasArg(options::OPT_static) ||
1208*67e74705SXin Li Args.hasArg(options::OPT_object) ||
1209*67e74705SXin Li Args.hasArg(options::OPT_preload)) {
1210*67e74705SXin Li CmdArgs.push_back("-lcrt0.o");
1211*67e74705SXin Li } else {
1212*67e74705SXin Li // Derived from darwin_crt1 spec.
1213*67e74705SXin Li if (isTargetWatchOSBased()) {
1214*67e74705SXin Li ; // watchOS does not need crt1.o.
1215*67e74705SXin Li } else if (isTargetIOSSimulator()) {
1216*67e74705SXin Li ; // iOS simulator does not need crt1.o.
1217*67e74705SXin Li } else if (isTargetIPhoneOS()) {
1218*67e74705SXin Li if (getArch() == llvm::Triple::aarch64)
1219*67e74705SXin Li ; // iOS does not need any crt1 files for arm64
1220*67e74705SXin Li else if (isIPhoneOSVersionLT(3, 1))
1221*67e74705SXin Li CmdArgs.push_back("-lcrt1.o");
1222*67e74705SXin Li else if (isIPhoneOSVersionLT(6, 0))
1223*67e74705SXin Li CmdArgs.push_back("-lcrt1.3.1.o");
1224*67e74705SXin Li } else {
1225*67e74705SXin Li if (isMacosxVersionLT(10, 5))
1226*67e74705SXin Li CmdArgs.push_back("-lcrt1.o");
1227*67e74705SXin Li else if (isMacosxVersionLT(10, 6))
1228*67e74705SXin Li CmdArgs.push_back("-lcrt1.10.5.o");
1229*67e74705SXin Li else if (isMacosxVersionLT(10, 8))
1230*67e74705SXin Li CmdArgs.push_back("-lcrt1.10.6.o");
1231*67e74705SXin Li
1232*67e74705SXin Li // darwin_crt2 spec is empty.
1233*67e74705SXin Li }
1234*67e74705SXin Li }
1235*67e74705SXin Li }
1236*67e74705SXin Li }
1237*67e74705SXin Li }
1238*67e74705SXin Li
1239*67e74705SXin Li if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
1240*67e74705SXin Li !isTargetWatchOS() &&
1241*67e74705SXin Li isMacosxVersionLT(10, 5)) {
1242*67e74705SXin Li const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
1243*67e74705SXin Li CmdArgs.push_back(Str);
1244*67e74705SXin Li }
1245*67e74705SXin Li }
1246*67e74705SXin Li
SupportsObjCGC() const1247*67e74705SXin Li bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); }
1248*67e74705SXin Li
CheckObjCARC() const1249*67e74705SXin Li void Darwin::CheckObjCARC() const {
1250*67e74705SXin Li if (isTargetIOSBased() || isTargetWatchOSBased() ||
1251*67e74705SXin Li (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
1252*67e74705SXin Li return;
1253*67e74705SXin Li getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
1254*67e74705SXin Li }
1255*67e74705SXin Li
getSupportedSanitizers() const1256*67e74705SXin Li SanitizerMask Darwin::getSupportedSanitizers() const {
1257*67e74705SXin Li const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
1258*67e74705SXin Li SanitizerMask Res = ToolChain::getSupportedSanitizers();
1259*67e74705SXin Li Res |= SanitizerKind::Address;
1260*67e74705SXin Li if (isTargetMacOS()) {
1261*67e74705SXin Li if (!isMacosxVersionLT(10, 9))
1262*67e74705SXin Li Res |= SanitizerKind::Vptr;
1263*67e74705SXin Li Res |= SanitizerKind::SafeStack;
1264*67e74705SXin Li if (IsX86_64)
1265*67e74705SXin Li Res |= SanitizerKind::Thread;
1266*67e74705SXin Li } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
1267*67e74705SXin Li if (IsX86_64)
1268*67e74705SXin Li Res |= SanitizerKind::Thread;
1269*67e74705SXin Li }
1270*67e74705SXin Li return Res;
1271*67e74705SXin Li }
1272*67e74705SXin Li
1273*67e74705SXin Li /// Generic_GCC - A tool chain using the 'gcc' command to perform
1274*67e74705SXin Li /// all subcommands; this relies on gcc translating the majority of
1275*67e74705SXin Li /// command line options.
1276*67e74705SXin Li
1277*67e74705SXin Li /// \brief Parse a GCCVersion object out of a string of text.
1278*67e74705SXin Li ///
1279*67e74705SXin Li /// This is the primary means of forming GCCVersion objects.
1280*67e74705SXin Li /*static*/
Parse(StringRef VersionText)1281*67e74705SXin Li Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
1282*67e74705SXin Li const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
1283*67e74705SXin Li std::pair<StringRef, StringRef> First = VersionText.split('.');
1284*67e74705SXin Li std::pair<StringRef, StringRef> Second = First.second.split('.');
1285*67e74705SXin Li
1286*67e74705SXin Li GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
1287*67e74705SXin Li if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
1288*67e74705SXin Li return BadVersion;
1289*67e74705SXin Li GoodVersion.MajorStr = First.first.str();
1290*67e74705SXin Li if (First.second.empty())
1291*67e74705SXin Li return GoodVersion;
1292*67e74705SXin Li if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
1293*67e74705SXin Li return BadVersion;
1294*67e74705SXin Li GoodVersion.MinorStr = Second.first.str();
1295*67e74705SXin Li
1296*67e74705SXin Li // First look for a number prefix and parse that if present. Otherwise just
1297*67e74705SXin Li // stash the entire patch string in the suffix, and leave the number
1298*67e74705SXin Li // unspecified. This covers versions strings such as:
1299*67e74705SXin Li // 5 (handled above)
1300*67e74705SXin Li // 4.4
1301*67e74705SXin Li // 4.4.0
1302*67e74705SXin Li // 4.4.x
1303*67e74705SXin Li // 4.4.2-rc4
1304*67e74705SXin Li // 4.4.x-patched
1305*67e74705SXin Li // And retains any patch number it finds.
1306*67e74705SXin Li StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
1307*67e74705SXin Li if (!PatchText.empty()) {
1308*67e74705SXin Li if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
1309*67e74705SXin Li // Try to parse the number and any suffix.
1310*67e74705SXin Li if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
1311*67e74705SXin Li GoodVersion.Patch < 0)
1312*67e74705SXin Li return BadVersion;
1313*67e74705SXin Li GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
1314*67e74705SXin Li }
1315*67e74705SXin Li }
1316*67e74705SXin Li
1317*67e74705SXin Li return GoodVersion;
1318*67e74705SXin Li }
1319*67e74705SXin Li
1320*67e74705SXin Li /// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
isOlderThan(int RHSMajor,int RHSMinor,int RHSPatch,StringRef RHSPatchSuffix) const1321*67e74705SXin Li bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
1322*67e74705SXin Li int RHSPatch,
1323*67e74705SXin Li StringRef RHSPatchSuffix) const {
1324*67e74705SXin Li if (Major != RHSMajor)
1325*67e74705SXin Li return Major < RHSMajor;
1326*67e74705SXin Li if (Minor != RHSMinor)
1327*67e74705SXin Li return Minor < RHSMinor;
1328*67e74705SXin Li if (Patch != RHSPatch) {
1329*67e74705SXin Li // Note that versions without a specified patch sort higher than those with
1330*67e74705SXin Li // a patch.
1331*67e74705SXin Li if (RHSPatch == -1)
1332*67e74705SXin Li return true;
1333*67e74705SXin Li if (Patch == -1)
1334*67e74705SXin Li return false;
1335*67e74705SXin Li
1336*67e74705SXin Li // Otherwise just sort on the patch itself.
1337*67e74705SXin Li return Patch < RHSPatch;
1338*67e74705SXin Li }
1339*67e74705SXin Li if (PatchSuffix != RHSPatchSuffix) {
1340*67e74705SXin Li // Sort empty suffixes higher.
1341*67e74705SXin Li if (RHSPatchSuffix.empty())
1342*67e74705SXin Li return true;
1343*67e74705SXin Li if (PatchSuffix.empty())
1344*67e74705SXin Li return false;
1345*67e74705SXin Li
1346*67e74705SXin Li // Provide a lexicographic sort to make this a total ordering.
1347*67e74705SXin Li return PatchSuffix < RHSPatchSuffix;
1348*67e74705SXin Li }
1349*67e74705SXin Li
1350*67e74705SXin Li // The versions are equal.
1351*67e74705SXin Li return false;
1352*67e74705SXin Li }
1353*67e74705SXin Li
getGCCToolchainDir(const ArgList & Args)1354*67e74705SXin Li static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
1355*67e74705SXin Li const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
1356*67e74705SXin Li if (A)
1357*67e74705SXin Li return A->getValue();
1358*67e74705SXin Li return GCC_INSTALL_PREFIX;
1359*67e74705SXin Li }
1360*67e74705SXin Li
1361*67e74705SXin Li /// \brief Initialize a GCCInstallationDetector from the driver.
1362*67e74705SXin Li ///
1363*67e74705SXin Li /// This performs all of the autodetection and sets up the various paths.
1364*67e74705SXin Li /// Once constructed, a GCCInstallationDetector is essentially immutable.
1365*67e74705SXin Li ///
1366*67e74705SXin Li /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1367*67e74705SXin Li /// should instead pull the target out of the driver. This is currently
1368*67e74705SXin Li /// necessary because the driver doesn't store the final version of the target
1369*67e74705SXin Li /// triple.
init(const llvm::Triple & TargetTriple,const ArgList & Args,ArrayRef<std::string> ExtraTripleAliases)1370*67e74705SXin Li void Generic_GCC::GCCInstallationDetector::init(
1371*67e74705SXin Li const llvm::Triple &TargetTriple, const ArgList &Args,
1372*67e74705SXin Li ArrayRef<std::string> ExtraTripleAliases) {
1373*67e74705SXin Li llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
1374*67e74705SXin Li ? TargetTriple.get64BitArchVariant()
1375*67e74705SXin Li : TargetTriple.get32BitArchVariant();
1376*67e74705SXin Li // The library directories which may contain GCC installations.
1377*67e74705SXin Li SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
1378*67e74705SXin Li // The compatible GCC triples for this particular architecture.
1379*67e74705SXin Li SmallVector<StringRef, 16> CandidateTripleAliases;
1380*67e74705SXin Li SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
1381*67e74705SXin Li CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
1382*67e74705SXin Li CandidateTripleAliases, CandidateBiarchLibDirs,
1383*67e74705SXin Li CandidateBiarchTripleAliases);
1384*67e74705SXin Li
1385*67e74705SXin Li // Compute the set of prefixes for our search.
1386*67e74705SXin Li SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1387*67e74705SXin Li D.PrefixDirs.end());
1388*67e74705SXin Li
1389*67e74705SXin Li StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1390*67e74705SXin Li if (GCCToolchainDir != "") {
1391*67e74705SXin Li if (GCCToolchainDir.back() == '/')
1392*67e74705SXin Li GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
1393*67e74705SXin Li
1394*67e74705SXin Li Prefixes.push_back(GCCToolchainDir);
1395*67e74705SXin Li } else {
1396*67e74705SXin Li // If we have a SysRoot, try that first.
1397*67e74705SXin Li if (!D.SysRoot.empty()) {
1398*67e74705SXin Li Prefixes.push_back(D.SysRoot);
1399*67e74705SXin Li Prefixes.push_back(D.SysRoot + "/usr");
1400*67e74705SXin Li }
1401*67e74705SXin Li
1402*67e74705SXin Li // Then look for gcc installed alongside clang.
1403*67e74705SXin Li Prefixes.push_back(D.InstalledDir + "/..");
1404*67e74705SXin Li
1405*67e74705SXin Li // Then look for distribution supplied gcc installations.
1406*67e74705SXin Li if (D.SysRoot.empty()) {
1407*67e74705SXin Li // Look for RHEL devtoolsets.
1408*67e74705SXin Li Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
1409*67e74705SXin Li Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
1410*67e74705SXin Li Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
1411*67e74705SXin Li Prefixes.push_back("/opt/rh/devtoolset-1.1/root/usr");
1412*67e74705SXin Li Prefixes.push_back("/opt/rh/devtoolset-1.0/root/usr");
1413*67e74705SXin Li // And finally in /usr.
1414*67e74705SXin Li Prefixes.push_back("/usr");
1415*67e74705SXin Li }
1416*67e74705SXin Li }
1417*67e74705SXin Li
1418*67e74705SXin Li // Loop over the various components which exist and select the best GCC
1419*67e74705SXin Li // installation available. GCC installs are ranked by version number.
1420*67e74705SXin Li Version = GCCVersion::Parse("0.0.0");
1421*67e74705SXin Li for (const std::string &Prefix : Prefixes) {
1422*67e74705SXin Li if (!D.getVFS().exists(Prefix))
1423*67e74705SXin Li continue;
1424*67e74705SXin Li for (StringRef Suffix : CandidateLibDirs) {
1425*67e74705SXin Li const std::string LibDir = Prefix + Suffix.str();
1426*67e74705SXin Li if (!D.getVFS().exists(LibDir))
1427*67e74705SXin Li continue;
1428*67e74705SXin Li for (StringRef Candidate : ExtraTripleAliases) // Try these first.
1429*67e74705SXin Li ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
1430*67e74705SXin Li for (StringRef Candidate : CandidateTripleAliases)
1431*67e74705SXin Li ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
1432*67e74705SXin Li }
1433*67e74705SXin Li for (StringRef Suffix : CandidateBiarchLibDirs) {
1434*67e74705SXin Li const std::string LibDir = Prefix + Suffix.str();
1435*67e74705SXin Li if (!D.getVFS().exists(LibDir))
1436*67e74705SXin Li continue;
1437*67e74705SXin Li for (StringRef Candidate : CandidateBiarchTripleAliases)
1438*67e74705SXin Li ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,
1439*67e74705SXin Li /*NeedsBiarchSuffix=*/ true);
1440*67e74705SXin Li }
1441*67e74705SXin Li }
1442*67e74705SXin Li }
1443*67e74705SXin Li
print(raw_ostream & OS) const1444*67e74705SXin Li void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
1445*67e74705SXin Li for (const auto &InstallPath : CandidateGCCInstallPaths)
1446*67e74705SXin Li OS << "Found candidate GCC installation: " << InstallPath << "\n";
1447*67e74705SXin Li
1448*67e74705SXin Li if (!GCCInstallPath.empty())
1449*67e74705SXin Li OS << "Selected GCC installation: " << GCCInstallPath << "\n";
1450*67e74705SXin Li
1451*67e74705SXin Li for (const auto &Multilib : Multilibs)
1452*67e74705SXin Li OS << "Candidate multilib: " << Multilib << "\n";
1453*67e74705SXin Li
1454*67e74705SXin Li if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
1455*67e74705SXin Li OS << "Selected multilib: " << SelectedMultilib << "\n";
1456*67e74705SXin Li }
1457*67e74705SXin Li
getBiarchSibling(Multilib & M) const1458*67e74705SXin Li bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
1459*67e74705SXin Li if (BiarchSibling.hasValue()) {
1460*67e74705SXin Li M = BiarchSibling.getValue();
1461*67e74705SXin Li return true;
1462*67e74705SXin Li }
1463*67e74705SXin Li return false;
1464*67e74705SXin Li }
1465*67e74705SXin Li
CollectLibDirsAndTriples(const llvm::Triple & TargetTriple,const llvm::Triple & BiarchTriple,SmallVectorImpl<StringRef> & LibDirs,SmallVectorImpl<StringRef> & TripleAliases,SmallVectorImpl<StringRef> & BiarchLibDirs,SmallVectorImpl<StringRef> & BiarchTripleAliases)1466*67e74705SXin Li /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
1467*67e74705SXin Li const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
1468*67e74705SXin Li SmallVectorImpl<StringRef> &LibDirs,
1469*67e74705SXin Li SmallVectorImpl<StringRef> &TripleAliases,
1470*67e74705SXin Li SmallVectorImpl<StringRef> &BiarchLibDirs,
1471*67e74705SXin Li SmallVectorImpl<StringRef> &BiarchTripleAliases) {
1472*67e74705SXin Li // Declare a bunch of static data sets that we'll select between below. These
1473*67e74705SXin Li // are specifically designed to always refer to string literals to avoid any
1474*67e74705SXin Li // lifetime or initialization issues.
1475*67e74705SXin Li static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
1476*67e74705SXin Li static const char *const AArch64Triples[] = {
1477*67e74705SXin Li "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
1478*67e74705SXin Li "aarch64-redhat-linux"};
1479*67e74705SXin Li static const char *const AArch64beLibDirs[] = {"/lib"};
1480*67e74705SXin Li static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
1481*67e74705SXin Li "aarch64_be-linux-gnu"};
1482*67e74705SXin Li
1483*67e74705SXin Li static const char *const ARMLibDirs[] = {"/lib"};
1484*67e74705SXin Li static const char *const ARMTriples[] = {"arm-linux-gnueabi",
1485*67e74705SXin Li "arm-linux-androideabi"};
1486*67e74705SXin Li static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
1487*67e74705SXin Li "armv7hl-redhat-linux-gnueabi"};
1488*67e74705SXin Li static const char *const ARMebLibDirs[] = {"/lib"};
1489*67e74705SXin Li static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
1490*67e74705SXin Li "armeb-linux-androideabi"};
1491*67e74705SXin Li static const char *const ARMebHFTriples[] = {
1492*67e74705SXin Li "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
1493*67e74705SXin Li
1494*67e74705SXin Li static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
1495*67e74705SXin Li static const char *const X86_64Triples[] = {
1496*67e74705SXin Li "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
1497*67e74705SXin Li "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
1498*67e74705SXin Li "x86_64-redhat-linux", "x86_64-suse-linux",
1499*67e74705SXin Li "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
1500*67e74705SXin Li "x86_64-slackware-linux", "x86_64-linux-android",
1501*67e74705SXin Li "x86_64-unknown-linux"};
1502*67e74705SXin Li static const char *const X32LibDirs[] = {"/libx32"};
1503*67e74705SXin Li static const char *const X86LibDirs[] = {"/lib32", "/lib"};
1504*67e74705SXin Li static const char *const X86Triples[] = {
1505*67e74705SXin Li "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu",
1506*67e74705SXin Li "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux",
1507*67e74705SXin Li "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux",
1508*67e74705SXin Li "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
1509*67e74705SXin Li "i586-linux-gnu"};
1510*67e74705SXin Li
1511*67e74705SXin Li static const char *const MIPSLibDirs[] = {"/lib"};
1512*67e74705SXin Li static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
1513*67e74705SXin Li "mips-mti-linux-gnu",
1514*67e74705SXin Li "mips-img-linux-gnu"};
1515*67e74705SXin Li static const char *const MIPSELLibDirs[] = {"/lib"};
1516*67e74705SXin Li static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
1517*67e74705SXin Li "mips-img-linux-gnu"};
1518*67e74705SXin Li
1519*67e74705SXin Li static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
1520*67e74705SXin Li static const char *const MIPS64Triples[] = {
1521*67e74705SXin Li "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
1522*67e74705SXin Li "mips64-linux-gnuabi64"};
1523*67e74705SXin Li static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};
1524*67e74705SXin Li static const char *const MIPS64ELTriples[] = {
1525*67e74705SXin Li "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
1526*67e74705SXin Li "mips64el-linux-gnuabi64"};
1527*67e74705SXin Li
1528*67e74705SXin Li static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2",
1529*67e74705SXin Li "/libr6"};
1530*67e74705SXin Li static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
1531*67e74705SXin Li static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib",
1532*67e74705SXin Li "/libr2", "/libr6"};
1533*67e74705SXin Li static const char *const MIPS64ELAndroidTriples[] = {
1534*67e74705SXin Li "mips64el-linux-android"};
1535*67e74705SXin Li
1536*67e74705SXin Li static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
1537*67e74705SXin Li static const char *const PPCTriples[] = {
1538*67e74705SXin Li "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
1539*67e74705SXin Li "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
1540*67e74705SXin Li static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
1541*67e74705SXin Li static const char *const PPC64Triples[] = {
1542*67e74705SXin Li "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
1543*67e74705SXin Li "powerpc64-suse-linux", "ppc64-redhat-linux"};
1544*67e74705SXin Li static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
1545*67e74705SXin Li static const char *const PPC64LETriples[] = {
1546*67e74705SXin Li "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
1547*67e74705SXin Li "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
1548*67e74705SXin Li
1549*67e74705SXin Li static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
1550*67e74705SXin Li static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
1551*67e74705SXin Li "sparcv8-linux-gnu"};
1552*67e74705SXin Li static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
1553*67e74705SXin Li static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
1554*67e74705SXin Li "sparcv9-linux-gnu"};
1555*67e74705SXin Li
1556*67e74705SXin Li static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
1557*67e74705SXin Li static const char *const SystemZTriples[] = {
1558*67e74705SXin Li "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
1559*67e74705SXin Li "s390x-suse-linux", "s390x-redhat-linux"};
1560*67e74705SXin Li
1561*67e74705SXin Li // Solaris.
1562*67e74705SXin Li static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
1563*67e74705SXin Li static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
1564*67e74705SXin Li "i386-pc-solaris2.11"};
1565*67e74705SXin Li
1566*67e74705SXin Li using std::begin;
1567*67e74705SXin Li using std::end;
1568*67e74705SXin Li
1569*67e74705SXin Li if (TargetTriple.getOS() == llvm::Triple::Solaris) {
1570*67e74705SXin Li LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
1571*67e74705SXin Li TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
1572*67e74705SXin Li return;
1573*67e74705SXin Li }
1574*67e74705SXin Li
1575*67e74705SXin Li switch (TargetTriple.getArch()) {
1576*67e74705SXin Li case llvm::Triple::aarch64:
1577*67e74705SXin Li LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1578*67e74705SXin Li TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1579*67e74705SXin Li BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1580*67e74705SXin Li BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1581*67e74705SXin Li break;
1582*67e74705SXin Li case llvm::Triple::aarch64_be:
1583*67e74705SXin Li LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1584*67e74705SXin Li TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1585*67e74705SXin Li BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1586*67e74705SXin Li BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1587*67e74705SXin Li break;
1588*67e74705SXin Li case llvm::Triple::arm:
1589*67e74705SXin Li case llvm::Triple::thumb:
1590*67e74705SXin Li LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
1591*67e74705SXin Li if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1592*67e74705SXin Li TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
1593*67e74705SXin Li } else {
1594*67e74705SXin Li TripleAliases.append(begin(ARMTriples), end(ARMTriples));
1595*67e74705SXin Li }
1596*67e74705SXin Li break;
1597*67e74705SXin Li case llvm::Triple::armeb:
1598*67e74705SXin Li case llvm::Triple::thumbeb:
1599*67e74705SXin Li LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
1600*67e74705SXin Li if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1601*67e74705SXin Li TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
1602*67e74705SXin Li } else {
1603*67e74705SXin Li TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
1604*67e74705SXin Li }
1605*67e74705SXin Li break;
1606*67e74705SXin Li case llvm::Triple::x86_64:
1607*67e74705SXin Li LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1608*67e74705SXin Li TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1609*67e74705SXin Li // x32 is always available when x86_64 is available, so adding it as
1610*67e74705SXin Li // secondary arch with x86_64 triples
1611*67e74705SXin Li if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
1612*67e74705SXin Li BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
1613*67e74705SXin Li BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1614*67e74705SXin Li } else {
1615*67e74705SXin Li BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1616*67e74705SXin Li BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
1617*67e74705SXin Li }
1618*67e74705SXin Li break;
1619*67e74705SXin Li case llvm::Triple::x86:
1620*67e74705SXin Li LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1621*67e74705SXin Li // MCU toolchain is 32 bit only and its triple alias is TargetTriple
1622*67e74705SXin Li // itself, which will be appended below.
1623*67e74705SXin Li if (!TargetTriple.isOSIAMCU()) {
1624*67e74705SXin Li TripleAliases.append(begin(X86Triples), end(X86Triples));
1625*67e74705SXin Li BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1626*67e74705SXin Li BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1627*67e74705SXin Li }
1628*67e74705SXin Li break;
1629*67e74705SXin Li case llvm::Triple::mips:
1630*67e74705SXin Li LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1631*67e74705SXin Li TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1632*67e74705SXin Li BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1633*67e74705SXin Li BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1634*67e74705SXin Li break;
1635*67e74705SXin Li case llvm::Triple::mipsel:
1636*67e74705SXin Li if (TargetTriple.isAndroid()) {
1637*67e74705SXin Li LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs));
1638*67e74705SXin Li TripleAliases.append(begin(MIPSELAndroidTriples),
1639*67e74705SXin Li end(MIPSELAndroidTriples));
1640*67e74705SXin Li BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs),
1641*67e74705SXin Li end(MIPS64ELAndroidLibDirs));
1642*67e74705SXin Li BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
1643*67e74705SXin Li end(MIPS64ELAndroidTriples));
1644*67e74705SXin Li
1645*67e74705SXin Li } else {
1646*67e74705SXin Li LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1647*67e74705SXin Li TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1648*67e74705SXin Li TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1649*67e74705SXin Li BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1650*67e74705SXin Li BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1651*67e74705SXin Li }
1652*67e74705SXin Li break;
1653*67e74705SXin Li case llvm::Triple::mips64:
1654*67e74705SXin Li LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1655*67e74705SXin Li TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1656*67e74705SXin Li BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1657*67e74705SXin Li BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1658*67e74705SXin Li break;
1659*67e74705SXin Li case llvm::Triple::mips64el:
1660*67e74705SXin Li if (TargetTriple.isAndroid()) {
1661*67e74705SXin Li LibDirs.append(begin(MIPS64ELAndroidLibDirs),
1662*67e74705SXin Li end(MIPS64ELAndroidLibDirs));
1663*67e74705SXin Li TripleAliases.append(begin(MIPS64ELAndroidTriples),
1664*67e74705SXin Li end(MIPS64ELAndroidTriples));
1665*67e74705SXin Li BiarchLibDirs.append(begin(MIPSELAndroidLibDirs),
1666*67e74705SXin Li end(MIPSELAndroidLibDirs));
1667*67e74705SXin Li BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
1668*67e74705SXin Li end(MIPSELAndroidTriples));
1669*67e74705SXin Li
1670*67e74705SXin Li } else {
1671*67e74705SXin Li LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1672*67e74705SXin Li TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1673*67e74705SXin Li BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1674*67e74705SXin Li BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1675*67e74705SXin Li BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1676*67e74705SXin Li }
1677*67e74705SXin Li break;
1678*67e74705SXin Li case llvm::Triple::ppc:
1679*67e74705SXin Li LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1680*67e74705SXin Li TripleAliases.append(begin(PPCTriples), end(PPCTriples));
1681*67e74705SXin Li BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1682*67e74705SXin Li BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1683*67e74705SXin Li break;
1684*67e74705SXin Li case llvm::Triple::ppc64:
1685*67e74705SXin Li LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1686*67e74705SXin Li TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1687*67e74705SXin Li BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1688*67e74705SXin Li BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
1689*67e74705SXin Li break;
1690*67e74705SXin Li case llvm::Triple::ppc64le:
1691*67e74705SXin Li LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
1692*67e74705SXin Li TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
1693*67e74705SXin Li break;
1694*67e74705SXin Li case llvm::Triple::sparc:
1695*67e74705SXin Li case llvm::Triple::sparcel:
1696*67e74705SXin Li LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1697*67e74705SXin Li TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1698*67e74705SXin Li BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1699*67e74705SXin Li BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1700*67e74705SXin Li break;
1701*67e74705SXin Li case llvm::Triple::sparcv9:
1702*67e74705SXin Li LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1703*67e74705SXin Li TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1704*67e74705SXin Li BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1705*67e74705SXin Li BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1706*67e74705SXin Li break;
1707*67e74705SXin Li case llvm::Triple::systemz:
1708*67e74705SXin Li LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
1709*67e74705SXin Li TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
1710*67e74705SXin Li break;
1711*67e74705SXin Li default:
1712*67e74705SXin Li // By default, just rely on the standard lib directories and the original
1713*67e74705SXin Li // triple.
1714*67e74705SXin Li break;
1715*67e74705SXin Li }
1716*67e74705SXin Li
1717*67e74705SXin Li // Always append the drivers target triple to the end, in case it doesn't
1718*67e74705SXin Li // match any of our aliases.
1719*67e74705SXin Li TripleAliases.push_back(TargetTriple.str());
1720*67e74705SXin Li
1721*67e74705SXin Li // Also include the multiarch variant if it's different.
1722*67e74705SXin Li if (TargetTriple.str() != BiarchTriple.str())
1723*67e74705SXin Li BiarchTripleAliases.push_back(BiarchTriple.str());
1724*67e74705SXin Li }
1725*67e74705SXin Li
1726*67e74705SXin Li // Parses the contents of version.txt in an CUDA installation. It should
1727*67e74705SXin Li // contain one line of the from e.g. "CUDA Version 7.5.2".
ParseCudaVersionFile(llvm::StringRef V)1728*67e74705SXin Li static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
1729*67e74705SXin Li if (!V.startswith("CUDA Version "))
1730*67e74705SXin Li return CudaVersion::UNKNOWN;
1731*67e74705SXin Li V = V.substr(strlen("CUDA Version "));
1732*67e74705SXin Li int Major = -1, Minor = -1;
1733*67e74705SXin Li auto First = V.split('.');
1734*67e74705SXin Li auto Second = First.second.split('.');
1735*67e74705SXin Li if (!First.first.getAsInteger(10, Major) ||
1736*67e74705SXin Li !Second.first.getAsInteger(10, Minor))
1737*67e74705SXin Li return CudaVersion::UNKNOWN;
1738*67e74705SXin Li
1739*67e74705SXin Li if (Major == 7 && Minor == 0) {
1740*67e74705SXin Li // This doesn't appear to ever happen -- version.txt doesn't exist in the
1741*67e74705SXin Li // CUDA 7 installs I've seen. But no harm in checking.
1742*67e74705SXin Li return CudaVersion::CUDA_70;
1743*67e74705SXin Li }
1744*67e74705SXin Li if (Major == 7 && Minor == 5)
1745*67e74705SXin Li return CudaVersion::CUDA_75;
1746*67e74705SXin Li if (Major == 8 && Minor == 0)
1747*67e74705SXin Li return CudaVersion::CUDA_80;
1748*67e74705SXin Li return CudaVersion::UNKNOWN;
1749*67e74705SXin Li }
1750*67e74705SXin Li
1751*67e74705SXin Li // \brief -- try common CUDA installation paths looking for files we need for
1752*67e74705SXin Li // CUDA compilation.
init(const llvm::Triple & TargetTriple,const llvm::opt::ArgList & Args)1753*67e74705SXin Li void Generic_GCC::CudaInstallationDetector::init(
1754*67e74705SXin Li const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args) {
1755*67e74705SXin Li SmallVector<std::string, 4> CudaPathCandidates;
1756*67e74705SXin Li
1757*67e74705SXin Li if (Args.hasArg(options::OPT_cuda_path_EQ))
1758*67e74705SXin Li CudaPathCandidates.push_back(
1759*67e74705SXin Li Args.getLastArgValue(options::OPT_cuda_path_EQ));
1760*67e74705SXin Li else {
1761*67e74705SXin Li CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
1762*67e74705SXin Li // FIXME: Uncomment this once we can compile the cuda 8 headers.
1763*67e74705SXin Li // CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-8.0");
1764*67e74705SXin Li CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.5");
1765*67e74705SXin Li CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.0");
1766*67e74705SXin Li }
1767*67e74705SXin Li
1768*67e74705SXin Li for (const auto &CudaPath : CudaPathCandidates) {
1769*67e74705SXin Li if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
1770*67e74705SXin Li continue;
1771*67e74705SXin Li
1772*67e74705SXin Li InstallPath = CudaPath;
1773*67e74705SXin Li BinPath = CudaPath + "/bin";
1774*67e74705SXin Li IncludePath = InstallPath + "/include";
1775*67e74705SXin Li LibDevicePath = InstallPath + "/nvvm/libdevice";
1776*67e74705SXin Li LibPath = InstallPath + (TargetTriple.isArch64Bit() ? "/lib64" : "/lib");
1777*67e74705SXin Li
1778*67e74705SXin Li auto &FS = D.getVFS();
1779*67e74705SXin Li if (!(FS.exists(IncludePath) && FS.exists(BinPath) && FS.exists(LibPath) &&
1780*67e74705SXin Li FS.exists(LibDevicePath)))
1781*67e74705SXin Li continue;
1782*67e74705SXin Li
1783*67e74705SXin Li std::error_code EC;
1784*67e74705SXin Li for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE;
1785*67e74705SXin Li !EC && LI != LE; LI = LI.increment(EC)) {
1786*67e74705SXin Li StringRef FilePath = LI->path();
1787*67e74705SXin Li StringRef FileName = llvm::sys::path::filename(FilePath);
1788*67e74705SXin Li // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc
1789*67e74705SXin Li const StringRef LibDeviceName = "libdevice.";
1790*67e74705SXin Li if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
1791*67e74705SXin Li continue;
1792*67e74705SXin Li StringRef GpuArch = FileName.slice(
1793*67e74705SXin Li LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
1794*67e74705SXin Li LibDeviceMap[GpuArch] = FilePath.str();
1795*67e74705SXin Li // Insert map entries for specifc devices with this compute capability.
1796*67e74705SXin Li if (GpuArch == "compute_20") {
1797*67e74705SXin Li LibDeviceMap["sm_20"] = FilePath;
1798*67e74705SXin Li LibDeviceMap["sm_21"] = FilePath;
1799*67e74705SXin Li } else if (GpuArch == "compute_30") {
1800*67e74705SXin Li LibDeviceMap["sm_30"] = FilePath;
1801*67e74705SXin Li LibDeviceMap["sm_32"] = FilePath;
1802*67e74705SXin Li } else if (GpuArch == "compute_35") {
1803*67e74705SXin Li LibDeviceMap["sm_35"] = FilePath;
1804*67e74705SXin Li LibDeviceMap["sm_37"] = FilePath;
1805*67e74705SXin Li } else if (GpuArch == "compute_50") {
1806*67e74705SXin Li LibDeviceMap["sm_50"] = FilePath;
1807*67e74705SXin Li LibDeviceMap["sm_52"] = FilePath;
1808*67e74705SXin Li LibDeviceMap["sm_53"] = FilePath;
1809*67e74705SXin Li LibDeviceMap["sm_60"] = FilePath;
1810*67e74705SXin Li LibDeviceMap["sm_61"] = FilePath;
1811*67e74705SXin Li LibDeviceMap["sm_62"] = FilePath;
1812*67e74705SXin Li }
1813*67e74705SXin Li }
1814*67e74705SXin Li
1815*67e74705SXin Li llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
1816*67e74705SXin Li FS.getBufferForFile(InstallPath + "/version.txt");
1817*67e74705SXin Li if (!VersionFile) {
1818*67e74705SXin Li // CUDA 7.0 doesn't have a version.txt, so guess that's our version if
1819*67e74705SXin Li // version.txt isn't present.
1820*67e74705SXin Li Version = CudaVersion::CUDA_70;
1821*67e74705SXin Li } else {
1822*67e74705SXin Li Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
1823*67e74705SXin Li }
1824*67e74705SXin Li
1825*67e74705SXin Li IsValid = true;
1826*67e74705SXin Li break;
1827*67e74705SXin Li }
1828*67e74705SXin Li }
1829*67e74705SXin Li
CheckCudaVersionSupportsArch(CudaArch Arch) const1830*67e74705SXin Li void Generic_GCC::CudaInstallationDetector::CheckCudaVersionSupportsArch(
1831*67e74705SXin Li CudaArch Arch) const {
1832*67e74705SXin Li if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
1833*67e74705SXin Li ArchsWithVersionTooLowErrors.count(Arch) > 0)
1834*67e74705SXin Li return;
1835*67e74705SXin Li
1836*67e74705SXin Li auto RequiredVersion = MinVersionForCudaArch(Arch);
1837*67e74705SXin Li if (Version < RequiredVersion) {
1838*67e74705SXin Li ArchsWithVersionTooLowErrors.insert(Arch);
1839*67e74705SXin Li D.Diag(diag::err_drv_cuda_version_too_low)
1840*67e74705SXin Li << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version)
1841*67e74705SXin Li << CudaVersionToString(RequiredVersion);
1842*67e74705SXin Li }
1843*67e74705SXin Li }
1844*67e74705SXin Li
print(raw_ostream & OS) const1845*67e74705SXin Li void Generic_GCC::CudaInstallationDetector::print(raw_ostream &OS) const {
1846*67e74705SXin Li if (isValid())
1847*67e74705SXin Li OS << "Found CUDA installation: " << InstallPath << ", version "
1848*67e74705SXin Li << CudaVersionToString(Version) << "\n";
1849*67e74705SXin Li }
1850*67e74705SXin Li
1851*67e74705SXin Li namespace {
1852*67e74705SXin Li // Filter to remove Multilibs that don't exist as a suffix to Path
1853*67e74705SXin Li class FilterNonExistent {
1854*67e74705SXin Li StringRef Base, File;
1855*67e74705SXin Li vfs::FileSystem &VFS;
1856*67e74705SXin Li
1857*67e74705SXin Li public:
FilterNonExistent(StringRef Base,StringRef File,vfs::FileSystem & VFS)1858*67e74705SXin Li FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS)
1859*67e74705SXin Li : Base(Base), File(File), VFS(VFS) {}
operator ()(const Multilib & M)1860*67e74705SXin Li bool operator()(const Multilib &M) {
1861*67e74705SXin Li return !VFS.exists(Base + M.gccSuffix() + File);
1862*67e74705SXin Li }
1863*67e74705SXin Li };
1864*67e74705SXin Li } // end anonymous namespace
1865*67e74705SXin Li
addMultilibFlag(bool Enabled,const char * const Flag,std::vector<std::string> & Flags)1866*67e74705SXin Li static void addMultilibFlag(bool Enabled, const char *const Flag,
1867*67e74705SXin Li std::vector<std::string> &Flags) {
1868*67e74705SXin Li if (Enabled)
1869*67e74705SXin Li Flags.push_back(std::string("+") + Flag);
1870*67e74705SXin Li else
1871*67e74705SXin Li Flags.push_back(std::string("-") + Flag);
1872*67e74705SXin Li }
1873*67e74705SXin Li
isArmOrThumbArch(llvm::Triple::ArchType Arch)1874*67e74705SXin Li static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
1875*67e74705SXin Li return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
1876*67e74705SXin Li }
1877*67e74705SXin Li
isMipsArch(llvm::Triple::ArchType Arch)1878*67e74705SXin Li static bool isMipsArch(llvm::Triple::ArchType Arch) {
1879*67e74705SXin Li return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
1880*67e74705SXin Li Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1881*67e74705SXin Li }
1882*67e74705SXin Li
isMips32(llvm::Triple::ArchType Arch)1883*67e74705SXin Li static bool isMips32(llvm::Triple::ArchType Arch) {
1884*67e74705SXin Li return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
1885*67e74705SXin Li }
1886*67e74705SXin Li
isMips64(llvm::Triple::ArchType Arch)1887*67e74705SXin Li static bool isMips64(llvm::Triple::ArchType Arch) {
1888*67e74705SXin Li return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1889*67e74705SXin Li }
1890*67e74705SXin Li
isMipsEL(llvm::Triple::ArchType Arch)1891*67e74705SXin Li static bool isMipsEL(llvm::Triple::ArchType Arch) {
1892*67e74705SXin Li return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
1893*67e74705SXin Li }
1894*67e74705SXin Li
isMips16(const ArgList & Args)1895*67e74705SXin Li static bool isMips16(const ArgList &Args) {
1896*67e74705SXin Li Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
1897*67e74705SXin Li return A && A->getOption().matches(options::OPT_mips16);
1898*67e74705SXin Li }
1899*67e74705SXin Li
isMicroMips(const ArgList & Args)1900*67e74705SXin Li static bool isMicroMips(const ArgList &Args) {
1901*67e74705SXin Li Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
1902*67e74705SXin Li return A && A->getOption().matches(options::OPT_mmicromips);
1903*67e74705SXin Li }
1904*67e74705SXin Li
1905*67e74705SXin Li namespace {
1906*67e74705SXin Li struct DetectedMultilibs {
1907*67e74705SXin Li /// The set of multilibs that the detected installation supports.
1908*67e74705SXin Li MultilibSet Multilibs;
1909*67e74705SXin Li
1910*67e74705SXin Li /// The primary multilib appropriate for the given flags.
1911*67e74705SXin Li Multilib SelectedMultilib;
1912*67e74705SXin Li
1913*67e74705SXin Li /// On Biarch systems, this corresponds to the default multilib when
1914*67e74705SXin Li /// targeting the non-default multilib. Otherwise, it is empty.
1915*67e74705SXin Li llvm::Optional<Multilib> BiarchSibling;
1916*67e74705SXin Li };
1917*67e74705SXin Li } // end anonymous namespace
1918*67e74705SXin Li
makeMultilib(StringRef commonSuffix)1919*67e74705SXin Li static Multilib makeMultilib(StringRef commonSuffix) {
1920*67e74705SXin Li return Multilib(commonSuffix, commonSuffix, commonSuffix);
1921*67e74705SXin Li }
1922*67e74705SXin Li
findMipsCsMultilibs(const Multilib::flags_list & Flags,FilterNonExistent & NonExistent,DetectedMultilibs & Result)1923*67e74705SXin Li static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
1924*67e74705SXin Li FilterNonExistent &NonExistent,
1925*67e74705SXin Li DetectedMultilibs &Result) {
1926*67e74705SXin Li // Check for Code Sourcery toolchain multilibs
1927*67e74705SXin Li MultilibSet CSMipsMultilibs;
1928*67e74705SXin Li {
1929*67e74705SXin Li auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");
1930*67e74705SXin Li
1931*67e74705SXin Li auto MArchMicroMips =
1932*67e74705SXin Li makeMultilib("/micromips").flag("+m32").flag("+mmicromips");
1933*67e74705SXin Li
1934*67e74705SXin Li auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");
1935*67e74705SXin Li
1936*67e74705SXin Li auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
1937*67e74705SXin Li
1938*67e74705SXin Li auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");
1939*67e74705SXin Li
1940*67e74705SXin Li auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
1941*67e74705SXin Li
1942*67e74705SXin Li auto DefaultFloat =
1943*67e74705SXin Li makeMultilib("").flag("-msoft-float").flag("-mnan=2008");
1944*67e74705SXin Li
1945*67e74705SXin Li auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
1946*67e74705SXin Li
1947*67e74705SXin Li auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
1948*67e74705SXin Li
1949*67e74705SXin Li // Note that this one's osSuffix is ""
1950*67e74705SXin Li auto MAbi64 = makeMultilib("")
1951*67e74705SXin Li .gccSuffix("/64")
1952*67e74705SXin Li .includeSuffix("/64")
1953*67e74705SXin Li .flag("+mabi=n64")
1954*67e74705SXin Li .flag("-mabi=n32")
1955*67e74705SXin Li .flag("-m32");
1956*67e74705SXin Li
1957*67e74705SXin Li CSMipsMultilibs =
1958*67e74705SXin Li MultilibSet()
1959*67e74705SXin Li .Either(MArchMips16, MArchMicroMips, MArchDefault)
1960*67e74705SXin Li .Maybe(UCLibc)
1961*67e74705SXin Li .Either(SoftFloat, Nan2008, DefaultFloat)
1962*67e74705SXin Li .FilterOut("/micromips/nan2008")
1963*67e74705SXin Li .FilterOut("/mips16/nan2008")
1964*67e74705SXin Li .Either(BigEndian, LittleEndian)
1965*67e74705SXin Li .Maybe(MAbi64)
1966*67e74705SXin Li .FilterOut("/mips16.*/64")
1967*67e74705SXin Li .FilterOut("/micromips.*/64")
1968*67e74705SXin Li .FilterOut(NonExistent)
1969*67e74705SXin Li .setIncludeDirsCallback([](const Multilib &M) {
1970*67e74705SXin Li std::vector<std::string> Dirs({"/include"});
1971*67e74705SXin Li if (StringRef(M.includeSuffix()).startswith("/uclibc"))
1972*67e74705SXin Li Dirs.push_back(
1973*67e74705SXin Li "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
1974*67e74705SXin Li else
1975*67e74705SXin Li Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
1976*67e74705SXin Li return Dirs;
1977*67e74705SXin Li });
1978*67e74705SXin Li }
1979*67e74705SXin Li
1980*67e74705SXin Li MultilibSet DebianMipsMultilibs;
1981*67e74705SXin Li {
1982*67e74705SXin Li Multilib MAbiN32 =
1983*67e74705SXin Li Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");
1984*67e74705SXin Li
1985*67e74705SXin Li Multilib M64 = Multilib()
1986*67e74705SXin Li .gccSuffix("/64")
1987*67e74705SXin Li .includeSuffix("/64")
1988*67e74705SXin Li .flag("+m64")
1989*67e74705SXin Li .flag("-m32")
1990*67e74705SXin Li .flag("-mabi=n32");
1991*67e74705SXin Li
1992*67e74705SXin Li Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");
1993*67e74705SXin Li
1994*67e74705SXin Li DebianMipsMultilibs =
1995*67e74705SXin Li MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
1996*67e74705SXin Li }
1997*67e74705SXin Li
1998*67e74705SXin Li // Sort candidates. Toolchain that best meets the directories tree goes first.
1999*67e74705SXin Li // Then select the first toolchains matches command line flags.
2000*67e74705SXin Li MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
2001*67e74705SXin Li if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
2002*67e74705SXin Li std::iter_swap(Candidates, Candidates + 1);
2003*67e74705SXin Li for (const MultilibSet *Candidate : Candidates) {
2004*67e74705SXin Li if (Candidate->select(Flags, Result.SelectedMultilib)) {
2005*67e74705SXin Li if (Candidate == &DebianMipsMultilibs)
2006*67e74705SXin Li Result.BiarchSibling = Multilib();
2007*67e74705SXin Li Result.Multilibs = *Candidate;
2008*67e74705SXin Li return true;
2009*67e74705SXin Li }
2010*67e74705SXin Li }
2011*67e74705SXin Li return false;
2012*67e74705SXin Li }
2013*67e74705SXin Li
findMipsAndroidMultilibs(vfs::FileSystem & VFS,StringRef Path,const Multilib::flags_list & Flags,FilterNonExistent & NonExistent,DetectedMultilibs & Result)2014*67e74705SXin Li static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path,
2015*67e74705SXin Li const Multilib::flags_list &Flags,
2016*67e74705SXin Li FilterNonExistent &NonExistent,
2017*67e74705SXin Li DetectedMultilibs &Result) {
2018*67e74705SXin Li
2019*67e74705SXin Li MultilibSet AndroidMipsMultilibs =
2020*67e74705SXin Li MultilibSet()
2021*67e74705SXin Li .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
2022*67e74705SXin Li .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
2023*67e74705SXin Li .FilterOut(NonExistent);
2024*67e74705SXin Li
2025*67e74705SXin Li MultilibSet AndroidMipselMultilibs =
2026*67e74705SXin Li MultilibSet()
2027*67e74705SXin Li .Either(Multilib().flag("+march=mips32"),
2028*67e74705SXin Li Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2029*67e74705SXin Li Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2030*67e74705SXin Li .FilterOut(NonExistent);
2031*67e74705SXin Li
2032*67e74705SXin Li MultilibSet AndroidMips64elMultilibs =
2033*67e74705SXin Li MultilibSet()
2034*67e74705SXin Li .Either(
2035*67e74705SXin Li Multilib().flag("+march=mips64r6"),
2036*67e74705SXin Li Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
2037*67e74705SXin Li Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2038*67e74705SXin Li Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2039*67e74705SXin Li .FilterOut(NonExistent);
2040*67e74705SXin Li
2041*67e74705SXin Li MultilibSet *MS = &AndroidMipsMultilibs;
2042*67e74705SXin Li if (VFS.exists(Path + "/mips-r6"))
2043*67e74705SXin Li MS = &AndroidMipselMultilibs;
2044*67e74705SXin Li else if (VFS.exists(Path + "/32"))
2045*67e74705SXin Li MS = &AndroidMips64elMultilibs;
2046*67e74705SXin Li if (MS->select(Flags, Result.SelectedMultilib)) {
2047*67e74705SXin Li Result.Multilibs = *MS;
2048*67e74705SXin Li return true;
2049*67e74705SXin Li }
2050*67e74705SXin Li return false;
2051*67e74705SXin Li }
2052*67e74705SXin Li
findMipsMuslMultilibs(const Multilib::flags_list & Flags,FilterNonExistent & NonExistent,DetectedMultilibs & Result)2053*67e74705SXin Li static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
2054*67e74705SXin Li FilterNonExistent &NonExistent,
2055*67e74705SXin Li DetectedMultilibs &Result) {
2056*67e74705SXin Li // Musl toolchain multilibs
2057*67e74705SXin Li MultilibSet MuslMipsMultilibs;
2058*67e74705SXin Li {
2059*67e74705SXin Li auto MArchMipsR2 = makeMultilib("")
2060*67e74705SXin Li .osSuffix("/mips-r2-hard-musl")
2061*67e74705SXin Li .flag("+EB")
2062*67e74705SXin Li .flag("-EL")
2063*67e74705SXin Li .flag("+march=mips32r2");
2064*67e74705SXin Li
2065*67e74705SXin Li auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
2066*67e74705SXin Li .flag("-EB")
2067*67e74705SXin Li .flag("+EL")
2068*67e74705SXin Li .flag("+march=mips32r2");
2069*67e74705SXin Li
2070*67e74705SXin Li MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);
2071*67e74705SXin Li
2072*67e74705SXin Li // Specify the callback that computes the include directories.
2073*67e74705SXin Li MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
2074*67e74705SXin Li return std::vector<std::string>(
2075*67e74705SXin Li {"/../sysroot" + M.osSuffix() + "/usr/include"});
2076*67e74705SXin Li });
2077*67e74705SXin Li }
2078*67e74705SXin Li if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
2079*67e74705SXin Li Result.Multilibs = MuslMipsMultilibs;
2080*67e74705SXin Li return true;
2081*67e74705SXin Li }
2082*67e74705SXin Li return false;
2083*67e74705SXin Li }
2084*67e74705SXin Li
findMipsMtiMultilibs(const Multilib::flags_list & Flags,FilterNonExistent & NonExistent,DetectedMultilibs & Result)2085*67e74705SXin Li static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
2086*67e74705SXin Li FilterNonExistent &NonExistent,
2087*67e74705SXin Li DetectedMultilibs &Result) {
2088*67e74705SXin Li // CodeScape MTI toolchain v1.2 and early.
2089*67e74705SXin Li MultilibSet MtiMipsMultilibsV1;
2090*67e74705SXin Li {
2091*67e74705SXin Li auto MArchMips32 = makeMultilib("/mips32")
2092*67e74705SXin Li .flag("+m32")
2093*67e74705SXin Li .flag("-m64")
2094*67e74705SXin Li .flag("-mmicromips")
2095*67e74705SXin Li .flag("+march=mips32");
2096*67e74705SXin Li
2097*67e74705SXin Li auto MArchMicroMips = makeMultilib("/micromips")
2098*67e74705SXin Li .flag("+m32")
2099*67e74705SXin Li .flag("-m64")
2100*67e74705SXin Li .flag("+mmicromips");
2101*67e74705SXin Li
2102*67e74705SXin Li auto MArchMips64r2 = makeMultilib("/mips64r2")
2103*67e74705SXin Li .flag("-m32")
2104*67e74705SXin Li .flag("+m64")
2105*67e74705SXin Li .flag("+march=mips64r2");
2106*67e74705SXin Li
2107*67e74705SXin Li auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
2108*67e74705SXin Li "-march=mips64r2");
2109*67e74705SXin Li
2110*67e74705SXin Li auto MArchDefault = makeMultilib("")
2111*67e74705SXin Li .flag("+m32")
2112*67e74705SXin Li .flag("-m64")
2113*67e74705SXin Li .flag("-mmicromips")
2114*67e74705SXin Li .flag("+march=mips32r2");
2115*67e74705SXin Li
2116*67e74705SXin Li auto Mips16 = makeMultilib("/mips16").flag("+mips16");
2117*67e74705SXin Li
2118*67e74705SXin Li auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
2119*67e74705SXin Li
2120*67e74705SXin Li auto MAbi64 =
2121*67e74705SXin Li makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
2122*67e74705SXin Li
2123*67e74705SXin Li auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
2124*67e74705SXin Li
2125*67e74705SXin Li auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
2126*67e74705SXin Li
2127*67e74705SXin Li auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");
2128*67e74705SXin Li
2129*67e74705SXin Li auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
2130*67e74705SXin Li
2131*67e74705SXin Li MtiMipsMultilibsV1 =
2132*67e74705SXin Li MultilibSet()
2133*67e74705SXin Li .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
2134*67e74705SXin Li MArchDefault)
2135*67e74705SXin Li .Maybe(UCLibc)
2136*67e74705SXin Li .Maybe(Mips16)
2137*67e74705SXin Li .FilterOut("/mips64/mips16")
2138*67e74705SXin Li .FilterOut("/mips64r2/mips16")
2139*67e74705SXin Li .FilterOut("/micromips/mips16")
2140*67e74705SXin Li .Maybe(MAbi64)
2141*67e74705SXin Li .FilterOut("/micromips/64")
2142*67e74705SXin Li .FilterOut("/mips32/64")
2143*67e74705SXin Li .FilterOut("^/64")
2144*67e74705SXin Li .FilterOut("/mips16/64")
2145*67e74705SXin Li .Either(BigEndian, LittleEndian)
2146*67e74705SXin Li .Maybe(SoftFloat)
2147*67e74705SXin Li .Maybe(Nan2008)
2148*67e74705SXin Li .FilterOut(".*sof/nan2008")
2149*67e74705SXin Li .FilterOut(NonExistent)
2150*67e74705SXin Li .setIncludeDirsCallback([](const Multilib &M) {
2151*67e74705SXin Li std::vector<std::string> Dirs({"/include"});
2152*67e74705SXin Li if (StringRef(M.includeSuffix()).startswith("/uclibc"))
2153*67e74705SXin Li Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
2154*67e74705SXin Li else
2155*67e74705SXin Li Dirs.push_back("/../../../../sysroot/usr/include");
2156*67e74705SXin Li return Dirs;
2157*67e74705SXin Li });
2158*67e74705SXin Li }
2159*67e74705SXin Li
2160*67e74705SXin Li // CodeScape IMG toolchain starting from v1.3.
2161*67e74705SXin Li MultilibSet MtiMipsMultilibsV2;
2162*67e74705SXin Li {
2163*67e74705SXin Li auto BeHard = makeMultilib("/mips-r2-hard")
2164*67e74705SXin Li .flag("+EB")
2165*67e74705SXin Li .flag("-msoft-float")
2166*67e74705SXin Li .flag("-mnan=2008")
2167*67e74705SXin Li .flag("-muclibc");
2168*67e74705SXin Li auto BeSoft = makeMultilib("/mips-r2-soft")
2169*67e74705SXin Li .flag("+EB")
2170*67e74705SXin Li .flag("+msoft-float")
2171*67e74705SXin Li .flag("-mnan=2008");
2172*67e74705SXin Li auto ElHard = makeMultilib("/mipsel-r2-hard")
2173*67e74705SXin Li .flag("+EL")
2174*67e74705SXin Li .flag("-msoft-float")
2175*67e74705SXin Li .flag("-mnan=2008")
2176*67e74705SXin Li .flag("-muclibc");
2177*67e74705SXin Li auto ElSoft = makeMultilib("/mipsel-r2-soft")
2178*67e74705SXin Li .flag("+EL")
2179*67e74705SXin Li .flag("+msoft-float")
2180*67e74705SXin Li .flag("-mnan=2008")
2181*67e74705SXin Li .flag("-mmicromips");
2182*67e74705SXin Li auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
2183*67e74705SXin Li .flag("+EB")
2184*67e74705SXin Li .flag("-msoft-float")
2185*67e74705SXin Li .flag("+mnan=2008")
2186*67e74705SXin Li .flag("-muclibc");
2187*67e74705SXin Li auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
2188*67e74705SXin Li .flag("+EL")
2189*67e74705SXin Li .flag("-msoft-float")
2190*67e74705SXin Li .flag("+mnan=2008")
2191*67e74705SXin Li .flag("-muclibc")
2192*67e74705SXin Li .flag("-mmicromips");
2193*67e74705SXin Li auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
2194*67e74705SXin Li .flag("+EB")
2195*67e74705SXin Li .flag("-msoft-float")
2196*67e74705SXin Li .flag("+mnan=2008")
2197*67e74705SXin Li .flag("+muclibc");
2198*67e74705SXin Li auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
2199*67e74705SXin Li .flag("+EL")
2200*67e74705SXin Li .flag("-msoft-float")
2201*67e74705SXin Li .flag("+mnan=2008")
2202*67e74705SXin Li .flag("+muclibc");
2203*67e74705SXin Li auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
2204*67e74705SXin Li .flag("+EB")
2205*67e74705SXin Li .flag("-msoft-float")
2206*67e74705SXin Li .flag("-mnan=2008")
2207*67e74705SXin Li .flag("+muclibc");
2208*67e74705SXin Li auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
2209*67e74705SXin Li .flag("+EL")
2210*67e74705SXin Li .flag("-msoft-float")
2211*67e74705SXin Li .flag("-mnan=2008")
2212*67e74705SXin Li .flag("+muclibc");
2213*67e74705SXin Li auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
2214*67e74705SXin Li .flag("+EL")
2215*67e74705SXin Li .flag("-msoft-float")
2216*67e74705SXin Li .flag("+mnan=2008")
2217*67e74705SXin Li .flag("+mmicromips");
2218*67e74705SXin Li auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
2219*67e74705SXin Li .flag("+EL")
2220*67e74705SXin Li .flag("+msoft-float")
2221*67e74705SXin Li .flag("-mnan=2008")
2222*67e74705SXin Li .flag("+mmicromips");
2223*67e74705SXin Li
2224*67e74705SXin Li auto O32 =
2225*67e74705SXin Li makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2226*67e74705SXin Li auto N32 =
2227*67e74705SXin Li makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2228*67e74705SXin Li auto N64 =
2229*67e74705SXin Li makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2230*67e74705SXin Li
2231*67e74705SXin Li MtiMipsMultilibsV2 =
2232*67e74705SXin Li MultilibSet()
2233*67e74705SXin Li .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
2234*67e74705SXin Li BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
2235*67e74705SXin Li ElHardUclibc, ElMicroHardNan, ElMicroSoft})
2236*67e74705SXin Li .Either(O32, N32, N64)
2237*67e74705SXin Li .FilterOut(NonExistent)
2238*67e74705SXin Li .setIncludeDirsCallback([](const Multilib &M) {
2239*67e74705SXin Li return std::vector<std::string>({"/../../../../sysroot" +
2240*67e74705SXin Li M.includeSuffix() +
2241*67e74705SXin Li "/../usr/include"});
2242*67e74705SXin Li })
2243*67e74705SXin Li .setFilePathsCallback([](const Multilib &M) {
2244*67e74705SXin Li return std::vector<std::string>(
2245*67e74705SXin Li {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
2246*67e74705SXin Li });
2247*67e74705SXin Li }
2248*67e74705SXin Li for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
2249*67e74705SXin Li if (Candidate->select(Flags, Result.SelectedMultilib)) {
2250*67e74705SXin Li Result.Multilibs = *Candidate;
2251*67e74705SXin Li return true;
2252*67e74705SXin Li }
2253*67e74705SXin Li }
2254*67e74705SXin Li return false;
2255*67e74705SXin Li }
2256*67e74705SXin Li
findMipsImgMultilibs(const Multilib::flags_list & Flags,FilterNonExistent & NonExistent,DetectedMultilibs & Result)2257*67e74705SXin Li static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
2258*67e74705SXin Li FilterNonExistent &NonExistent,
2259*67e74705SXin Li DetectedMultilibs &Result) {
2260*67e74705SXin Li // CodeScape IMG toolchain v1.2 and early.
2261*67e74705SXin Li MultilibSet ImgMultilibsV1;
2262*67e74705SXin Li {
2263*67e74705SXin Li auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");
2264*67e74705SXin Li
2265*67e74705SXin Li auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
2266*67e74705SXin Li
2267*67e74705SXin Li auto MAbi64 =
2268*67e74705SXin Li makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
2269*67e74705SXin Li
2270*67e74705SXin Li ImgMultilibsV1 =
2271*67e74705SXin Li MultilibSet()
2272*67e74705SXin Li .Maybe(Mips64r6)
2273*67e74705SXin Li .Maybe(MAbi64)
2274*67e74705SXin Li .Maybe(LittleEndian)
2275*67e74705SXin Li .FilterOut(NonExistent)
2276*67e74705SXin Li .setIncludeDirsCallback([](const Multilib &M) {
2277*67e74705SXin Li return std::vector<std::string>(
2278*67e74705SXin Li {"/include", "/../../../../sysroot/usr/include"});
2279*67e74705SXin Li });
2280*67e74705SXin Li }
2281*67e74705SXin Li
2282*67e74705SXin Li // CodeScape IMG toolchain starting from v1.3.
2283*67e74705SXin Li MultilibSet ImgMultilibsV2;
2284*67e74705SXin Li {
2285*67e74705SXin Li auto BeHard = makeMultilib("/mips-r6-hard")
2286*67e74705SXin Li .flag("+EB")
2287*67e74705SXin Li .flag("-msoft-float")
2288*67e74705SXin Li .flag("-mmicromips");
2289*67e74705SXin Li auto BeSoft = makeMultilib("/mips-r6-soft")
2290*67e74705SXin Li .flag("+EB")
2291*67e74705SXin Li .flag("+msoft-float")
2292*67e74705SXin Li .flag("-mmicromips");
2293*67e74705SXin Li auto ElHard = makeMultilib("/mipsel-r6-hard")
2294*67e74705SXin Li .flag("+EL")
2295*67e74705SXin Li .flag("-msoft-float")
2296*67e74705SXin Li .flag("-mmicromips");
2297*67e74705SXin Li auto ElSoft = makeMultilib("/mipsel-r6-soft")
2298*67e74705SXin Li .flag("+EL")
2299*67e74705SXin Li .flag("+msoft-float")
2300*67e74705SXin Li .flag("-mmicromips");
2301*67e74705SXin Li auto BeMicroHard = makeMultilib("/micromips-r6-hard")
2302*67e74705SXin Li .flag("+EB")
2303*67e74705SXin Li .flag("-msoft-float")
2304*67e74705SXin Li .flag("+mmicromips");
2305*67e74705SXin Li auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
2306*67e74705SXin Li .flag("+EB")
2307*67e74705SXin Li .flag("+msoft-float")
2308*67e74705SXin Li .flag("+mmicromips");
2309*67e74705SXin Li auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
2310*67e74705SXin Li .flag("+EL")
2311*67e74705SXin Li .flag("-msoft-float")
2312*67e74705SXin Li .flag("+mmicromips");
2313*67e74705SXin Li auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
2314*67e74705SXin Li .flag("+EL")
2315*67e74705SXin Li .flag("+msoft-float")
2316*67e74705SXin Li .flag("+mmicromips");
2317*67e74705SXin Li
2318*67e74705SXin Li auto O32 =
2319*67e74705SXin Li makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2320*67e74705SXin Li auto N32 =
2321*67e74705SXin Li makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2322*67e74705SXin Li auto N64 =
2323*67e74705SXin Li makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2324*67e74705SXin Li
2325*67e74705SXin Li ImgMultilibsV2 =
2326*67e74705SXin Li MultilibSet()
2327*67e74705SXin Li .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
2328*67e74705SXin Li ElMicroHard, ElMicroSoft})
2329*67e74705SXin Li .Either(O32, N32, N64)
2330*67e74705SXin Li .FilterOut(NonExistent)
2331*67e74705SXin Li .setIncludeDirsCallback([](const Multilib &M) {
2332*67e74705SXin Li return std::vector<std::string>({"/../../../../sysroot" +
2333*67e74705SXin Li M.includeSuffix() +
2334*67e74705SXin Li "/../usr/include"});
2335*67e74705SXin Li })
2336*67e74705SXin Li .setFilePathsCallback([](const Multilib &M) {
2337*67e74705SXin Li return std::vector<std::string>(
2338*67e74705SXin Li {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
2339*67e74705SXin Li });
2340*67e74705SXin Li }
2341*67e74705SXin Li for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
2342*67e74705SXin Li if (Candidate->select(Flags, Result.SelectedMultilib)) {
2343*67e74705SXin Li Result.Multilibs = *Candidate;
2344*67e74705SXin Li return true;
2345*67e74705SXin Li }
2346*67e74705SXin Li }
2347*67e74705SXin Li return false;
2348*67e74705SXin Li }
2349*67e74705SXin Li
findMIPSMultilibs(const Driver & D,const llvm::Triple & TargetTriple,StringRef Path,const ArgList & Args,DetectedMultilibs & Result)2350*67e74705SXin Li static bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
2351*67e74705SXin Li StringRef Path, const ArgList &Args,
2352*67e74705SXin Li DetectedMultilibs &Result) {
2353*67e74705SXin Li FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
2354*67e74705SXin Li
2355*67e74705SXin Li StringRef CPUName;
2356*67e74705SXin Li StringRef ABIName;
2357*67e74705SXin Li tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
2358*67e74705SXin Li
2359*67e74705SXin Li llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
2360*67e74705SXin Li
2361*67e74705SXin Li Multilib::flags_list Flags;
2362*67e74705SXin Li addMultilibFlag(isMips32(TargetArch), "m32", Flags);
2363*67e74705SXin Li addMultilibFlag(isMips64(TargetArch), "m64", Flags);
2364*67e74705SXin Li addMultilibFlag(isMips16(Args), "mips16", Flags);
2365*67e74705SXin Li addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
2366*67e74705SXin Li addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
2367*67e74705SXin Li CPUName == "mips32r5" || CPUName == "p5600",
2368*67e74705SXin Li "march=mips32r2", Flags);
2369*67e74705SXin Li addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
2370*67e74705SXin Li addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
2371*67e74705SXin Li addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
2372*67e74705SXin Li CPUName == "mips64r5" || CPUName == "octeon",
2373*67e74705SXin Li "march=mips64r2", Flags);
2374*67e74705SXin Li addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
2375*67e74705SXin Li addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
2376*67e74705SXin Li addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
2377*67e74705SXin Li addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
2378*67e74705SXin Li Flags);
2379*67e74705SXin Li addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
2380*67e74705SXin Li addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
2381*67e74705SXin Li addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
2382*67e74705SXin Li addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
2383*67e74705SXin Li addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
2384*67e74705SXin Li addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
2385*67e74705SXin Li
2386*67e74705SXin Li if (TargetTriple.isAndroid())
2387*67e74705SXin Li return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
2388*67e74705SXin Li Result);
2389*67e74705SXin Li
2390*67e74705SXin Li if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2391*67e74705SXin Li TargetTriple.getOS() == llvm::Triple::Linux &&
2392*67e74705SXin Li TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
2393*67e74705SXin Li return findMipsMuslMultilibs(Flags, NonExistent, Result);
2394*67e74705SXin Li
2395*67e74705SXin Li if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2396*67e74705SXin Li TargetTriple.getOS() == llvm::Triple::Linux &&
2397*67e74705SXin Li TargetTriple.getEnvironment() == llvm::Triple::GNU)
2398*67e74705SXin Li return findMipsMtiMultilibs(Flags, NonExistent, Result);
2399*67e74705SXin Li
2400*67e74705SXin Li if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
2401*67e74705SXin Li TargetTriple.getOS() == llvm::Triple::Linux &&
2402*67e74705SXin Li TargetTriple.getEnvironment() == llvm::Triple::GNU)
2403*67e74705SXin Li return findMipsImgMultilibs(Flags, NonExistent, Result);
2404*67e74705SXin Li
2405*67e74705SXin Li if (findMipsCsMultilibs(Flags, NonExistent, Result))
2406*67e74705SXin Li return true;
2407*67e74705SXin Li
2408*67e74705SXin Li // Fallback to the regular toolchain-tree structure.
2409*67e74705SXin Li Multilib Default;
2410*67e74705SXin Li Result.Multilibs.push_back(Default);
2411*67e74705SXin Li Result.Multilibs.FilterOut(NonExistent);
2412*67e74705SXin Li
2413*67e74705SXin Li if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
2414*67e74705SXin Li Result.BiarchSibling = Multilib();
2415*67e74705SXin Li return true;
2416*67e74705SXin Li }
2417*67e74705SXin Li
2418*67e74705SXin Li return false;
2419*67e74705SXin Li }
2420*67e74705SXin Li
findAndroidArmMultilibs(const Driver & D,const llvm::Triple & TargetTriple,StringRef Path,const ArgList & Args,DetectedMultilibs & Result)2421*67e74705SXin Li static void findAndroidArmMultilibs(const Driver &D,
2422*67e74705SXin Li const llvm::Triple &TargetTriple,
2423*67e74705SXin Li StringRef Path, const ArgList &Args,
2424*67e74705SXin Li DetectedMultilibs &Result) {
2425*67e74705SXin Li // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
2426*67e74705SXin Li FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
2427*67e74705SXin Li Multilib ArmV7Multilib = makeMultilib("/armv7-a")
2428*67e74705SXin Li .flag("+armv7")
2429*67e74705SXin Li .flag("-thumb");
2430*67e74705SXin Li Multilib ThumbMultilib = makeMultilib("/thumb")
2431*67e74705SXin Li .flag("-armv7")
2432*67e74705SXin Li .flag("+thumb");
2433*67e74705SXin Li Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
2434*67e74705SXin Li .flag("+armv7")
2435*67e74705SXin Li .flag("+thumb");
2436*67e74705SXin Li Multilib DefaultMultilib = makeMultilib("")
2437*67e74705SXin Li .flag("-armv7")
2438*67e74705SXin Li .flag("-thumb");
2439*67e74705SXin Li MultilibSet AndroidArmMultilibs =
2440*67e74705SXin Li MultilibSet()
2441*67e74705SXin Li .Either(ThumbMultilib, ArmV7Multilib,
2442*67e74705SXin Li ArmV7ThumbMultilib, DefaultMultilib)
2443*67e74705SXin Li .FilterOut(NonExistent);
2444*67e74705SXin Li
2445*67e74705SXin Li Multilib::flags_list Flags;
2446*67e74705SXin Li llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
2447*67e74705SXin Li bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
2448*67e74705SXin Li bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
2449*67e74705SXin Li bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
2450*67e74705SXin Li bool IsThumbMode = IsThumbArch ||
2451*67e74705SXin Li Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
2452*67e74705SXin Li (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB);
2453*67e74705SXin Li bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
2454*67e74705SXin Li (llvm::ARM::parseArchVersion(Arch) == 7 ||
2455*67e74705SXin Li (IsArmArch && Arch == "" && IsV7SubArch));
2456*67e74705SXin Li addMultilibFlag(IsArmV7Mode, "armv7", Flags);
2457*67e74705SXin Li addMultilibFlag(IsThumbMode, "thumb", Flags);
2458*67e74705SXin Li
2459*67e74705SXin Li if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
2460*67e74705SXin Li Result.Multilibs = AndroidArmMultilibs;
2461*67e74705SXin Li }
2462*67e74705SXin Li
findBiarchMultilibs(const Driver & D,const llvm::Triple & TargetTriple,StringRef Path,const ArgList & Args,bool NeedsBiarchSuffix,DetectedMultilibs & Result)2463*67e74705SXin Li static bool findBiarchMultilibs(const Driver &D,
2464*67e74705SXin Li const llvm::Triple &TargetTriple,
2465*67e74705SXin Li StringRef Path, const ArgList &Args,
2466*67e74705SXin Li bool NeedsBiarchSuffix,
2467*67e74705SXin Li DetectedMultilibs &Result) {
2468*67e74705SXin Li // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
2469*67e74705SXin Li // in what would normally be GCCInstallPath and put the 64-bit
2470*67e74705SXin Li // libs in a subdirectory named 64. The simple logic we follow is that
2471*67e74705SXin Li // *if* there is a subdirectory of the right name with crtbegin.o in it,
2472*67e74705SXin Li // we use that. If not, and if not a biarch triple alias, we look for
2473*67e74705SXin Li // crtbegin.o without the subdirectory.
2474*67e74705SXin Li
2475*67e74705SXin Li Multilib Default;
2476*67e74705SXin Li Multilib Alt64 = Multilib()
2477*67e74705SXin Li .gccSuffix("/64")
2478*67e74705SXin Li .includeSuffix("/64")
2479*67e74705SXin Li .flag("-m32")
2480*67e74705SXin Li .flag("+m64")
2481*67e74705SXin Li .flag("-mx32");
2482*67e74705SXin Li Multilib Alt32 = Multilib()
2483*67e74705SXin Li .gccSuffix("/32")
2484*67e74705SXin Li .includeSuffix("/32")
2485*67e74705SXin Li .flag("+m32")
2486*67e74705SXin Li .flag("-m64")
2487*67e74705SXin Li .flag("-mx32");
2488*67e74705SXin Li Multilib Altx32 = Multilib()
2489*67e74705SXin Li .gccSuffix("/x32")
2490*67e74705SXin Li .includeSuffix("/x32")
2491*67e74705SXin Li .flag("-m32")
2492*67e74705SXin Li .flag("-m64")
2493*67e74705SXin Li .flag("+mx32");
2494*67e74705SXin Li
2495*67e74705SXin Li // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
2496*67e74705SXin Li FilterNonExistent NonExistent(
2497*67e74705SXin Li Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
2498*67e74705SXin Li
2499*67e74705SXin Li // Determine default multilib from: 32, 64, x32
2500*67e74705SXin Li // Also handle cases such as 64 on 32, 32 on 64, etc.
2501*67e74705SXin Li enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
2502*67e74705SXin Li const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32;
2503*67e74705SXin Li if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
2504*67e74705SXin Li Want = WANT64;
2505*67e74705SXin Li else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
2506*67e74705SXin Li Want = WANT64;
2507*67e74705SXin Li else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
2508*67e74705SXin Li Want = WANT32;
2509*67e74705SXin Li else {
2510*67e74705SXin Li if (TargetTriple.isArch32Bit())
2511*67e74705SXin Li Want = NeedsBiarchSuffix ? WANT64 : WANT32;
2512*67e74705SXin Li else if (IsX32)
2513*67e74705SXin Li Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
2514*67e74705SXin Li else
2515*67e74705SXin Li Want = NeedsBiarchSuffix ? WANT32 : WANT64;
2516*67e74705SXin Li }
2517*67e74705SXin Li
2518*67e74705SXin Li if (Want == WANT32)
2519*67e74705SXin Li Default.flag("+m32").flag("-m64").flag("-mx32");
2520*67e74705SXin Li else if (Want == WANT64)
2521*67e74705SXin Li Default.flag("-m32").flag("+m64").flag("-mx32");
2522*67e74705SXin Li else if (Want == WANTX32)
2523*67e74705SXin Li Default.flag("-m32").flag("-m64").flag("+mx32");
2524*67e74705SXin Li else
2525*67e74705SXin Li return false;
2526*67e74705SXin Li
2527*67e74705SXin Li Result.Multilibs.push_back(Default);
2528*67e74705SXin Li Result.Multilibs.push_back(Alt64);
2529*67e74705SXin Li Result.Multilibs.push_back(Alt32);
2530*67e74705SXin Li Result.Multilibs.push_back(Altx32);
2531*67e74705SXin Li
2532*67e74705SXin Li Result.Multilibs.FilterOut(NonExistent);
2533*67e74705SXin Li
2534*67e74705SXin Li Multilib::flags_list Flags;
2535*67e74705SXin Li addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
2536*67e74705SXin Li addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
2537*67e74705SXin Li addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
2538*67e74705SXin Li
2539*67e74705SXin Li if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
2540*67e74705SXin Li return false;
2541*67e74705SXin Li
2542*67e74705SXin Li if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 ||
2543*67e74705SXin Li Result.SelectedMultilib == Altx32)
2544*67e74705SXin Li Result.BiarchSibling = Default;
2545*67e74705SXin Li
2546*67e74705SXin Li return true;
2547*67e74705SXin Li }
2548*67e74705SXin Li
scanLibDirForGCCTripleSolaris(const llvm::Triple & TargetArch,const llvm::opt::ArgList & Args,const std::string & LibDir,StringRef CandidateTriple,bool NeedsBiarchSuffix)2549*67e74705SXin Li void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
2550*67e74705SXin Li const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
2551*67e74705SXin Li const std::string &LibDir, StringRef CandidateTriple,
2552*67e74705SXin Li bool NeedsBiarchSuffix) {
2553*67e74705SXin Li // Solaris is a special case. The GCC installation is under
2554*67e74705SXin Li // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
2555*67e74705SXin Li // need to iterate twice.
2556*67e74705SXin Li std::error_code EC;
2557*67e74705SXin Li for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
2558*67e74705SXin Li !EC && LI != LE; LI = LI.increment(EC)) {
2559*67e74705SXin Li StringRef VersionText = llvm::sys::path::filename(LI->getName());
2560*67e74705SXin Li GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2561*67e74705SXin Li
2562*67e74705SXin Li if (CandidateVersion.Major != -1) // Filter obviously bad entries.
2563*67e74705SXin Li if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
2564*67e74705SXin Li continue; // Saw this path before; no need to look at it again.
2565*67e74705SXin Li if (CandidateVersion.isOlderThan(4, 1, 1))
2566*67e74705SXin Li continue;
2567*67e74705SXin Li if (CandidateVersion <= Version)
2568*67e74705SXin Li continue;
2569*67e74705SXin Li
2570*67e74705SXin Li GCCInstallPath =
2571*67e74705SXin Li LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
2572*67e74705SXin Li if (!D.getVFS().exists(GCCInstallPath))
2573*67e74705SXin Li continue;
2574*67e74705SXin Li
2575*67e74705SXin Li // If we make it here there has to be at least one GCC version, let's just
2576*67e74705SXin Li // use the latest one.
2577*67e74705SXin Li std::error_code EEC;
2578*67e74705SXin Li for (vfs::directory_iterator
2579*67e74705SXin Li LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
2580*67e74705SXin Li LLE;
2581*67e74705SXin Li !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
2582*67e74705SXin Li
2583*67e74705SXin Li StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
2584*67e74705SXin Li GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
2585*67e74705SXin Li
2586*67e74705SXin Li if (CandidateSubVersion > Version)
2587*67e74705SXin Li Version = CandidateSubVersion;
2588*67e74705SXin Li }
2589*67e74705SXin Li
2590*67e74705SXin Li GCCTriple.setTriple(CandidateTriple);
2591*67e74705SXin Li
2592*67e74705SXin Li GCCInstallPath += "/" + Version.Text;
2593*67e74705SXin Li GCCParentLibPath = GCCInstallPath + "/../../../../";
2594*67e74705SXin Li
2595*67e74705SXin Li IsValid = true;
2596*67e74705SXin Li }
2597*67e74705SXin Li }
2598*67e74705SXin Li
ScanLibDirForGCCTriple(const llvm::Triple & TargetTriple,const ArgList & Args,const std::string & LibDir,StringRef CandidateTriple,bool NeedsBiarchSuffix)2599*67e74705SXin Li void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
2600*67e74705SXin Li const llvm::Triple &TargetTriple, const ArgList &Args,
2601*67e74705SXin Li const std::string &LibDir, StringRef CandidateTriple,
2602*67e74705SXin Li bool NeedsBiarchSuffix) {
2603*67e74705SXin Li llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
2604*67e74705SXin Li // There are various different suffixes involving the triple we
2605*67e74705SXin Li // check for. We also record what is necessary to walk from each back
2606*67e74705SXin Li // up to the lib directory. Specifically, the number of "up" steps
2607*67e74705SXin Li // in the second half of each row is 1 + the number of path separators
2608*67e74705SXin Li // in the first half.
2609*67e74705SXin Li const std::string LibAndInstallSuffixes[][2] = {
2610*67e74705SXin Li {"/gcc/" + CandidateTriple.str(), "/../../.."},
2611*67e74705SXin Li
2612*67e74705SXin Li // Debian puts cross-compilers in gcc-cross
2613*67e74705SXin Li {"/gcc-cross/" + CandidateTriple.str(), "/../../.."},
2614*67e74705SXin Li
2615*67e74705SXin Li {"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
2616*67e74705SXin Li "/../../../.."},
2617*67e74705SXin Li
2618*67e74705SXin Li // The Freescale PPC SDK has the gcc libraries in
2619*67e74705SXin Li // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
2620*67e74705SXin Li {"/" + CandidateTriple.str(), "/../.."},
2621*67e74705SXin Li
2622*67e74705SXin Li // Ubuntu has a strange mis-matched pair of triples that this happens to
2623*67e74705SXin Li // match.
2624*67e74705SXin Li // FIXME: It may be worthwhile to generalize this and look for a second
2625*67e74705SXin Li // triple.
2626*67e74705SXin Li {"/i386-linux-gnu/gcc/" + CandidateTriple.str(), "/../../../.."}};
2627*67e74705SXin Li
2628*67e74705SXin Li if (TargetTriple.getOS() == llvm::Triple::Solaris) {
2629*67e74705SXin Li scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
2630*67e74705SXin Li NeedsBiarchSuffix);
2631*67e74705SXin Li return;
2632*67e74705SXin Li }
2633*67e74705SXin Li
2634*67e74705SXin Li // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
2635*67e74705SXin Li const unsigned NumLibSuffixes = (llvm::array_lengthof(LibAndInstallSuffixes) -
2636*67e74705SXin Li (TargetArch != llvm::Triple::x86));
2637*67e74705SXin Li for (unsigned i = 0; i < NumLibSuffixes; ++i) {
2638*67e74705SXin Li StringRef LibSuffix = LibAndInstallSuffixes[i][0];
2639*67e74705SXin Li std::error_code EC;
2640*67e74705SXin Li for (vfs::directory_iterator
2641*67e74705SXin Li LI = D.getVFS().dir_begin(LibDir + LibSuffix, EC),
2642*67e74705SXin Li LE;
2643*67e74705SXin Li !EC && LI != LE; LI = LI.increment(EC)) {
2644*67e74705SXin Li StringRef VersionText = llvm::sys::path::filename(LI->getName());
2645*67e74705SXin Li GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2646*67e74705SXin Li if (CandidateVersion.Major != -1) // Filter obviously bad entries.
2647*67e74705SXin Li if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
2648*67e74705SXin Li continue; // Saw this path before; no need to look at it again.
2649*67e74705SXin Li if (CandidateVersion.isOlderThan(4, 1, 1))
2650*67e74705SXin Li continue;
2651*67e74705SXin Li if (CandidateVersion <= Version)
2652*67e74705SXin Li continue;
2653*67e74705SXin Li
2654*67e74705SXin Li DetectedMultilibs Detected;
2655*67e74705SXin Li
2656*67e74705SXin Li // Android standalone toolchain could have multilibs for ARM and Thumb.
2657*67e74705SXin Li // Debian mips multilibs behave more like the rest of the biarch ones,
2658*67e74705SXin Li // so handle them there
2659*67e74705SXin Li if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
2660*67e74705SXin Li // It should also work without multilibs in a simplified toolchain.
2661*67e74705SXin Li findAndroidArmMultilibs(D, TargetTriple, LI->getName(), Args, Detected);
2662*67e74705SXin Li } else if (isMipsArch(TargetArch)) {
2663*67e74705SXin Li if (!findMIPSMultilibs(D, TargetTriple, LI->getName(), Args, Detected))
2664*67e74705SXin Li continue;
2665*67e74705SXin Li } else if (!findBiarchMultilibs(D, TargetTriple, LI->getName(), Args,
2666*67e74705SXin Li NeedsBiarchSuffix, Detected)) {
2667*67e74705SXin Li continue;
2668*67e74705SXin Li }
2669*67e74705SXin Li
2670*67e74705SXin Li Multilibs = Detected.Multilibs;
2671*67e74705SXin Li SelectedMultilib = Detected.SelectedMultilib;
2672*67e74705SXin Li BiarchSibling = Detected.BiarchSibling;
2673*67e74705SXin Li Version = CandidateVersion;
2674*67e74705SXin Li GCCTriple.setTriple(CandidateTriple);
2675*67e74705SXin Li // FIXME: We hack together the directory name here instead of
2676*67e74705SXin Li // using LI to ensure stable path separators across Windows and
2677*67e74705SXin Li // Linux.
2678*67e74705SXin Li GCCInstallPath =
2679*67e74705SXin Li LibDir + LibAndInstallSuffixes[i][0] + "/" + VersionText.str();
2680*67e74705SXin Li GCCParentLibPath = GCCInstallPath + LibAndInstallSuffixes[i][1];
2681*67e74705SXin Li IsValid = true;
2682*67e74705SXin Li }
2683*67e74705SXin Li }
2684*67e74705SXin Li }
2685*67e74705SXin Li
Generic_GCC(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2686*67e74705SXin Li Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
2687*67e74705SXin Li const ArgList &Args)
2688*67e74705SXin Li : ToolChain(D, Triple, Args), GCCInstallation(D), CudaInstallation(D) {
2689*67e74705SXin Li getProgramPaths().push_back(getDriver().getInstalledDir());
2690*67e74705SXin Li if (getDriver().getInstalledDir() != getDriver().Dir)
2691*67e74705SXin Li getProgramPaths().push_back(getDriver().Dir);
2692*67e74705SXin Li }
2693*67e74705SXin Li
~Generic_GCC()2694*67e74705SXin Li Generic_GCC::~Generic_GCC() {}
2695*67e74705SXin Li
getTool(Action::ActionClass AC) const2696*67e74705SXin Li Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
2697*67e74705SXin Li switch (AC) {
2698*67e74705SXin Li case Action::PreprocessJobClass:
2699*67e74705SXin Li if (!Preprocess)
2700*67e74705SXin Li Preprocess.reset(new tools::gcc::Preprocessor(*this));
2701*67e74705SXin Li return Preprocess.get();
2702*67e74705SXin Li case Action::CompileJobClass:
2703*67e74705SXin Li if (!Compile)
2704*67e74705SXin Li Compile.reset(new tools::gcc::Compiler(*this));
2705*67e74705SXin Li return Compile.get();
2706*67e74705SXin Li default:
2707*67e74705SXin Li return ToolChain::getTool(AC);
2708*67e74705SXin Li }
2709*67e74705SXin Li }
2710*67e74705SXin Li
buildAssembler() const2711*67e74705SXin Li Tool *Generic_GCC::buildAssembler() const {
2712*67e74705SXin Li return new tools::gnutools::Assembler(*this);
2713*67e74705SXin Li }
2714*67e74705SXin Li
buildLinker() const2715*67e74705SXin Li Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
2716*67e74705SXin Li
printVerboseInfo(raw_ostream & OS) const2717*67e74705SXin Li void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
2718*67e74705SXin Li // Print the information about how we detected the GCC installation.
2719*67e74705SXin Li GCCInstallation.print(OS);
2720*67e74705SXin Li CudaInstallation.print(OS);
2721*67e74705SXin Li }
2722*67e74705SXin Li
IsUnwindTablesDefault() const2723*67e74705SXin Li bool Generic_GCC::IsUnwindTablesDefault() const {
2724*67e74705SXin Li return getArch() == llvm::Triple::x86_64;
2725*67e74705SXin Li }
2726*67e74705SXin Li
isPICDefault() const2727*67e74705SXin Li bool Generic_GCC::isPICDefault() const {
2728*67e74705SXin Li return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2729*67e74705SXin Li }
2730*67e74705SXin Li
isPIEDefault() const2731*67e74705SXin Li bool Generic_GCC::isPIEDefault() const { return false; }
2732*67e74705SXin Li
isPICDefaultForced() const2733*67e74705SXin Li bool Generic_GCC::isPICDefaultForced() const {
2734*67e74705SXin Li return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2735*67e74705SXin Li }
2736*67e74705SXin Li
IsIntegratedAssemblerDefault() const2737*67e74705SXin Li bool Generic_GCC::IsIntegratedAssemblerDefault() const {
2738*67e74705SXin Li switch (getTriple().getArch()) {
2739*67e74705SXin Li case llvm::Triple::x86:
2740*67e74705SXin Li case llvm::Triple::x86_64:
2741*67e74705SXin Li case llvm::Triple::aarch64:
2742*67e74705SXin Li case llvm::Triple::aarch64_be:
2743*67e74705SXin Li case llvm::Triple::arm:
2744*67e74705SXin Li case llvm::Triple::armeb:
2745*67e74705SXin Li case llvm::Triple::bpfel:
2746*67e74705SXin Li case llvm::Triple::bpfeb:
2747*67e74705SXin Li case llvm::Triple::thumb:
2748*67e74705SXin Li case llvm::Triple::thumbeb:
2749*67e74705SXin Li case llvm::Triple::ppc:
2750*67e74705SXin Li case llvm::Triple::ppc64:
2751*67e74705SXin Li case llvm::Triple::ppc64le:
2752*67e74705SXin Li case llvm::Triple::systemz:
2753*67e74705SXin Li case llvm::Triple::mips:
2754*67e74705SXin Li case llvm::Triple::mipsel:
2755*67e74705SXin Li return true;
2756*67e74705SXin Li default:
2757*67e74705SXin Li return false;
2758*67e74705SXin Li }
2759*67e74705SXin Li }
2760*67e74705SXin Li
2761*67e74705SXin Li /// \brief Helper to add the variant paths of a libstdc++ installation.
addLibStdCXXIncludePaths(Twine Base,Twine Suffix,StringRef GCCTriple,StringRef GCCMultiarchTriple,StringRef TargetMultiarchTriple,Twine IncludeSuffix,const ArgList & DriverArgs,ArgStringList & CC1Args) const2762*67e74705SXin Li bool Generic_GCC::addLibStdCXXIncludePaths(
2763*67e74705SXin Li Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
2764*67e74705SXin Li StringRef TargetMultiarchTriple, Twine IncludeSuffix,
2765*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2766*67e74705SXin Li if (!getVFS().exists(Base + Suffix))
2767*67e74705SXin Li return false;
2768*67e74705SXin Li
2769*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
2770*67e74705SXin Li
2771*67e74705SXin Li // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
2772*67e74705SXin Li // that path exists or we have neither a GCC nor target multiarch triple, use
2773*67e74705SXin Li // this vanilla search path.
2774*67e74705SXin Li if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
2775*67e74705SXin Li getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
2776*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
2777*67e74705SXin Li Base + Suffix + "/" + GCCTriple + IncludeSuffix);
2778*67e74705SXin Li } else {
2779*67e74705SXin Li // Otherwise try to use multiarch naming schemes which have normalized the
2780*67e74705SXin Li // triples and put the triple before the suffix.
2781*67e74705SXin Li //
2782*67e74705SXin Li // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
2783*67e74705SXin Li // the target triple, so we support that here.
2784*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
2785*67e74705SXin Li Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
2786*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
2787*67e74705SXin Li Base + "/" + TargetMultiarchTriple + Suffix);
2788*67e74705SXin Li }
2789*67e74705SXin Li
2790*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
2791*67e74705SXin Li return true;
2792*67e74705SXin Li }
2793*67e74705SXin Li
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args) const2794*67e74705SXin Li void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
2795*67e74705SXin Li ArgStringList &CC1Args) const {
2796*67e74705SXin Li const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
2797*67e74705SXin Li bool UseInitArrayDefault =
2798*67e74705SXin Li getTriple().getArch() == llvm::Triple::aarch64 ||
2799*67e74705SXin Li getTriple().getArch() == llvm::Triple::aarch64_be ||
2800*67e74705SXin Li (getTriple().getOS() == llvm::Triple::Linux &&
2801*67e74705SXin Li (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
2802*67e74705SXin Li getTriple().getOS() == llvm::Triple::NaCl ||
2803*67e74705SXin Li (getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
2804*67e74705SXin Li !getTriple().hasEnvironment());
2805*67e74705SXin Li
2806*67e74705SXin Li if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
2807*67e74705SXin Li options::OPT_fno_use_init_array, UseInitArrayDefault))
2808*67e74705SXin Li CC1Args.push_back("-fuse-init-array");
2809*67e74705SXin Li }
2810*67e74705SXin Li
2811*67e74705SXin Li /// Mips Toolchain
MipsLLVMToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2812*67e74705SXin Li MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
2813*67e74705SXin Li const llvm::Triple &Triple,
2814*67e74705SXin Li const ArgList &Args)
2815*67e74705SXin Li : Linux(D, Triple, Args) {
2816*67e74705SXin Li // Select the correct multilib according to the given arguments.
2817*67e74705SXin Li DetectedMultilibs Result;
2818*67e74705SXin Li findMIPSMultilibs(D, Triple, "", Args, Result);
2819*67e74705SXin Li Multilibs = Result.Multilibs;
2820*67e74705SXin Li SelectedMultilib = Result.SelectedMultilib;
2821*67e74705SXin Li
2822*67e74705SXin Li // Find out the library suffix based on the ABI.
2823*67e74705SXin Li LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
2824*67e74705SXin Li getFilePaths().clear();
2825*67e74705SXin Li getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
2826*67e74705SXin Li
2827*67e74705SXin Li // Use LLD by default.
2828*67e74705SXin Li DefaultLinker = "lld";
2829*67e74705SXin Li }
2830*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2831*67e74705SXin Li void MipsLLVMToolChain::AddClangSystemIncludeArgs(
2832*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2833*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc))
2834*67e74705SXin Li return;
2835*67e74705SXin Li
2836*67e74705SXin Li const Driver &D = getDriver();
2837*67e74705SXin Li
2838*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2839*67e74705SXin Li SmallString<128> P(D.ResourceDir);
2840*67e74705SXin Li llvm::sys::path::append(P, "include");
2841*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P);
2842*67e74705SXin Li }
2843*67e74705SXin Li
2844*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2845*67e74705SXin Li return;
2846*67e74705SXin Li
2847*67e74705SXin Li const auto &Callback = Multilibs.includeDirsCallback();
2848*67e74705SXin Li if (Callback) {
2849*67e74705SXin Li for (const auto &Path : Callback(SelectedMultilib))
2850*67e74705SXin Li addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
2851*67e74705SXin Li D.getInstalledDir() + Path);
2852*67e74705SXin Li }
2853*67e74705SXin Li }
2854*67e74705SXin Li
buildLinker() const2855*67e74705SXin Li Tool *MipsLLVMToolChain::buildLinker() const {
2856*67e74705SXin Li return new tools::gnutools::Linker(*this);
2857*67e74705SXin Li }
2858*67e74705SXin Li
computeSysRoot() const2859*67e74705SXin Li std::string MipsLLVMToolChain::computeSysRoot() const {
2860*67e74705SXin Li if (!getDriver().SysRoot.empty())
2861*67e74705SXin Li return getDriver().SysRoot + SelectedMultilib.osSuffix();
2862*67e74705SXin Li
2863*67e74705SXin Li const std::string InstalledDir(getDriver().getInstalledDir());
2864*67e74705SXin Li std::string SysRootPath =
2865*67e74705SXin Li InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix();
2866*67e74705SXin Li if (llvm::sys::fs::exists(SysRootPath))
2867*67e74705SXin Li return SysRootPath;
2868*67e74705SXin Li
2869*67e74705SXin Li return std::string();
2870*67e74705SXin Li }
2871*67e74705SXin Li
2872*67e74705SXin Li ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const2873*67e74705SXin Li MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
2874*67e74705SXin Li Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
2875*67e74705SXin Li if (A) {
2876*67e74705SXin Li StringRef Value = A->getValue();
2877*67e74705SXin Li if (Value != "libc++")
2878*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2879*67e74705SXin Li << A->getAsString(Args);
2880*67e74705SXin Li }
2881*67e74705SXin Li
2882*67e74705SXin Li return ToolChain::CST_Libcxx;
2883*67e74705SXin Li }
2884*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2885*67e74705SXin Li void MipsLLVMToolChain::AddClangCXXStdlibIncludeArgs(
2886*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2887*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2888*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
2889*67e74705SXin Li return;
2890*67e74705SXin Li
2891*67e74705SXin Li assert((GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) &&
2892*67e74705SXin Li "Only -lc++ (aka libcxx) is suported in this toolchain.");
2893*67e74705SXin Li
2894*67e74705SXin Li const auto &Callback = Multilibs.includeDirsCallback();
2895*67e74705SXin Li if (Callback) {
2896*67e74705SXin Li for (std::string Path : Callback(SelectedMultilib)) {
2897*67e74705SXin Li Path = getDriver().getInstalledDir() + Path + "/c++/v1";
2898*67e74705SXin Li if (llvm::sys::fs::exists(Path)) {
2899*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, Path);
2900*67e74705SXin Li break;
2901*67e74705SXin Li }
2902*67e74705SXin Li }
2903*67e74705SXin Li }
2904*67e74705SXin Li }
2905*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const2906*67e74705SXin Li void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
2907*67e74705SXin Li ArgStringList &CmdArgs) const {
2908*67e74705SXin Li assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
2909*67e74705SXin Li "Only -lc++ (aka libxx) is suported in this toolchain.");
2910*67e74705SXin Li
2911*67e74705SXin Li CmdArgs.push_back("-lc++");
2912*67e74705SXin Li CmdArgs.push_back("-lc++abi");
2913*67e74705SXin Li CmdArgs.push_back("-lunwind");
2914*67e74705SXin Li }
2915*67e74705SXin Li
getCompilerRT(const ArgList & Args,StringRef Component,bool Shared) const2916*67e74705SXin Li std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
2917*67e74705SXin Li StringRef Component,
2918*67e74705SXin Li bool Shared) const {
2919*67e74705SXin Li SmallString<128> Path(getDriver().ResourceDir);
2920*67e74705SXin Li llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
2921*67e74705SXin Li getOS());
2922*67e74705SXin Li llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
2923*67e74705SXin Li "mips" + (Shared ? ".so" : ".a")));
2924*67e74705SXin Li return Path.str();
2925*67e74705SXin Li }
2926*67e74705SXin Li
2927*67e74705SXin Li /// Hexagon Toolchain
2928*67e74705SXin Li
getHexagonTargetDir(const std::string & InstalledDir,const SmallVectorImpl<std::string> & PrefixDirs) const2929*67e74705SXin Li std::string HexagonToolChain::getHexagonTargetDir(
2930*67e74705SXin Li const std::string &InstalledDir,
2931*67e74705SXin Li const SmallVectorImpl<std::string> &PrefixDirs) const {
2932*67e74705SXin Li std::string InstallRelDir;
2933*67e74705SXin Li const Driver &D = getDriver();
2934*67e74705SXin Li
2935*67e74705SXin Li // Locate the rest of the toolchain ...
2936*67e74705SXin Li for (auto &I : PrefixDirs)
2937*67e74705SXin Li if (D.getVFS().exists(I))
2938*67e74705SXin Li return I;
2939*67e74705SXin Li
2940*67e74705SXin Li if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
2941*67e74705SXin Li return InstallRelDir;
2942*67e74705SXin Li
2943*67e74705SXin Li return InstallRelDir;
2944*67e74705SXin Li }
2945*67e74705SXin Li
getSmallDataThreshold(const ArgList & Args)2946*67e74705SXin Li Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
2947*67e74705SXin Li const ArgList &Args) {
2948*67e74705SXin Li StringRef Gn = "";
2949*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
2950*67e74705SXin Li options::OPT_msmall_data_threshold_EQ)) {
2951*67e74705SXin Li Gn = A->getValue();
2952*67e74705SXin Li } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2953*67e74705SXin Li options::OPT_fPIC)) {
2954*67e74705SXin Li Gn = "0";
2955*67e74705SXin Li }
2956*67e74705SXin Li
2957*67e74705SXin Li unsigned G;
2958*67e74705SXin Li if (!Gn.getAsInteger(10, G))
2959*67e74705SXin Li return G;
2960*67e74705SXin Li
2961*67e74705SXin Li return None;
2962*67e74705SXin Li }
2963*67e74705SXin Li
getHexagonLibraryPaths(const ArgList & Args,ToolChain::path_list & LibPaths) const2964*67e74705SXin Li void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
2965*67e74705SXin Li ToolChain::path_list &LibPaths) const {
2966*67e74705SXin Li const Driver &D = getDriver();
2967*67e74705SXin Li
2968*67e74705SXin Li //----------------------------------------------------------------------------
2969*67e74705SXin Li // -L Args
2970*67e74705SXin Li //----------------------------------------------------------------------------
2971*67e74705SXin Li for (Arg *A : Args.filtered(options::OPT_L))
2972*67e74705SXin Li for (const char *Value : A->getValues())
2973*67e74705SXin Li LibPaths.push_back(Value);
2974*67e74705SXin Li
2975*67e74705SXin Li //----------------------------------------------------------------------------
2976*67e74705SXin Li // Other standard paths
2977*67e74705SXin Li //----------------------------------------------------------------------------
2978*67e74705SXin Li std::vector<std::string> RootDirs;
2979*67e74705SXin Li std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
2980*67e74705SXin Li std::back_inserter(RootDirs));
2981*67e74705SXin Li
2982*67e74705SXin Li std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
2983*67e74705SXin Li D.PrefixDirs);
2984*67e74705SXin Li if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
2985*67e74705SXin Li RootDirs.push_back(TargetDir);
2986*67e74705SXin Li
2987*67e74705SXin Li bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
2988*67e74705SXin Li // Assume G0 with -shared.
2989*67e74705SXin Li bool HasG0 = Args.hasArg(options::OPT_shared);
2990*67e74705SXin Li if (auto G = getSmallDataThreshold(Args))
2991*67e74705SXin Li HasG0 = G.getValue() == 0;
2992*67e74705SXin Li
2993*67e74705SXin Li const std::string CpuVer = GetTargetCPUVersion(Args).str();
2994*67e74705SXin Li for (auto &Dir : RootDirs) {
2995*67e74705SXin Li std::string LibDir = Dir + "/hexagon/lib";
2996*67e74705SXin Li std::string LibDirCpu = LibDir + '/' + CpuVer;
2997*67e74705SXin Li if (HasG0) {
2998*67e74705SXin Li if (HasPIC)
2999*67e74705SXin Li LibPaths.push_back(LibDirCpu + "/G0/pic");
3000*67e74705SXin Li LibPaths.push_back(LibDirCpu + "/G0");
3001*67e74705SXin Li }
3002*67e74705SXin Li LibPaths.push_back(LibDirCpu);
3003*67e74705SXin Li LibPaths.push_back(LibDir);
3004*67e74705SXin Li }
3005*67e74705SXin Li }
3006*67e74705SXin Li
HexagonToolChain(const Driver & D,const llvm::Triple & Triple,const llvm::opt::ArgList & Args)3007*67e74705SXin Li HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
3008*67e74705SXin Li const llvm::opt::ArgList &Args)
3009*67e74705SXin Li : Linux(D, Triple, Args) {
3010*67e74705SXin Li const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3011*67e74705SXin Li D.PrefixDirs);
3012*67e74705SXin Li
3013*67e74705SXin Li // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
3014*67e74705SXin Li // program paths
3015*67e74705SXin Li const std::string BinDir(TargetDir + "/bin");
3016*67e74705SXin Li if (D.getVFS().exists(BinDir))
3017*67e74705SXin Li getProgramPaths().push_back(BinDir);
3018*67e74705SXin Li
3019*67e74705SXin Li ToolChain::path_list &LibPaths = getFilePaths();
3020*67e74705SXin Li
3021*67e74705SXin Li // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
3022*67e74705SXin Li // 'elf' OS type, so the Linux paths are not appropriate. When we actually
3023*67e74705SXin Li // support 'linux' we'll need to fix this up
3024*67e74705SXin Li LibPaths.clear();
3025*67e74705SXin Li getHexagonLibraryPaths(Args, LibPaths);
3026*67e74705SXin Li }
3027*67e74705SXin Li
~HexagonToolChain()3028*67e74705SXin Li HexagonToolChain::~HexagonToolChain() {}
3029*67e74705SXin Li
buildAssembler() const3030*67e74705SXin Li Tool *HexagonToolChain::buildAssembler() const {
3031*67e74705SXin Li return new tools::hexagon::Assembler(*this);
3032*67e74705SXin Li }
3033*67e74705SXin Li
buildLinker() const3034*67e74705SXin Li Tool *HexagonToolChain::buildLinker() const {
3035*67e74705SXin Li return new tools::hexagon::Linker(*this);
3036*67e74705SXin Li }
3037*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3038*67e74705SXin Li void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3039*67e74705SXin Li ArgStringList &CC1Args) const {
3040*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3041*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdlibinc))
3042*67e74705SXin Li return;
3043*67e74705SXin Li
3044*67e74705SXin Li const Driver &D = getDriver();
3045*67e74705SXin Li std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3046*67e74705SXin Li D.PrefixDirs);
3047*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
3048*67e74705SXin Li }
3049*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3050*67e74705SXin Li void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
3051*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
3052*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3053*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3054*67e74705SXin Li return;
3055*67e74705SXin Li
3056*67e74705SXin Li const Driver &D = getDriver();
3057*67e74705SXin Li std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
3058*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++");
3059*67e74705SXin Li }
3060*67e74705SXin Li
3061*67e74705SXin Li ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const3062*67e74705SXin Li HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
3063*67e74705SXin Li Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
3064*67e74705SXin Li if (!A)
3065*67e74705SXin Li return ToolChain::CST_Libstdcxx;
3066*67e74705SXin Li
3067*67e74705SXin Li StringRef Value = A->getValue();
3068*67e74705SXin Li if (Value != "libstdc++")
3069*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
3070*67e74705SXin Li
3071*67e74705SXin Li return ToolChain::CST_Libstdcxx;
3072*67e74705SXin Li }
3073*67e74705SXin Li
3074*67e74705SXin Li //
3075*67e74705SXin Li // Returns the default CPU for Hexagon. This is the default compilation target
3076*67e74705SXin Li // if no Hexagon processor is selected at the command-line.
3077*67e74705SXin Li //
GetDefaultCPU()3078*67e74705SXin Li const StringRef HexagonToolChain::GetDefaultCPU() {
3079*67e74705SXin Li return "hexagonv60";
3080*67e74705SXin Li }
3081*67e74705SXin Li
GetTargetCPUVersion(const ArgList & Args)3082*67e74705SXin Li const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
3083*67e74705SXin Li Arg *CpuArg = nullptr;
3084*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
3085*67e74705SXin Li CpuArg = A;
3086*67e74705SXin Li
3087*67e74705SXin Li StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
3088*67e74705SXin Li if (CPU.startswith("hexagon"))
3089*67e74705SXin Li return CPU.substr(sizeof("hexagon") - 1);
3090*67e74705SXin Li return CPU;
3091*67e74705SXin Li }
3092*67e74705SXin Li // End Hexagon
3093*67e74705SXin Li
3094*67e74705SXin Li /// AMDGPU Toolchain
AMDGPUToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3095*67e74705SXin Li AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
3096*67e74705SXin Li const ArgList &Args)
3097*67e74705SXin Li : Generic_ELF(D, Triple, Args) { }
3098*67e74705SXin Li
buildLinker() const3099*67e74705SXin Li Tool *AMDGPUToolChain::buildLinker() const {
3100*67e74705SXin Li return new tools::amdgpu::Linker(*this);
3101*67e74705SXin Li }
3102*67e74705SXin Li // End AMDGPU
3103*67e74705SXin Li
3104*67e74705SXin Li /// NaCl Toolchain
NaClToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3105*67e74705SXin Li NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
3106*67e74705SXin Li const ArgList &Args)
3107*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3108*67e74705SXin Li
3109*67e74705SXin Li // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
3110*67e74705SXin Li // default paths, and must instead only use the paths provided
3111*67e74705SXin Li // with this toolchain based on architecture.
3112*67e74705SXin Li path_list &file_paths = getFilePaths();
3113*67e74705SXin Li path_list &prog_paths = getProgramPaths();
3114*67e74705SXin Li
3115*67e74705SXin Li file_paths.clear();
3116*67e74705SXin Li prog_paths.clear();
3117*67e74705SXin Li
3118*67e74705SXin Li // Path for library files (libc.a, ...)
3119*67e74705SXin Li std::string FilePath(getDriver().Dir + "/../");
3120*67e74705SXin Li
3121*67e74705SXin Li // Path for tools (clang, ld, etc..)
3122*67e74705SXin Li std::string ProgPath(getDriver().Dir + "/../");
3123*67e74705SXin Li
3124*67e74705SXin Li // Path for toolchain libraries (libgcc.a, ...)
3125*67e74705SXin Li std::string ToolPath(getDriver().ResourceDir + "/lib/");
3126*67e74705SXin Li
3127*67e74705SXin Li switch (Triple.getArch()) {
3128*67e74705SXin Li case llvm::Triple::x86:
3129*67e74705SXin Li file_paths.push_back(FilePath + "x86_64-nacl/lib32");
3130*67e74705SXin Li file_paths.push_back(FilePath + "i686-nacl/usr/lib");
3131*67e74705SXin Li prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3132*67e74705SXin Li file_paths.push_back(ToolPath + "i686-nacl");
3133*67e74705SXin Li break;
3134*67e74705SXin Li case llvm::Triple::x86_64:
3135*67e74705SXin Li file_paths.push_back(FilePath + "x86_64-nacl/lib");
3136*67e74705SXin Li file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
3137*67e74705SXin Li prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3138*67e74705SXin Li file_paths.push_back(ToolPath + "x86_64-nacl");
3139*67e74705SXin Li break;
3140*67e74705SXin Li case llvm::Triple::arm:
3141*67e74705SXin Li file_paths.push_back(FilePath + "arm-nacl/lib");
3142*67e74705SXin Li file_paths.push_back(FilePath + "arm-nacl/usr/lib");
3143*67e74705SXin Li prog_paths.push_back(ProgPath + "arm-nacl/bin");
3144*67e74705SXin Li file_paths.push_back(ToolPath + "arm-nacl");
3145*67e74705SXin Li break;
3146*67e74705SXin Li case llvm::Triple::mipsel:
3147*67e74705SXin Li file_paths.push_back(FilePath + "mipsel-nacl/lib");
3148*67e74705SXin Li file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
3149*67e74705SXin Li prog_paths.push_back(ProgPath + "bin");
3150*67e74705SXin Li file_paths.push_back(ToolPath + "mipsel-nacl");
3151*67e74705SXin Li break;
3152*67e74705SXin Li default:
3153*67e74705SXin Li break;
3154*67e74705SXin Li }
3155*67e74705SXin Li
3156*67e74705SXin Li NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
3157*67e74705SXin Li }
3158*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3159*67e74705SXin Li void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3160*67e74705SXin Li ArgStringList &CC1Args) const {
3161*67e74705SXin Li const Driver &D = getDriver();
3162*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc))
3163*67e74705SXin Li return;
3164*67e74705SXin Li
3165*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3166*67e74705SXin Li SmallString<128> P(D.ResourceDir);
3167*67e74705SXin Li llvm::sys::path::append(P, "include");
3168*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3169*67e74705SXin Li }
3170*67e74705SXin Li
3171*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3172*67e74705SXin Li return;
3173*67e74705SXin Li
3174*67e74705SXin Li SmallString<128> P(D.Dir + "/../");
3175*67e74705SXin Li switch (getTriple().getArch()) {
3176*67e74705SXin Li case llvm::Triple::x86:
3177*67e74705SXin Li // x86 is special because multilib style uses x86_64-nacl/include for libc
3178*67e74705SXin Li // headers but the SDK wants i686-nacl/usr/include. The other architectures
3179*67e74705SXin Li // have the same substring.
3180*67e74705SXin Li llvm::sys::path::append(P, "i686-nacl/usr/include");
3181*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3182*67e74705SXin Li llvm::sys::path::remove_filename(P);
3183*67e74705SXin Li llvm::sys::path::remove_filename(P);
3184*67e74705SXin Li llvm::sys::path::remove_filename(P);
3185*67e74705SXin Li llvm::sys::path::append(P, "x86_64-nacl/include");
3186*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3187*67e74705SXin Li return;
3188*67e74705SXin Li case llvm::Triple::arm:
3189*67e74705SXin Li llvm::sys::path::append(P, "arm-nacl/usr/include");
3190*67e74705SXin Li break;
3191*67e74705SXin Li case llvm::Triple::x86_64:
3192*67e74705SXin Li llvm::sys::path::append(P, "x86_64-nacl/usr/include");
3193*67e74705SXin Li break;
3194*67e74705SXin Li case llvm::Triple::mipsel:
3195*67e74705SXin Li llvm::sys::path::append(P, "mipsel-nacl/usr/include");
3196*67e74705SXin Li break;
3197*67e74705SXin Li default:
3198*67e74705SXin Li return;
3199*67e74705SXin Li }
3200*67e74705SXin Li
3201*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3202*67e74705SXin Li llvm::sys::path::remove_filename(P);
3203*67e74705SXin Li llvm::sys::path::remove_filename(P);
3204*67e74705SXin Li llvm::sys::path::append(P, "include");
3205*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3206*67e74705SXin Li }
3207*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3208*67e74705SXin Li void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
3209*67e74705SXin Li ArgStringList &CmdArgs) const {
3210*67e74705SXin Li // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3211*67e74705SXin Li // if the value is libc++, and emits an error for other values.
3212*67e74705SXin Li GetCXXStdlibType(Args);
3213*67e74705SXin Li CmdArgs.push_back("-lc++");
3214*67e74705SXin Li }
3215*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3216*67e74705SXin Li void NaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3217*67e74705SXin Li ArgStringList &CC1Args) const {
3218*67e74705SXin Li const Driver &D = getDriver();
3219*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3220*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3221*67e74705SXin Li return;
3222*67e74705SXin Li
3223*67e74705SXin Li // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3224*67e74705SXin Li // if the value is libc++, and emits an error for other values.
3225*67e74705SXin Li GetCXXStdlibType(DriverArgs);
3226*67e74705SXin Li
3227*67e74705SXin Li SmallString<128> P(D.Dir + "/../");
3228*67e74705SXin Li switch (getTriple().getArch()) {
3229*67e74705SXin Li case llvm::Triple::arm:
3230*67e74705SXin Li llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
3231*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3232*67e74705SXin Li break;
3233*67e74705SXin Li case llvm::Triple::x86:
3234*67e74705SXin Li llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3235*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3236*67e74705SXin Li break;
3237*67e74705SXin Li case llvm::Triple::x86_64:
3238*67e74705SXin Li llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3239*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3240*67e74705SXin Li break;
3241*67e74705SXin Li case llvm::Triple::mipsel:
3242*67e74705SXin Li llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
3243*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3244*67e74705SXin Li break;
3245*67e74705SXin Li default:
3246*67e74705SXin Li break;
3247*67e74705SXin Li }
3248*67e74705SXin Li }
3249*67e74705SXin Li
3250*67e74705SXin Li ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const3251*67e74705SXin Li NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
3252*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
3253*67e74705SXin Li StringRef Value = A->getValue();
3254*67e74705SXin Li if (Value == "libc++")
3255*67e74705SXin Li return ToolChain::CST_Libcxx;
3256*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
3257*67e74705SXin Li }
3258*67e74705SXin Li
3259*67e74705SXin Li return ToolChain::CST_Libcxx;
3260*67e74705SXin Li }
3261*67e74705SXin Li
3262*67e74705SXin Li std::string
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const3263*67e74705SXin Li NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
3264*67e74705SXin Li types::ID InputType) const {
3265*67e74705SXin Li llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
3266*67e74705SXin Li if (TheTriple.getArch() == llvm::Triple::arm &&
3267*67e74705SXin Li TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
3268*67e74705SXin Li TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
3269*67e74705SXin Li return TheTriple.getTriple();
3270*67e74705SXin Li }
3271*67e74705SXin Li
buildLinker() const3272*67e74705SXin Li Tool *NaClToolChain::buildLinker() const {
3273*67e74705SXin Li return new tools::nacltools::Linker(*this);
3274*67e74705SXin Li }
3275*67e74705SXin Li
buildAssembler() const3276*67e74705SXin Li Tool *NaClToolChain::buildAssembler() const {
3277*67e74705SXin Li if (getTriple().getArch() == llvm::Triple::arm)
3278*67e74705SXin Li return new tools::nacltools::AssemblerARM(*this);
3279*67e74705SXin Li return new tools::gnutools::Assembler(*this);
3280*67e74705SXin Li }
3281*67e74705SXin Li // End NaCl
3282*67e74705SXin Li
3283*67e74705SXin Li /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
3284*67e74705SXin Li /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
3285*67e74705SXin Li /// Currently does not support anything else but compilation.
3286*67e74705SXin Li
TCEToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3287*67e74705SXin Li TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
3288*67e74705SXin Li const ArgList &Args)
3289*67e74705SXin Li : ToolChain(D, Triple, Args) {
3290*67e74705SXin Li // Path mangling to find libexec
3291*67e74705SXin Li std::string Path(getDriver().Dir);
3292*67e74705SXin Li
3293*67e74705SXin Li Path += "/../libexec";
3294*67e74705SXin Li getProgramPaths().push_back(Path);
3295*67e74705SXin Li }
3296*67e74705SXin Li
~TCEToolChain()3297*67e74705SXin Li TCEToolChain::~TCEToolChain() {}
3298*67e74705SXin Li
IsMathErrnoDefault() const3299*67e74705SXin Li bool TCEToolChain::IsMathErrnoDefault() const { return true; }
3300*67e74705SXin Li
isPICDefault() const3301*67e74705SXin Li bool TCEToolChain::isPICDefault() const { return false; }
3302*67e74705SXin Li
isPIEDefault() const3303*67e74705SXin Li bool TCEToolChain::isPIEDefault() const { return false; }
3304*67e74705SXin Li
isPICDefaultForced() const3305*67e74705SXin Li bool TCEToolChain::isPICDefaultForced() const { return false; }
3306*67e74705SXin Li
3307*67e74705SXin Li // CloudABI - CloudABI tool chain which can call ld(1) directly.
3308*67e74705SXin Li
CloudABI(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3309*67e74705SXin Li CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
3310*67e74705SXin Li const ArgList &Args)
3311*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3312*67e74705SXin Li SmallString<128> P(getDriver().Dir);
3313*67e74705SXin Li llvm::sys::path::append(P, "..", getTriple().str(), "lib");
3314*67e74705SXin Li getFilePaths().push_back(P.str());
3315*67e74705SXin Li }
3316*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3317*67e74705SXin Li void CloudABI::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3318*67e74705SXin Li ArgStringList &CC1Args) const {
3319*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) &&
3320*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3321*67e74705SXin Li return;
3322*67e74705SXin Li
3323*67e74705SXin Li SmallString<128> P(getDriver().Dir);
3324*67e74705SXin Li llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
3325*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P.str());
3326*67e74705SXin Li }
3327*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3328*67e74705SXin Li void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
3329*67e74705SXin Li ArgStringList &CmdArgs) const {
3330*67e74705SXin Li CmdArgs.push_back("-lc++");
3331*67e74705SXin Li CmdArgs.push_back("-lc++abi");
3332*67e74705SXin Li CmdArgs.push_back("-lunwind");
3333*67e74705SXin Li }
3334*67e74705SXin Li
buildLinker() const3335*67e74705SXin Li Tool *CloudABI::buildLinker() const {
3336*67e74705SXin Li return new tools::cloudabi::Linker(*this);
3337*67e74705SXin Li }
3338*67e74705SXin Li
getSupportedSanitizers() const3339*67e74705SXin Li SanitizerMask CloudABI::getSupportedSanitizers() const {
3340*67e74705SXin Li SanitizerMask Res = ToolChain::getSupportedSanitizers();
3341*67e74705SXin Li Res |= SanitizerKind::SafeStack;
3342*67e74705SXin Li return Res;
3343*67e74705SXin Li }
3344*67e74705SXin Li
getDefaultSanitizers() const3345*67e74705SXin Li SanitizerMask CloudABI::getDefaultSanitizers() const {
3346*67e74705SXin Li return SanitizerKind::SafeStack;
3347*67e74705SXin Li }
3348*67e74705SXin Li
3349*67e74705SXin Li /// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
3350*67e74705SXin Li
Haiku(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3351*67e74705SXin Li Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
3352*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3353*67e74705SXin Li
3354*67e74705SXin Li }
3355*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3356*67e74705SXin Li void Haiku::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3357*67e74705SXin Li ArgStringList &CC1Args) const {
3358*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3359*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3360*67e74705SXin Li return;
3361*67e74705SXin Li
3362*67e74705SXin Li switch (GetCXXStdlibType(DriverArgs)) {
3363*67e74705SXin Li case ToolChain::CST_Libcxx:
3364*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3365*67e74705SXin Li getDriver().SysRoot + "/system/develop/headers/c++/v1");
3366*67e74705SXin Li break;
3367*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3368*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3369*67e74705SXin Li getDriver().SysRoot + "/system/develop/headers/c++");
3370*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3371*67e74705SXin Li getDriver().SysRoot + "/system/develop/headers/c++/backward");
3372*67e74705SXin Li
3373*67e74705SXin Li StringRef Triple = getTriple().str();
3374*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3375*67e74705SXin Li getDriver().SysRoot + "/system/develop/headers/c++/" +
3376*67e74705SXin Li Triple);
3377*67e74705SXin Li break;
3378*67e74705SXin Li }
3379*67e74705SXin Li }
3380*67e74705SXin Li
3381*67e74705SXin Li /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
3382*67e74705SXin Li
OpenBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3383*67e74705SXin Li OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
3384*67e74705SXin Li const ArgList &Args)
3385*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3386*67e74705SXin Li getFilePaths().push_back(getDriver().Dir + "/../lib");
3387*67e74705SXin Li getFilePaths().push_back("/usr/lib");
3388*67e74705SXin Li }
3389*67e74705SXin Li
buildAssembler() const3390*67e74705SXin Li Tool *OpenBSD::buildAssembler() const {
3391*67e74705SXin Li return new tools::openbsd::Assembler(*this);
3392*67e74705SXin Li }
3393*67e74705SXin Li
buildLinker() const3394*67e74705SXin Li Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
3395*67e74705SXin Li
3396*67e74705SXin Li /// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
3397*67e74705SXin Li
Bitrig(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3398*67e74705SXin Li Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3399*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3400*67e74705SXin Li getFilePaths().push_back(getDriver().Dir + "/../lib");
3401*67e74705SXin Li getFilePaths().push_back("/usr/lib");
3402*67e74705SXin Li }
3403*67e74705SXin Li
buildAssembler() const3404*67e74705SXin Li Tool *Bitrig::buildAssembler() const {
3405*67e74705SXin Li return new tools::bitrig::Assembler(*this);
3406*67e74705SXin Li }
3407*67e74705SXin Li
buildLinker() const3408*67e74705SXin Li Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
3409*67e74705SXin Li
GetDefaultCXXStdlibType() const3410*67e74705SXin Li ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
3411*67e74705SXin Li return ToolChain::CST_Libcxx;
3412*67e74705SXin Li }
3413*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3414*67e74705SXin Li void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3415*67e74705SXin Li ArgStringList &CC1Args) const {
3416*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3417*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3418*67e74705SXin Li return;
3419*67e74705SXin Li
3420*67e74705SXin Li switch (GetCXXStdlibType(DriverArgs)) {
3421*67e74705SXin Li case ToolChain::CST_Libcxx:
3422*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3423*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/v1");
3424*67e74705SXin Li break;
3425*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3426*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3427*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/stdc++");
3428*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3429*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
3430*67e74705SXin Li
3431*67e74705SXin Li StringRef Triple = getTriple().str();
3432*67e74705SXin Li if (Triple.startswith("amd64"))
3433*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3434*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
3435*67e74705SXin Li Triple.substr(5));
3436*67e74705SXin Li else
3437*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot +
3438*67e74705SXin Li "/usr/include/c++/stdc++/" +
3439*67e74705SXin Li Triple);
3440*67e74705SXin Li break;
3441*67e74705SXin Li }
3442*67e74705SXin Li }
3443*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3444*67e74705SXin Li void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
3445*67e74705SXin Li ArgStringList &CmdArgs) const {
3446*67e74705SXin Li switch (GetCXXStdlibType(Args)) {
3447*67e74705SXin Li case ToolChain::CST_Libcxx:
3448*67e74705SXin Li CmdArgs.push_back("-lc++");
3449*67e74705SXin Li CmdArgs.push_back("-lc++abi");
3450*67e74705SXin Li CmdArgs.push_back("-lpthread");
3451*67e74705SXin Li break;
3452*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3453*67e74705SXin Li CmdArgs.push_back("-lstdc++");
3454*67e74705SXin Li break;
3455*67e74705SXin Li }
3456*67e74705SXin Li }
3457*67e74705SXin Li
3458*67e74705SXin Li /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
3459*67e74705SXin Li
FreeBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3460*67e74705SXin Li FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
3461*67e74705SXin Li const ArgList &Args)
3462*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3463*67e74705SXin Li
3464*67e74705SXin Li // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
3465*67e74705SXin Li // back to '/usr/lib' if it doesn't exist.
3466*67e74705SXin Li if ((Triple.getArch() == llvm::Triple::x86 ||
3467*67e74705SXin Li Triple.getArch() == llvm::Triple::ppc) &&
3468*67e74705SXin Li D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
3469*67e74705SXin Li getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
3470*67e74705SXin Li else
3471*67e74705SXin Li getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
3472*67e74705SXin Li }
3473*67e74705SXin Li
GetDefaultCXXStdlibType() const3474*67e74705SXin Li ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
3475*67e74705SXin Li if (getTriple().getOSMajorVersion() >= 10)
3476*67e74705SXin Li return ToolChain::CST_Libcxx;
3477*67e74705SXin Li return ToolChain::CST_Libstdcxx;
3478*67e74705SXin Li }
3479*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3480*67e74705SXin Li void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3481*67e74705SXin Li ArgStringList &CC1Args) const {
3482*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3483*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3484*67e74705SXin Li return;
3485*67e74705SXin Li
3486*67e74705SXin Li switch (GetCXXStdlibType(DriverArgs)) {
3487*67e74705SXin Li case ToolChain::CST_Libcxx:
3488*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3489*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/v1");
3490*67e74705SXin Li break;
3491*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3492*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3493*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/4.2");
3494*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3495*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/4.2/backward");
3496*67e74705SXin Li break;
3497*67e74705SXin Li }
3498*67e74705SXin Li }
3499*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3500*67e74705SXin Li void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
3501*67e74705SXin Li ArgStringList &CmdArgs) const {
3502*67e74705SXin Li CXXStdlibType Type = GetCXXStdlibType(Args);
3503*67e74705SXin Li bool Profiling = Args.hasArg(options::OPT_pg);
3504*67e74705SXin Li
3505*67e74705SXin Li switch (Type) {
3506*67e74705SXin Li case ToolChain::CST_Libcxx:
3507*67e74705SXin Li CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
3508*67e74705SXin Li break;
3509*67e74705SXin Li
3510*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3511*67e74705SXin Li CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
3512*67e74705SXin Li break;
3513*67e74705SXin Li }
3514*67e74705SXin Li }
3515*67e74705SXin Li
buildAssembler() const3516*67e74705SXin Li Tool *FreeBSD::buildAssembler() const {
3517*67e74705SXin Li return new tools::freebsd::Assembler(*this);
3518*67e74705SXin Li }
3519*67e74705SXin Li
buildLinker() const3520*67e74705SXin Li Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
3521*67e74705SXin Li
UseSjLjExceptions(const ArgList & Args) const3522*67e74705SXin Li bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
3523*67e74705SXin Li // FreeBSD uses SjLj exceptions on ARM oabi.
3524*67e74705SXin Li switch (getTriple().getEnvironment()) {
3525*67e74705SXin Li case llvm::Triple::GNUEABIHF:
3526*67e74705SXin Li case llvm::Triple::GNUEABI:
3527*67e74705SXin Li case llvm::Triple::EABI:
3528*67e74705SXin Li return false;
3529*67e74705SXin Li
3530*67e74705SXin Li default:
3531*67e74705SXin Li return (getTriple().getArch() == llvm::Triple::arm ||
3532*67e74705SXin Li getTriple().getArch() == llvm::Triple::thumb);
3533*67e74705SXin Li }
3534*67e74705SXin Li }
3535*67e74705SXin Li
HasNativeLLVMSupport() const3536*67e74705SXin Li bool FreeBSD::HasNativeLLVMSupport() const { return true; }
3537*67e74705SXin Li
isPIEDefault() const3538*67e74705SXin Li bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
3539*67e74705SXin Li
getSupportedSanitizers() const3540*67e74705SXin Li SanitizerMask FreeBSD::getSupportedSanitizers() const {
3541*67e74705SXin Li const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
3542*67e74705SXin Li const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3543*67e74705SXin Li const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
3544*67e74705SXin Li getTriple().getArch() == llvm::Triple::mips64el;
3545*67e74705SXin Li SanitizerMask Res = ToolChain::getSupportedSanitizers();
3546*67e74705SXin Li Res |= SanitizerKind::Address;
3547*67e74705SXin Li Res |= SanitizerKind::Vptr;
3548*67e74705SXin Li if (IsX86_64 || IsMIPS64) {
3549*67e74705SXin Li Res |= SanitizerKind::Leak;
3550*67e74705SXin Li Res |= SanitizerKind::Thread;
3551*67e74705SXin Li }
3552*67e74705SXin Li if (IsX86 || IsX86_64) {
3553*67e74705SXin Li Res |= SanitizerKind::SafeStack;
3554*67e74705SXin Li }
3555*67e74705SXin Li return Res;
3556*67e74705SXin Li }
3557*67e74705SXin Li
3558*67e74705SXin Li /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
3559*67e74705SXin Li
NetBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3560*67e74705SXin Li NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3561*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3562*67e74705SXin Li if (getDriver().UseStdLib) {
3563*67e74705SXin Li // When targeting a 32-bit platform, try the special directory used on
3564*67e74705SXin Li // 64-bit hosts, and only fall back to the main library directory if that
3565*67e74705SXin Li // doesn't work.
3566*67e74705SXin Li // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
3567*67e74705SXin Li // what all logic is needed to emulate the '=' prefix here.
3568*67e74705SXin Li switch (Triple.getArch()) {
3569*67e74705SXin Li case llvm::Triple::x86:
3570*67e74705SXin Li getFilePaths().push_back("=/usr/lib/i386");
3571*67e74705SXin Li break;
3572*67e74705SXin Li case llvm::Triple::arm:
3573*67e74705SXin Li case llvm::Triple::armeb:
3574*67e74705SXin Li case llvm::Triple::thumb:
3575*67e74705SXin Li case llvm::Triple::thumbeb:
3576*67e74705SXin Li switch (Triple.getEnvironment()) {
3577*67e74705SXin Li case llvm::Triple::EABI:
3578*67e74705SXin Li case llvm::Triple::GNUEABI:
3579*67e74705SXin Li getFilePaths().push_back("=/usr/lib/eabi");
3580*67e74705SXin Li break;
3581*67e74705SXin Li case llvm::Triple::EABIHF:
3582*67e74705SXin Li case llvm::Triple::GNUEABIHF:
3583*67e74705SXin Li getFilePaths().push_back("=/usr/lib/eabihf");
3584*67e74705SXin Li break;
3585*67e74705SXin Li default:
3586*67e74705SXin Li getFilePaths().push_back("=/usr/lib/oabi");
3587*67e74705SXin Li break;
3588*67e74705SXin Li }
3589*67e74705SXin Li break;
3590*67e74705SXin Li case llvm::Triple::mips64:
3591*67e74705SXin Li case llvm::Triple::mips64el:
3592*67e74705SXin Li if (tools::mips::hasMipsAbiArg(Args, "o32"))
3593*67e74705SXin Li getFilePaths().push_back("=/usr/lib/o32");
3594*67e74705SXin Li else if (tools::mips::hasMipsAbiArg(Args, "64"))
3595*67e74705SXin Li getFilePaths().push_back("=/usr/lib/64");
3596*67e74705SXin Li break;
3597*67e74705SXin Li case llvm::Triple::ppc:
3598*67e74705SXin Li getFilePaths().push_back("=/usr/lib/powerpc");
3599*67e74705SXin Li break;
3600*67e74705SXin Li case llvm::Triple::sparc:
3601*67e74705SXin Li getFilePaths().push_back("=/usr/lib/sparc");
3602*67e74705SXin Li break;
3603*67e74705SXin Li default:
3604*67e74705SXin Li break;
3605*67e74705SXin Li }
3606*67e74705SXin Li
3607*67e74705SXin Li getFilePaths().push_back("=/usr/lib");
3608*67e74705SXin Li }
3609*67e74705SXin Li }
3610*67e74705SXin Li
buildAssembler() const3611*67e74705SXin Li Tool *NetBSD::buildAssembler() const {
3612*67e74705SXin Li return new tools::netbsd::Assembler(*this);
3613*67e74705SXin Li }
3614*67e74705SXin Li
buildLinker() const3615*67e74705SXin Li Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
3616*67e74705SXin Li
GetDefaultCXXStdlibType() const3617*67e74705SXin Li ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
3618*67e74705SXin Li unsigned Major, Minor, Micro;
3619*67e74705SXin Li getTriple().getOSVersion(Major, Minor, Micro);
3620*67e74705SXin Li if (Major >= 7 || Major == 0) {
3621*67e74705SXin Li switch (getArch()) {
3622*67e74705SXin Li case llvm::Triple::aarch64:
3623*67e74705SXin Li case llvm::Triple::arm:
3624*67e74705SXin Li case llvm::Triple::armeb:
3625*67e74705SXin Li case llvm::Triple::thumb:
3626*67e74705SXin Li case llvm::Triple::thumbeb:
3627*67e74705SXin Li case llvm::Triple::ppc:
3628*67e74705SXin Li case llvm::Triple::ppc64:
3629*67e74705SXin Li case llvm::Triple::ppc64le:
3630*67e74705SXin Li case llvm::Triple::sparc:
3631*67e74705SXin Li case llvm::Triple::sparcv9:
3632*67e74705SXin Li case llvm::Triple::x86:
3633*67e74705SXin Li case llvm::Triple::x86_64:
3634*67e74705SXin Li return ToolChain::CST_Libcxx;
3635*67e74705SXin Li default:
3636*67e74705SXin Li break;
3637*67e74705SXin Li }
3638*67e74705SXin Li }
3639*67e74705SXin Li return ToolChain::CST_Libstdcxx;
3640*67e74705SXin Li }
3641*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3642*67e74705SXin Li void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3643*67e74705SXin Li ArgStringList &CC1Args) const {
3644*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3645*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3646*67e74705SXin Li return;
3647*67e74705SXin Li
3648*67e74705SXin Li switch (GetCXXStdlibType(DriverArgs)) {
3649*67e74705SXin Li case ToolChain::CST_Libcxx:
3650*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3651*67e74705SXin Li getDriver().SysRoot + "/usr/include/c++/");
3652*67e74705SXin Li break;
3653*67e74705SXin Li case ToolChain::CST_Libstdcxx:
3654*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3655*67e74705SXin Li getDriver().SysRoot + "/usr/include/g++");
3656*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3657*67e74705SXin Li getDriver().SysRoot + "/usr/include/g++/backward");
3658*67e74705SXin Li break;
3659*67e74705SXin Li }
3660*67e74705SXin Li }
3661*67e74705SXin Li
3662*67e74705SXin Li /// Minix - Minix tool chain which can call as(1) and ld(1) directly.
3663*67e74705SXin Li
Minix(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3664*67e74705SXin Li Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3665*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
3666*67e74705SXin Li getFilePaths().push_back(getDriver().Dir + "/../lib");
3667*67e74705SXin Li getFilePaths().push_back("/usr/lib");
3668*67e74705SXin Li }
3669*67e74705SXin Li
buildAssembler() const3670*67e74705SXin Li Tool *Minix::buildAssembler() const {
3671*67e74705SXin Li return new tools::minix::Assembler(*this);
3672*67e74705SXin Li }
3673*67e74705SXin Li
buildLinker() const3674*67e74705SXin Li Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }
3675*67e74705SXin Li
addPathIfExists(const Driver & D,const Twine & Path,ToolChain::path_list & Paths)3676*67e74705SXin Li static void addPathIfExists(const Driver &D, const Twine &Path,
3677*67e74705SXin Li ToolChain::path_list &Paths) {
3678*67e74705SXin Li if (D.getVFS().exists(Path))
3679*67e74705SXin Li Paths.push_back(Path.str());
3680*67e74705SXin Li }
3681*67e74705SXin Li
3682*67e74705SXin Li /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
3683*67e74705SXin Li
Solaris(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3684*67e74705SXin Li Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
3685*67e74705SXin Li const ArgList &Args)
3686*67e74705SXin Li : Generic_GCC(D, Triple, Args) {
3687*67e74705SXin Li
3688*67e74705SXin Li GCCInstallation.init(Triple, Args);
3689*67e74705SXin Li
3690*67e74705SXin Li path_list &Paths = getFilePaths();
3691*67e74705SXin Li if (GCCInstallation.isValid())
3692*67e74705SXin Li addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
3693*67e74705SXin Li
3694*67e74705SXin Li addPathIfExists(D, getDriver().getInstalledDir(), Paths);
3695*67e74705SXin Li if (getDriver().getInstalledDir() != getDriver().Dir)
3696*67e74705SXin Li addPathIfExists(D, getDriver().Dir, Paths);
3697*67e74705SXin Li
3698*67e74705SXin Li addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
3699*67e74705SXin Li
3700*67e74705SXin Li std::string LibPath = "/usr/lib/";
3701*67e74705SXin Li switch (Triple.getArch()) {
3702*67e74705SXin Li case llvm::Triple::x86:
3703*67e74705SXin Li case llvm::Triple::sparc:
3704*67e74705SXin Li break;
3705*67e74705SXin Li case llvm::Triple::x86_64:
3706*67e74705SXin Li LibPath += "amd64/";
3707*67e74705SXin Li break;
3708*67e74705SXin Li case llvm::Triple::sparcv9:
3709*67e74705SXin Li LibPath += "sparcv9/";
3710*67e74705SXin Li break;
3711*67e74705SXin Li default:
3712*67e74705SXin Li llvm_unreachable("Unsupported architecture");
3713*67e74705SXin Li }
3714*67e74705SXin Li
3715*67e74705SXin Li addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
3716*67e74705SXin Li }
3717*67e74705SXin Li
buildAssembler() const3718*67e74705SXin Li Tool *Solaris::buildAssembler() const {
3719*67e74705SXin Li return new tools::solaris::Assembler(*this);
3720*67e74705SXin Li }
3721*67e74705SXin Li
buildLinker() const3722*67e74705SXin Li Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
3723*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3724*67e74705SXin Li void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3725*67e74705SXin Li ArgStringList &CC1Args) const {
3726*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3727*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
3728*67e74705SXin Li return;
3729*67e74705SXin Li
3730*67e74705SXin Li // Include the support directory for things like xlocale and fudged system
3731*67e74705SXin Li // headers.
3732*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
3733*67e74705SXin Li
3734*67e74705SXin Li if (GCCInstallation.isValid()) {
3735*67e74705SXin Li GCCVersion Version = GCCInstallation.getVersion();
3736*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3737*67e74705SXin Li getDriver().SysRoot + "/usr/gcc/" +
3738*67e74705SXin Li Version.MajorStr + "." +
3739*67e74705SXin Li Version.MinorStr +
3740*67e74705SXin Li "/include/c++/" + Version.Text);
3741*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
3742*67e74705SXin Li getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
3743*67e74705SXin Li "." + Version.MinorStr + "/include/c++/" +
3744*67e74705SXin Li Version.Text + "/" +
3745*67e74705SXin Li GCCInstallation.getTriple().str());
3746*67e74705SXin Li }
3747*67e74705SXin Li }
3748*67e74705SXin Li
3749*67e74705SXin Li /// Distribution (very bare-bones at the moment).
3750*67e74705SXin Li
3751*67e74705SXin Li enum Distro {
3752*67e74705SXin Li // NB: Releases of a particular Linux distro should be kept together
3753*67e74705SXin Li // in this enum, because some tests are done by integer comparison against
3754*67e74705SXin Li // the first and last known member in the family, e.g. IsRedHat().
3755*67e74705SXin Li ArchLinux,
3756*67e74705SXin Li DebianLenny,
3757*67e74705SXin Li DebianSqueeze,
3758*67e74705SXin Li DebianWheezy,
3759*67e74705SXin Li DebianJessie,
3760*67e74705SXin Li DebianStretch,
3761*67e74705SXin Li Exherbo,
3762*67e74705SXin Li RHEL5,
3763*67e74705SXin Li RHEL6,
3764*67e74705SXin Li RHEL7,
3765*67e74705SXin Li Fedora,
3766*67e74705SXin Li OpenSUSE,
3767*67e74705SXin Li UbuntuHardy,
3768*67e74705SXin Li UbuntuIntrepid,
3769*67e74705SXin Li UbuntuJaunty,
3770*67e74705SXin Li UbuntuKarmic,
3771*67e74705SXin Li UbuntuLucid,
3772*67e74705SXin Li UbuntuMaverick,
3773*67e74705SXin Li UbuntuNatty,
3774*67e74705SXin Li UbuntuOneiric,
3775*67e74705SXin Li UbuntuPrecise,
3776*67e74705SXin Li UbuntuQuantal,
3777*67e74705SXin Li UbuntuRaring,
3778*67e74705SXin Li UbuntuSaucy,
3779*67e74705SXin Li UbuntuTrusty,
3780*67e74705SXin Li UbuntuUtopic,
3781*67e74705SXin Li UbuntuVivid,
3782*67e74705SXin Li UbuntuWily,
3783*67e74705SXin Li UbuntuXenial,
3784*67e74705SXin Li UnknownDistro
3785*67e74705SXin Li };
3786*67e74705SXin Li
IsRedhat(enum Distro Distro)3787*67e74705SXin Li static bool IsRedhat(enum Distro Distro) {
3788*67e74705SXin Li return Distro == Fedora || (Distro >= RHEL5 && Distro <= RHEL7);
3789*67e74705SXin Li }
3790*67e74705SXin Li
IsOpenSUSE(enum Distro Distro)3791*67e74705SXin Li static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; }
3792*67e74705SXin Li
IsDebian(enum Distro Distro)3793*67e74705SXin Li static bool IsDebian(enum Distro Distro) {
3794*67e74705SXin Li return Distro >= DebianLenny && Distro <= DebianStretch;
3795*67e74705SXin Li }
3796*67e74705SXin Li
IsUbuntu(enum Distro Distro)3797*67e74705SXin Li static bool IsUbuntu(enum Distro Distro) {
3798*67e74705SXin Li return Distro >= UbuntuHardy && Distro <= UbuntuXenial;
3799*67e74705SXin Li }
3800*67e74705SXin Li
DetectDistro(const Driver & D,llvm::Triple::ArchType Arch)3801*67e74705SXin Li static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
3802*67e74705SXin Li llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
3803*67e74705SXin Li llvm::MemoryBuffer::getFile("/etc/lsb-release");
3804*67e74705SXin Li if (File) {
3805*67e74705SXin Li StringRef Data = File.get()->getBuffer();
3806*67e74705SXin Li SmallVector<StringRef, 16> Lines;
3807*67e74705SXin Li Data.split(Lines, "\n");
3808*67e74705SXin Li Distro Version = UnknownDistro;
3809*67e74705SXin Li for (StringRef Line : Lines)
3810*67e74705SXin Li if (Version == UnknownDistro && Line.startswith("DISTRIB_CODENAME="))
3811*67e74705SXin Li Version = llvm::StringSwitch<Distro>(Line.substr(17))
3812*67e74705SXin Li .Case("hardy", UbuntuHardy)
3813*67e74705SXin Li .Case("intrepid", UbuntuIntrepid)
3814*67e74705SXin Li .Case("jaunty", UbuntuJaunty)
3815*67e74705SXin Li .Case("karmic", UbuntuKarmic)
3816*67e74705SXin Li .Case("lucid", UbuntuLucid)
3817*67e74705SXin Li .Case("maverick", UbuntuMaverick)
3818*67e74705SXin Li .Case("natty", UbuntuNatty)
3819*67e74705SXin Li .Case("oneiric", UbuntuOneiric)
3820*67e74705SXin Li .Case("precise", UbuntuPrecise)
3821*67e74705SXin Li .Case("quantal", UbuntuQuantal)
3822*67e74705SXin Li .Case("raring", UbuntuRaring)
3823*67e74705SXin Li .Case("saucy", UbuntuSaucy)
3824*67e74705SXin Li .Case("trusty", UbuntuTrusty)
3825*67e74705SXin Li .Case("utopic", UbuntuUtopic)
3826*67e74705SXin Li .Case("vivid", UbuntuVivid)
3827*67e74705SXin Li .Case("wily", UbuntuWily)
3828*67e74705SXin Li .Case("xenial", UbuntuXenial)
3829*67e74705SXin Li .Default(UnknownDistro);
3830*67e74705SXin Li if (Version != UnknownDistro)
3831*67e74705SXin Li return Version;
3832*67e74705SXin Li }
3833*67e74705SXin Li
3834*67e74705SXin Li File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
3835*67e74705SXin Li if (File) {
3836*67e74705SXin Li StringRef Data = File.get()->getBuffer();
3837*67e74705SXin Li if (Data.startswith("Fedora release"))
3838*67e74705SXin Li return Fedora;
3839*67e74705SXin Li if (Data.startswith("Red Hat Enterprise Linux") ||
3840*67e74705SXin Li Data.startswith("CentOS") ||
3841*67e74705SXin Li Data.startswith("Scientific Linux")) {
3842*67e74705SXin Li if (Data.find("release 7") != StringRef::npos)
3843*67e74705SXin Li return RHEL7;
3844*67e74705SXin Li else if (Data.find("release 6") != StringRef::npos)
3845*67e74705SXin Li return RHEL6;
3846*67e74705SXin Li else if (Data.find("release 5") != StringRef::npos)
3847*67e74705SXin Li return RHEL5;
3848*67e74705SXin Li }
3849*67e74705SXin Li return UnknownDistro;
3850*67e74705SXin Li }
3851*67e74705SXin Li
3852*67e74705SXin Li File = llvm::MemoryBuffer::getFile("/etc/debian_version");
3853*67e74705SXin Li if (File) {
3854*67e74705SXin Li StringRef Data = File.get()->getBuffer();
3855*67e74705SXin Li if (Data[0] == '5')
3856*67e74705SXin Li return DebianLenny;
3857*67e74705SXin Li else if (Data.startswith("squeeze/sid") || Data[0] == '6')
3858*67e74705SXin Li return DebianSqueeze;
3859*67e74705SXin Li else if (Data.startswith("wheezy/sid") || Data[0] == '7')
3860*67e74705SXin Li return DebianWheezy;
3861*67e74705SXin Li else if (Data.startswith("jessie/sid") || Data[0] == '8')
3862*67e74705SXin Li return DebianJessie;
3863*67e74705SXin Li else if (Data.startswith("stretch/sid") || Data[0] == '9')
3864*67e74705SXin Li return DebianStretch;
3865*67e74705SXin Li return UnknownDistro;
3866*67e74705SXin Li }
3867*67e74705SXin Li
3868*67e74705SXin Li if (D.getVFS().exists("/etc/SuSE-release"))
3869*67e74705SXin Li return OpenSUSE;
3870*67e74705SXin Li
3871*67e74705SXin Li if (D.getVFS().exists("/etc/exherbo-release"))
3872*67e74705SXin Li return Exherbo;
3873*67e74705SXin Li
3874*67e74705SXin Li if (D.getVFS().exists("/etc/arch-release"))
3875*67e74705SXin Li return ArchLinux;
3876*67e74705SXin Li
3877*67e74705SXin Li return UnknownDistro;
3878*67e74705SXin Li }
3879*67e74705SXin Li
3880*67e74705SXin Li /// \brief Get our best guess at the multiarch triple for a target.
3881*67e74705SXin Li ///
3882*67e74705SXin Li /// Debian-based systems are starting to use a multiarch setup where they use
3883*67e74705SXin Li /// a target-triple directory in the library and header search paths.
3884*67e74705SXin Li /// Unfortunately, this triple does not align with the vanilla target triple,
3885*67e74705SXin Li /// so we provide a rough mapping here.
getMultiarchTriple(const Driver & D,const llvm::Triple & TargetTriple,StringRef SysRoot)3886*67e74705SXin Li static std::string getMultiarchTriple(const Driver &D,
3887*67e74705SXin Li const llvm::Triple &TargetTriple,
3888*67e74705SXin Li StringRef SysRoot) {
3889*67e74705SXin Li llvm::Triple::EnvironmentType TargetEnvironment =
3890*67e74705SXin Li TargetTriple.getEnvironment();
3891*67e74705SXin Li
3892*67e74705SXin Li // For most architectures, just use whatever we have rather than trying to be
3893*67e74705SXin Li // clever.
3894*67e74705SXin Li switch (TargetTriple.getArch()) {
3895*67e74705SXin Li default:
3896*67e74705SXin Li break;
3897*67e74705SXin Li
3898*67e74705SXin Li // We use the existence of '/lib/<triple>' as a directory to detect some
3899*67e74705SXin Li // common linux triples that don't quite match the Clang triple for both
3900*67e74705SXin Li // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
3901*67e74705SXin Li // regardless of what the actual target triple is.
3902*67e74705SXin Li case llvm::Triple::arm:
3903*67e74705SXin Li case llvm::Triple::thumb:
3904*67e74705SXin Li if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
3905*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
3906*67e74705SXin Li return "arm-linux-gnueabihf";
3907*67e74705SXin Li } else {
3908*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
3909*67e74705SXin Li return "arm-linux-gnueabi";
3910*67e74705SXin Li }
3911*67e74705SXin Li break;
3912*67e74705SXin Li case llvm::Triple::armeb:
3913*67e74705SXin Li case llvm::Triple::thumbeb:
3914*67e74705SXin Li if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
3915*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
3916*67e74705SXin Li return "armeb-linux-gnueabihf";
3917*67e74705SXin Li } else {
3918*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
3919*67e74705SXin Li return "armeb-linux-gnueabi";
3920*67e74705SXin Li }
3921*67e74705SXin Li break;
3922*67e74705SXin Li case llvm::Triple::x86:
3923*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
3924*67e74705SXin Li return "i386-linux-gnu";
3925*67e74705SXin Li break;
3926*67e74705SXin Li case llvm::Triple::x86_64:
3927*67e74705SXin Li // We don't want this for x32, otherwise it will match x86_64 libs
3928*67e74705SXin Li if (TargetEnvironment != llvm::Triple::GNUX32 &&
3929*67e74705SXin Li D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
3930*67e74705SXin Li return "x86_64-linux-gnu";
3931*67e74705SXin Li break;
3932*67e74705SXin Li case llvm::Triple::aarch64:
3933*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
3934*67e74705SXin Li return "aarch64-linux-gnu";
3935*67e74705SXin Li break;
3936*67e74705SXin Li case llvm::Triple::aarch64_be:
3937*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
3938*67e74705SXin Li return "aarch64_be-linux-gnu";
3939*67e74705SXin Li break;
3940*67e74705SXin Li case llvm::Triple::mips:
3941*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
3942*67e74705SXin Li return "mips-linux-gnu";
3943*67e74705SXin Li break;
3944*67e74705SXin Li case llvm::Triple::mipsel:
3945*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
3946*67e74705SXin Li return "mipsel-linux-gnu";
3947*67e74705SXin Li break;
3948*67e74705SXin Li case llvm::Triple::mips64:
3949*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
3950*67e74705SXin Li return "mips64-linux-gnu";
3951*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
3952*67e74705SXin Li return "mips64-linux-gnuabi64";
3953*67e74705SXin Li break;
3954*67e74705SXin Li case llvm::Triple::mips64el:
3955*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
3956*67e74705SXin Li return "mips64el-linux-gnu";
3957*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
3958*67e74705SXin Li return "mips64el-linux-gnuabi64";
3959*67e74705SXin Li break;
3960*67e74705SXin Li case llvm::Triple::ppc:
3961*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
3962*67e74705SXin Li return "powerpc-linux-gnuspe";
3963*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
3964*67e74705SXin Li return "powerpc-linux-gnu";
3965*67e74705SXin Li break;
3966*67e74705SXin Li case llvm::Triple::ppc64:
3967*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
3968*67e74705SXin Li return "powerpc64-linux-gnu";
3969*67e74705SXin Li break;
3970*67e74705SXin Li case llvm::Triple::ppc64le:
3971*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
3972*67e74705SXin Li return "powerpc64le-linux-gnu";
3973*67e74705SXin Li break;
3974*67e74705SXin Li case llvm::Triple::sparc:
3975*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
3976*67e74705SXin Li return "sparc-linux-gnu";
3977*67e74705SXin Li break;
3978*67e74705SXin Li case llvm::Triple::sparcv9:
3979*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
3980*67e74705SXin Li return "sparc64-linux-gnu";
3981*67e74705SXin Li break;
3982*67e74705SXin Li case llvm::Triple::systemz:
3983*67e74705SXin Li if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
3984*67e74705SXin Li return "s390x-linux-gnu";
3985*67e74705SXin Li break;
3986*67e74705SXin Li }
3987*67e74705SXin Li return TargetTriple.str();
3988*67e74705SXin Li }
3989*67e74705SXin Li
getOSLibDir(const llvm::Triple & Triple,const ArgList & Args)3990*67e74705SXin Li static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
3991*67e74705SXin Li if (isMipsArch(Triple.getArch())) {
3992*67e74705SXin Li if (Triple.isAndroid()) {
3993*67e74705SXin Li StringRef CPUName;
3994*67e74705SXin Li StringRef ABIName;
3995*67e74705SXin Li tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
3996*67e74705SXin Li if (CPUName == "mips32r6")
3997*67e74705SXin Li return "libr6";
3998*67e74705SXin Li if (CPUName == "mips32r2")
3999*67e74705SXin Li return "libr2";
4000*67e74705SXin Li }
4001*67e74705SXin Li // lib32 directory has a special meaning on MIPS targets.
4002*67e74705SXin Li // It contains N32 ABI binaries. Use this folder if produce
4003*67e74705SXin Li // code for N32 ABI only.
4004*67e74705SXin Li if (tools::mips::hasMipsAbiArg(Args, "n32"))
4005*67e74705SXin Li return "lib32";
4006*67e74705SXin Li return Triple.isArch32Bit() ? "lib" : "lib64";
4007*67e74705SXin Li }
4008*67e74705SXin Li
4009*67e74705SXin Li // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
4010*67e74705SXin Li // using that variant while targeting other architectures causes problems
4011*67e74705SXin Li // because the libraries are laid out in shared system roots that can't cope
4012*67e74705SXin Li // with a 'lib32' library search path being considered. So we only enable
4013*67e74705SXin Li // them when we know we may need it.
4014*67e74705SXin Li //
4015*67e74705SXin Li // FIXME: This is a bit of a hack. We should really unify this code for
4016*67e74705SXin Li // reasoning about oslibdir spellings with the lib dir spellings in the
4017*67e74705SXin Li // GCCInstallationDetector, but that is a more significant refactoring.
4018*67e74705SXin Li if (Triple.getArch() == llvm::Triple::x86 ||
4019*67e74705SXin Li Triple.getArch() == llvm::Triple::ppc)
4020*67e74705SXin Li return "lib32";
4021*67e74705SXin Li
4022*67e74705SXin Li if (Triple.getArch() == llvm::Triple::x86_64 &&
4023*67e74705SXin Li Triple.getEnvironment() == llvm::Triple::GNUX32)
4024*67e74705SXin Li return "libx32";
4025*67e74705SXin Li
4026*67e74705SXin Li return Triple.isArch32Bit() ? "lib" : "lib64";
4027*67e74705SXin Li }
4028*67e74705SXin Li
addMultilibsFilePaths(const Driver & D,const MultilibSet & Multilibs,const Multilib & Multilib,StringRef InstallPath,ToolChain::path_list & Paths)4029*67e74705SXin Li static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
4030*67e74705SXin Li const Multilib &Multilib,
4031*67e74705SXin Li StringRef InstallPath,
4032*67e74705SXin Li ToolChain::path_list &Paths) {
4033*67e74705SXin Li if (const auto &PathsCallback = Multilibs.filePathsCallback())
4034*67e74705SXin Li for (const auto &Path : PathsCallback(Multilib))
4035*67e74705SXin Li addPathIfExists(D, InstallPath + Path, Paths);
4036*67e74705SXin Li }
4037*67e74705SXin Li
Linux(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)4038*67e74705SXin Li Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
4039*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
4040*67e74705SXin Li GCCInstallation.init(Triple, Args);
4041*67e74705SXin Li CudaInstallation.init(Triple, Args);
4042*67e74705SXin Li Multilibs = GCCInstallation.getMultilibs();
4043*67e74705SXin Li llvm::Triple::ArchType Arch = Triple.getArch();
4044*67e74705SXin Li std::string SysRoot = computeSysRoot();
4045*67e74705SXin Li
4046*67e74705SXin Li // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
4047*67e74705SXin Li // least) put various tools in a triple-prefixed directory off of the parent
4048*67e74705SXin Li // of the GCC installation. We use the GCC triple here to ensure that we end
4049*67e74705SXin Li // up with tools that support the same amount of cross compiling as the
4050*67e74705SXin Li // detected GCC installation. For example, if we find a GCC installation
4051*67e74705SXin Li // targeting x86_64, but it is a bi-arch GCC installation, it can also be
4052*67e74705SXin Li // used to target i386.
4053*67e74705SXin Li // FIXME: This seems unlikely to be Linux-specific.
4054*67e74705SXin Li ToolChain::path_list &PPaths = getProgramPaths();
4055*67e74705SXin Li PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
4056*67e74705SXin Li GCCInstallation.getTriple().str() + "/bin")
4057*67e74705SXin Li .str());
4058*67e74705SXin Li
4059*67e74705SXin Li Distro Distro = DetectDistro(D, Arch);
4060*67e74705SXin Li
4061*67e74705SXin Li if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
4062*67e74705SXin Li ExtraOpts.push_back("-z");
4063*67e74705SXin Li ExtraOpts.push_back("relro");
4064*67e74705SXin Li }
4065*67e74705SXin Li
4066*67e74705SXin Li if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
4067*67e74705SXin Li ExtraOpts.push_back("-X");
4068*67e74705SXin Li
4069*67e74705SXin Li const bool IsAndroid = Triple.isAndroid();
4070*67e74705SXin Li const bool IsMips = isMipsArch(Arch);
4071*67e74705SXin Li
4072*67e74705SXin Li if (IsMips && !SysRoot.empty())
4073*67e74705SXin Li ExtraOpts.push_back("--sysroot=" + SysRoot);
4074*67e74705SXin Li
4075*67e74705SXin Li // Do not use 'gnu' hash style for Mips targets because .gnu.hash
4076*67e74705SXin Li // and the MIPS ABI require .dynsym to be sorted in different ways.
4077*67e74705SXin Li // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
4078*67e74705SXin Li // ABI requires a mapping between the GOT and the symbol table.
4079*67e74705SXin Li // Android loader does not support .gnu.hash.
4080*67e74705SXin Li if (!IsMips && !IsAndroid) {
4081*67e74705SXin Li if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
4082*67e74705SXin Li (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
4083*67e74705SXin Li ExtraOpts.push_back("--hash-style=gnu");
4084*67e74705SXin Li
4085*67e74705SXin Li if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
4086*67e74705SXin Li Distro == UbuntuJaunty || Distro == UbuntuKarmic)
4087*67e74705SXin Li ExtraOpts.push_back("--hash-style=both");
4088*67e74705SXin Li }
4089*67e74705SXin Li
4090*67e74705SXin Li if (IsRedhat(Distro) && Distro != RHEL5 && Distro != RHEL6)
4091*67e74705SXin Li ExtraOpts.push_back("--no-add-needed");
4092*67e74705SXin Li
4093*67e74705SXin Li #ifdef ENABLE_LINKER_BUILD_ID
4094*67e74705SXin Li ExtraOpts.push_back("--build-id");
4095*67e74705SXin Li #endif
4096*67e74705SXin Li
4097*67e74705SXin Li if (IsOpenSUSE(Distro))
4098*67e74705SXin Li ExtraOpts.push_back("--enable-new-dtags");
4099*67e74705SXin Li
4100*67e74705SXin Li // The selection of paths to try here is designed to match the patterns which
4101*67e74705SXin Li // the GCC driver itself uses, as this is part of the GCC-compatible driver.
4102*67e74705SXin Li // This was determined by running GCC in a fake filesystem, creating all
4103*67e74705SXin Li // possible permutations of these directories, and seeing which ones it added
4104*67e74705SXin Li // to the link paths.
4105*67e74705SXin Li path_list &Paths = getFilePaths();
4106*67e74705SXin Li
4107*67e74705SXin Li const std::string OSLibDir = getOSLibDir(Triple, Args);
4108*67e74705SXin Li const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
4109*67e74705SXin Li
4110*67e74705SXin Li // Add the multilib suffixed paths where they are available.
4111*67e74705SXin Li if (GCCInstallation.isValid()) {
4112*67e74705SXin Li const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
4113*67e74705SXin Li const std::string &LibPath = GCCInstallation.getParentLibPath();
4114*67e74705SXin Li const Multilib &Multilib = GCCInstallation.getMultilib();
4115*67e74705SXin Li const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
4116*67e74705SXin Li
4117*67e74705SXin Li // Add toolchain / multilib specific file paths.
4118*67e74705SXin Li addMultilibsFilePaths(D, Multilibs, Multilib,
4119*67e74705SXin Li GCCInstallation.getInstallPath(), Paths);
4120*67e74705SXin Li
4121*67e74705SXin Li // Sourcery CodeBench MIPS toolchain holds some libraries under
4122*67e74705SXin Li // a biarch-like suffix of the GCC installation.
4123*67e74705SXin Li addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
4124*67e74705SXin Li Paths);
4125*67e74705SXin Li
4126*67e74705SXin Li // GCC cross compiling toolchains will install target libraries which ship
4127*67e74705SXin Li // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
4128*67e74705SXin Li // any part of the GCC installation in
4129*67e74705SXin Li // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
4130*67e74705SXin Li // debatable, but is the reality today. We need to search this tree even
4131*67e74705SXin Li // when we have a sysroot somewhere else. It is the responsibility of
4132*67e74705SXin Li // whomever is doing the cross build targeting a sysroot using a GCC
4133*67e74705SXin Li // installation that is *not* within the system root to ensure two things:
4134*67e74705SXin Li //
4135*67e74705SXin Li // 1) Any DSOs that are linked in from this tree or from the install path
4136*67e74705SXin Li // above must be present on the system root and found via an
4137*67e74705SXin Li // appropriate rpath.
4138*67e74705SXin Li // 2) There must not be libraries installed into
4139*67e74705SXin Li // <prefix>/<triple>/<libdir> unless they should be preferred over
4140*67e74705SXin Li // those within the system root.
4141*67e74705SXin Li //
4142*67e74705SXin Li // Note that this matches the GCC behavior. See the below comment for where
4143*67e74705SXin Li // Clang diverges from GCC's behavior.
4144*67e74705SXin Li addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
4145*67e74705SXin Li OSLibDir + Multilib.osSuffix(),
4146*67e74705SXin Li Paths);
4147*67e74705SXin Li
4148*67e74705SXin Li // If the GCC installation we found is inside of the sysroot, we want to
4149*67e74705SXin Li // prefer libraries installed in the parent prefix of the GCC installation.
4150*67e74705SXin Li // It is important to *not* use these paths when the GCC installation is
4151*67e74705SXin Li // outside of the system root as that can pick up unintended libraries.
4152*67e74705SXin Li // This usually happens when there is an external cross compiler on the
4153*67e74705SXin Li // host system, and a more minimal sysroot available that is the target of
4154*67e74705SXin Li // the cross. Note that GCC does include some of these directories in some
4155*67e74705SXin Li // configurations but this seems somewhere between questionable and simply
4156*67e74705SXin Li // a bug.
4157*67e74705SXin Li if (StringRef(LibPath).startswith(SysRoot)) {
4158*67e74705SXin Li addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
4159*67e74705SXin Li addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
4160*67e74705SXin Li }
4161*67e74705SXin Li }
4162*67e74705SXin Li
4163*67e74705SXin Li // Similar to the logic for GCC above, if we currently running Clang inside
4164*67e74705SXin Li // of the requested system root, add its parent library paths to
4165*67e74705SXin Li // those searched.
4166*67e74705SXin Li // FIXME: It's not clear whether we should use the driver's installed
4167*67e74705SXin Li // directory ('Dir' below) or the ResourceDir.
4168*67e74705SXin Li if (StringRef(D.Dir).startswith(SysRoot)) {
4169*67e74705SXin Li addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
4170*67e74705SXin Li addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
4171*67e74705SXin Li }
4172*67e74705SXin Li
4173*67e74705SXin Li addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
4174*67e74705SXin Li addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
4175*67e74705SXin Li addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
4176*67e74705SXin Li addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
4177*67e74705SXin Li
4178*67e74705SXin Li // Try walking via the GCC triple path in case of biarch or multiarch GCC
4179*67e74705SXin Li // installations with strange symlinks.
4180*67e74705SXin Li if (GCCInstallation.isValid()) {
4181*67e74705SXin Li addPathIfExists(D,
4182*67e74705SXin Li SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
4183*67e74705SXin Li "/../../" + OSLibDir,
4184*67e74705SXin Li Paths);
4185*67e74705SXin Li
4186*67e74705SXin Li // Add the 'other' biarch variant path
4187*67e74705SXin Li Multilib BiarchSibling;
4188*67e74705SXin Li if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
4189*67e74705SXin Li addPathIfExists(D, GCCInstallation.getInstallPath() +
4190*67e74705SXin Li BiarchSibling.gccSuffix(),
4191*67e74705SXin Li Paths);
4192*67e74705SXin Li }
4193*67e74705SXin Li
4194*67e74705SXin Li // See comments above on the multilib variant for details of why this is
4195*67e74705SXin Li // included even from outside the sysroot.
4196*67e74705SXin Li const std::string &LibPath = GCCInstallation.getParentLibPath();
4197*67e74705SXin Li const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
4198*67e74705SXin Li const Multilib &Multilib = GCCInstallation.getMultilib();
4199*67e74705SXin Li addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
4200*67e74705SXin Li Multilib.osSuffix(),
4201*67e74705SXin Li Paths);
4202*67e74705SXin Li
4203*67e74705SXin Li // See comments above on the multilib variant for details of why this is
4204*67e74705SXin Li // only included from within the sysroot.
4205*67e74705SXin Li if (StringRef(LibPath).startswith(SysRoot))
4206*67e74705SXin Li addPathIfExists(D, LibPath, Paths);
4207*67e74705SXin Li }
4208*67e74705SXin Li
4209*67e74705SXin Li // Similar to the logic for GCC above, if we are currently running Clang
4210*67e74705SXin Li // inside of the requested system root, add its parent library path to those
4211*67e74705SXin Li // searched.
4212*67e74705SXin Li // FIXME: It's not clear whether we should use the driver's installed
4213*67e74705SXin Li // directory ('Dir' below) or the ResourceDir.
4214*67e74705SXin Li if (StringRef(D.Dir).startswith(SysRoot))
4215*67e74705SXin Li addPathIfExists(D, D.Dir + "/../lib", Paths);
4216*67e74705SXin Li
4217*67e74705SXin Li addPathIfExists(D, SysRoot + "/lib", Paths);
4218*67e74705SXin Li addPathIfExists(D, SysRoot + "/usr/lib", Paths);
4219*67e74705SXin Li }
4220*67e74705SXin Li
HasNativeLLVMSupport() const4221*67e74705SXin Li bool Linux::HasNativeLLVMSupport() const { return true; }
4222*67e74705SXin Li
buildLinker() const4223*67e74705SXin Li Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
4224*67e74705SXin Li
buildAssembler() const4225*67e74705SXin Li Tool *Linux::buildAssembler() const {
4226*67e74705SXin Li return new tools::gnutools::Assembler(*this);
4227*67e74705SXin Li }
4228*67e74705SXin Li
computeSysRoot() const4229*67e74705SXin Li std::string Linux::computeSysRoot() const {
4230*67e74705SXin Li if (!getDriver().SysRoot.empty())
4231*67e74705SXin Li return getDriver().SysRoot;
4232*67e74705SXin Li
4233*67e74705SXin Li if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
4234*67e74705SXin Li return std::string();
4235*67e74705SXin Li
4236*67e74705SXin Li // Standalone MIPS toolchains use different names for sysroot folder
4237*67e74705SXin Li // and put it into different places. Here we try to check some known
4238*67e74705SXin Li // variants.
4239*67e74705SXin Li
4240*67e74705SXin Li const StringRef InstallDir = GCCInstallation.getInstallPath();
4241*67e74705SXin Li const StringRef TripleStr = GCCInstallation.getTriple().str();
4242*67e74705SXin Li const Multilib &Multilib = GCCInstallation.getMultilib();
4243*67e74705SXin Li
4244*67e74705SXin Li std::string Path =
4245*67e74705SXin Li (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
4246*67e74705SXin Li .str();
4247*67e74705SXin Li
4248*67e74705SXin Li if (getVFS().exists(Path))
4249*67e74705SXin Li return Path;
4250*67e74705SXin Li
4251*67e74705SXin Li Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
4252*67e74705SXin Li
4253*67e74705SXin Li if (getVFS().exists(Path))
4254*67e74705SXin Li return Path;
4255*67e74705SXin Li
4256*67e74705SXin Li return std::string();
4257*67e74705SXin Li }
4258*67e74705SXin Li
getDynamicLinker(const ArgList & Args) const4259*67e74705SXin Li std::string Linux::getDynamicLinker(const ArgList &Args) const {
4260*67e74705SXin Li const llvm::Triple::ArchType Arch = getArch();
4261*67e74705SXin Li const llvm::Triple &Triple = getTriple();
4262*67e74705SXin Li
4263*67e74705SXin Li const enum Distro Distro = DetectDistro(getDriver(), Arch);
4264*67e74705SXin Li
4265*67e74705SXin Li if (Triple.isAndroid())
4266*67e74705SXin Li return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
4267*67e74705SXin Li else if (Triple.isMusl()) {
4268*67e74705SXin Li std::string ArchName;
4269*67e74705SXin Li switch (Arch) {
4270*67e74705SXin Li case llvm::Triple::thumb:
4271*67e74705SXin Li ArchName = "arm";
4272*67e74705SXin Li break;
4273*67e74705SXin Li case llvm::Triple::thumbeb:
4274*67e74705SXin Li ArchName = "armeb";
4275*67e74705SXin Li break;
4276*67e74705SXin Li default:
4277*67e74705SXin Li ArchName = Triple.getArchName().str();
4278*67e74705SXin Li }
4279*67e74705SXin Li if (Triple.getEnvironment() == llvm::Triple::MuslEABIHF)
4280*67e74705SXin Li ArchName += "hf";
4281*67e74705SXin Li
4282*67e74705SXin Li return "/lib/ld-musl-" + ArchName + ".so.1";
4283*67e74705SXin Li }
4284*67e74705SXin Li
4285*67e74705SXin Li std::string LibDir;
4286*67e74705SXin Li std::string Loader;
4287*67e74705SXin Li
4288*67e74705SXin Li switch (Arch) {
4289*67e74705SXin Li default:
4290*67e74705SXin Li llvm_unreachable("unsupported architecture");
4291*67e74705SXin Li
4292*67e74705SXin Li case llvm::Triple::aarch64:
4293*67e74705SXin Li LibDir = "lib";
4294*67e74705SXin Li Loader = "ld-linux-aarch64.so.1";
4295*67e74705SXin Li break;
4296*67e74705SXin Li case llvm::Triple::aarch64_be:
4297*67e74705SXin Li LibDir = "lib";
4298*67e74705SXin Li Loader = "ld-linux-aarch64_be.so.1";
4299*67e74705SXin Li break;
4300*67e74705SXin Li case llvm::Triple::arm:
4301*67e74705SXin Li case llvm::Triple::thumb:
4302*67e74705SXin Li case llvm::Triple::armeb:
4303*67e74705SXin Li case llvm::Triple::thumbeb: {
4304*67e74705SXin Li const bool HF =
4305*67e74705SXin Li Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
4306*67e74705SXin Li tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
4307*67e74705SXin Li
4308*67e74705SXin Li LibDir = "lib";
4309*67e74705SXin Li Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
4310*67e74705SXin Li break;
4311*67e74705SXin Li }
4312*67e74705SXin Li case llvm::Triple::mips:
4313*67e74705SXin Li case llvm::Triple::mipsel:
4314*67e74705SXin Li case llvm::Triple::mips64:
4315*67e74705SXin Li case llvm::Triple::mips64el: {
4316*67e74705SXin Li bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
4317*67e74705SXin Li (Triple.getArch() == llvm::Triple::mips64el);
4318*67e74705SXin Li bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
4319*67e74705SXin Li
4320*67e74705SXin Li LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
4321*67e74705SXin Li
4322*67e74705SXin Li if (tools::mips::isUCLibc(Args))
4323*67e74705SXin Li Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
4324*67e74705SXin Li else if (!Triple.hasEnvironment() &&
4325*67e74705SXin Li Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
4326*67e74705SXin Li Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
4327*67e74705SXin Li else
4328*67e74705SXin Li Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
4329*67e74705SXin Li
4330*67e74705SXin Li break;
4331*67e74705SXin Li }
4332*67e74705SXin Li case llvm::Triple::ppc:
4333*67e74705SXin Li LibDir = "lib";
4334*67e74705SXin Li Loader = "ld.so.1";
4335*67e74705SXin Li break;
4336*67e74705SXin Li case llvm::Triple::ppc64:
4337*67e74705SXin Li LibDir = "lib64";
4338*67e74705SXin Li Loader =
4339*67e74705SXin Li (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
4340*67e74705SXin Li break;
4341*67e74705SXin Li case llvm::Triple::ppc64le:
4342*67e74705SXin Li LibDir = "lib64";
4343*67e74705SXin Li Loader =
4344*67e74705SXin Li (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
4345*67e74705SXin Li break;
4346*67e74705SXin Li case llvm::Triple::sparc:
4347*67e74705SXin Li case llvm::Triple::sparcel:
4348*67e74705SXin Li LibDir = "lib";
4349*67e74705SXin Li Loader = "ld-linux.so.2";
4350*67e74705SXin Li break;
4351*67e74705SXin Li case llvm::Triple::sparcv9:
4352*67e74705SXin Li LibDir = "lib64";
4353*67e74705SXin Li Loader = "ld-linux.so.2";
4354*67e74705SXin Li break;
4355*67e74705SXin Li case llvm::Triple::systemz:
4356*67e74705SXin Li LibDir = "lib";
4357*67e74705SXin Li Loader = "ld64.so.1";
4358*67e74705SXin Li break;
4359*67e74705SXin Li case llvm::Triple::x86:
4360*67e74705SXin Li LibDir = "lib";
4361*67e74705SXin Li Loader = "ld-linux.so.2";
4362*67e74705SXin Li break;
4363*67e74705SXin Li case llvm::Triple::x86_64: {
4364*67e74705SXin Li bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
4365*67e74705SXin Li
4366*67e74705SXin Li LibDir = X32 ? "libx32" : "lib64";
4367*67e74705SXin Li Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
4368*67e74705SXin Li break;
4369*67e74705SXin Li }
4370*67e74705SXin Li }
4371*67e74705SXin Li
4372*67e74705SXin Li if (Distro == Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
4373*67e74705SXin Li Triple.getVendor() == llvm::Triple::PC))
4374*67e74705SXin Li return "/usr/" + Triple.str() + "/lib/" + Loader;
4375*67e74705SXin Li return "/" + LibDir + "/" + Loader;
4376*67e74705SXin Li }
4377*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4378*67e74705SXin Li void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4379*67e74705SXin Li ArgStringList &CC1Args) const {
4380*67e74705SXin Li const Driver &D = getDriver();
4381*67e74705SXin Li std::string SysRoot = computeSysRoot();
4382*67e74705SXin Li
4383*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc))
4384*67e74705SXin Li return;
4385*67e74705SXin Li
4386*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
4387*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
4388*67e74705SXin Li
4389*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
4390*67e74705SXin Li SmallString<128> P(D.ResourceDir);
4391*67e74705SXin Li llvm::sys::path::append(P, "include");
4392*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, P);
4393*67e74705SXin Li }
4394*67e74705SXin Li
4395*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc))
4396*67e74705SXin Li return;
4397*67e74705SXin Li
4398*67e74705SXin Li // Check for configure-time C include directories.
4399*67e74705SXin Li StringRef CIncludeDirs(C_INCLUDE_DIRS);
4400*67e74705SXin Li if (CIncludeDirs != "") {
4401*67e74705SXin Li SmallVector<StringRef, 5> dirs;
4402*67e74705SXin Li CIncludeDirs.split(dirs, ":");
4403*67e74705SXin Li for (StringRef dir : dirs) {
4404*67e74705SXin Li StringRef Prefix =
4405*67e74705SXin Li llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
4406*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
4407*67e74705SXin Li }
4408*67e74705SXin Li return;
4409*67e74705SXin Li }
4410*67e74705SXin Li
4411*67e74705SXin Li // Lacking those, try to detect the correct set of system includes for the
4412*67e74705SXin Li // target triple.
4413*67e74705SXin Li
4414*67e74705SXin Li // Add include directories specific to the selected multilib set and multilib.
4415*67e74705SXin Li if (GCCInstallation.isValid()) {
4416*67e74705SXin Li const auto &Callback = Multilibs.includeDirsCallback();
4417*67e74705SXin Li if (Callback) {
4418*67e74705SXin Li for (const auto &Path : Callback(GCCInstallation.getMultilib()))
4419*67e74705SXin Li addExternCSystemIncludeIfExists(
4420*67e74705SXin Li DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
4421*67e74705SXin Li }
4422*67e74705SXin Li }
4423*67e74705SXin Li
4424*67e74705SXin Li // Implement generic Debian multiarch support.
4425*67e74705SXin Li const StringRef X86_64MultiarchIncludeDirs[] = {
4426*67e74705SXin Li "/usr/include/x86_64-linux-gnu",
4427*67e74705SXin Li
4428*67e74705SXin Li // FIXME: These are older forms of multiarch. It's not clear that they're
4429*67e74705SXin Li // in use in any released version of Debian, so we should consider
4430*67e74705SXin Li // removing them.
4431*67e74705SXin Li "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
4432*67e74705SXin Li const StringRef X86MultiarchIncludeDirs[] = {
4433*67e74705SXin Li "/usr/include/i386-linux-gnu",
4434*67e74705SXin Li
4435*67e74705SXin Li // FIXME: These are older forms of multiarch. It's not clear that they're
4436*67e74705SXin Li // in use in any released version of Debian, so we should consider
4437*67e74705SXin Li // removing them.
4438*67e74705SXin Li "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
4439*67e74705SXin Li "/usr/include/i486-linux-gnu"};
4440*67e74705SXin Li const StringRef AArch64MultiarchIncludeDirs[] = {
4441*67e74705SXin Li "/usr/include/aarch64-linux-gnu"};
4442*67e74705SXin Li const StringRef ARMMultiarchIncludeDirs[] = {
4443*67e74705SXin Li "/usr/include/arm-linux-gnueabi"};
4444*67e74705SXin Li const StringRef ARMHFMultiarchIncludeDirs[] = {
4445*67e74705SXin Li "/usr/include/arm-linux-gnueabihf"};
4446*67e74705SXin Li const StringRef ARMEBMultiarchIncludeDirs[] = {
4447*67e74705SXin Li "/usr/include/armeb-linux-gnueabi"};
4448*67e74705SXin Li const StringRef ARMEBHFMultiarchIncludeDirs[] = {
4449*67e74705SXin Li "/usr/include/armeb-linux-gnueabihf"};
4450*67e74705SXin Li const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
4451*67e74705SXin Li const StringRef MIPSELMultiarchIncludeDirs[] = {
4452*67e74705SXin Li "/usr/include/mipsel-linux-gnu"};
4453*67e74705SXin Li const StringRef MIPS64MultiarchIncludeDirs[] = {
4454*67e74705SXin Li "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
4455*67e74705SXin Li const StringRef MIPS64ELMultiarchIncludeDirs[] = {
4456*67e74705SXin Li "/usr/include/mips64el-linux-gnu",
4457*67e74705SXin Li "/usr/include/mips64el-linux-gnuabi64"};
4458*67e74705SXin Li const StringRef PPCMultiarchIncludeDirs[] = {
4459*67e74705SXin Li "/usr/include/powerpc-linux-gnu"};
4460*67e74705SXin Li const StringRef PPC64MultiarchIncludeDirs[] = {
4461*67e74705SXin Li "/usr/include/powerpc64-linux-gnu"};
4462*67e74705SXin Li const StringRef PPC64LEMultiarchIncludeDirs[] = {
4463*67e74705SXin Li "/usr/include/powerpc64le-linux-gnu"};
4464*67e74705SXin Li const StringRef SparcMultiarchIncludeDirs[] = {
4465*67e74705SXin Li "/usr/include/sparc-linux-gnu"};
4466*67e74705SXin Li const StringRef Sparc64MultiarchIncludeDirs[] = {
4467*67e74705SXin Li "/usr/include/sparc64-linux-gnu"};
4468*67e74705SXin Li const StringRef SYSTEMZMultiarchIncludeDirs[] = {
4469*67e74705SXin Li "/usr/include/s390x-linux-gnu"};
4470*67e74705SXin Li ArrayRef<StringRef> MultiarchIncludeDirs;
4471*67e74705SXin Li switch (getTriple().getArch()) {
4472*67e74705SXin Li case llvm::Triple::x86_64:
4473*67e74705SXin Li MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
4474*67e74705SXin Li break;
4475*67e74705SXin Li case llvm::Triple::x86:
4476*67e74705SXin Li MultiarchIncludeDirs = X86MultiarchIncludeDirs;
4477*67e74705SXin Li break;
4478*67e74705SXin Li case llvm::Triple::aarch64:
4479*67e74705SXin Li case llvm::Triple::aarch64_be:
4480*67e74705SXin Li MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
4481*67e74705SXin Li break;
4482*67e74705SXin Li case llvm::Triple::arm:
4483*67e74705SXin Li case llvm::Triple::thumb:
4484*67e74705SXin Li if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4485*67e74705SXin Li MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
4486*67e74705SXin Li else
4487*67e74705SXin Li MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
4488*67e74705SXin Li break;
4489*67e74705SXin Li case llvm::Triple::armeb:
4490*67e74705SXin Li case llvm::Triple::thumbeb:
4491*67e74705SXin Li if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4492*67e74705SXin Li MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
4493*67e74705SXin Li else
4494*67e74705SXin Li MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
4495*67e74705SXin Li break;
4496*67e74705SXin Li case llvm::Triple::mips:
4497*67e74705SXin Li MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
4498*67e74705SXin Li break;
4499*67e74705SXin Li case llvm::Triple::mipsel:
4500*67e74705SXin Li MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
4501*67e74705SXin Li break;
4502*67e74705SXin Li case llvm::Triple::mips64:
4503*67e74705SXin Li MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
4504*67e74705SXin Li break;
4505*67e74705SXin Li case llvm::Triple::mips64el:
4506*67e74705SXin Li MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
4507*67e74705SXin Li break;
4508*67e74705SXin Li case llvm::Triple::ppc:
4509*67e74705SXin Li MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
4510*67e74705SXin Li break;
4511*67e74705SXin Li case llvm::Triple::ppc64:
4512*67e74705SXin Li MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
4513*67e74705SXin Li break;
4514*67e74705SXin Li case llvm::Triple::ppc64le:
4515*67e74705SXin Li MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
4516*67e74705SXin Li break;
4517*67e74705SXin Li case llvm::Triple::sparc:
4518*67e74705SXin Li MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
4519*67e74705SXin Li break;
4520*67e74705SXin Li case llvm::Triple::sparcv9:
4521*67e74705SXin Li MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
4522*67e74705SXin Li break;
4523*67e74705SXin Li case llvm::Triple::systemz:
4524*67e74705SXin Li MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
4525*67e74705SXin Li break;
4526*67e74705SXin Li default:
4527*67e74705SXin Li break;
4528*67e74705SXin Li }
4529*67e74705SXin Li for (StringRef Dir : MultiarchIncludeDirs) {
4530*67e74705SXin Li if (D.getVFS().exists(SysRoot + Dir)) {
4531*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
4532*67e74705SXin Li break;
4533*67e74705SXin Li }
4534*67e74705SXin Li }
4535*67e74705SXin Li
4536*67e74705SXin Li if (getTriple().getOS() == llvm::Triple::RTEMS)
4537*67e74705SXin Li return;
4538*67e74705SXin Li
4539*67e74705SXin Li // Add an include of '/include' directly. This isn't provided by default by
4540*67e74705SXin Li // system GCCs, but is often used with cross-compiling GCCs, and harmless to
4541*67e74705SXin Li // add even when Clang is acting as-if it were a system compiler.
4542*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
4543*67e74705SXin Li
4544*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
4545*67e74705SXin Li }
4546*67e74705SXin Li
DetectLibcxxIncludePath(StringRef base)4547*67e74705SXin Li static std::string DetectLibcxxIncludePath(StringRef base) {
4548*67e74705SXin Li std::error_code EC;
4549*67e74705SXin Li int MaxVersion = 0;
4550*67e74705SXin Li std::string MaxVersionString = "";
4551*67e74705SXin Li for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
4552*67e74705SXin Li LI = LI.increment(EC)) {
4553*67e74705SXin Li StringRef VersionText = llvm::sys::path::filename(LI->path());
4554*67e74705SXin Li int Version;
4555*67e74705SXin Li if (VersionText[0] == 'v' &&
4556*67e74705SXin Li !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
4557*67e74705SXin Li if (Version > MaxVersion) {
4558*67e74705SXin Li MaxVersion = Version;
4559*67e74705SXin Li MaxVersionString = VersionText;
4560*67e74705SXin Li }
4561*67e74705SXin Li }
4562*67e74705SXin Li }
4563*67e74705SXin Li return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
4564*67e74705SXin Li }
4565*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4566*67e74705SXin Li void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
4567*67e74705SXin Li ArgStringList &CC1Args) const {
4568*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4569*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
4570*67e74705SXin Li return;
4571*67e74705SXin Li
4572*67e74705SXin Li // Check if libc++ has been enabled and provide its include paths if so.
4573*67e74705SXin Li if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
4574*67e74705SXin Li const std::string LibCXXIncludePathCandidates[] = {
4575*67e74705SXin Li DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
4576*67e74705SXin Li // If this is a development, non-installed, clang, libcxx will
4577*67e74705SXin Li // not be found at ../include/c++ but it likely to be found at
4578*67e74705SXin Li // one of the following two locations:
4579*67e74705SXin Li DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
4580*67e74705SXin Li DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
4581*67e74705SXin Li for (const auto &IncludePath : LibCXXIncludePathCandidates) {
4582*67e74705SXin Li if (IncludePath.empty() || !getVFS().exists(IncludePath))
4583*67e74705SXin Li continue;
4584*67e74705SXin Li // Add the first candidate that exists.
4585*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, IncludePath);
4586*67e74705SXin Li break;
4587*67e74705SXin Li }
4588*67e74705SXin Li return;
4589*67e74705SXin Li }
4590*67e74705SXin Li
4591*67e74705SXin Li // We need a detected GCC installation on Linux to provide libstdc++'s
4592*67e74705SXin Li // headers. We handled the libc++ case above.
4593*67e74705SXin Li if (!GCCInstallation.isValid())
4594*67e74705SXin Li return;
4595*67e74705SXin Li
4596*67e74705SXin Li // By default, look for the C++ headers in an include directory adjacent to
4597*67e74705SXin Li // the lib directory of the GCC installation. Note that this is expect to be
4598*67e74705SXin Li // equivalent to '/usr/include/c++/X.Y' in almost all cases.
4599*67e74705SXin Li StringRef LibDir = GCCInstallation.getParentLibPath();
4600*67e74705SXin Li StringRef InstallDir = GCCInstallation.getInstallPath();
4601*67e74705SXin Li StringRef TripleStr = GCCInstallation.getTriple().str();
4602*67e74705SXin Li const Multilib &Multilib = GCCInstallation.getMultilib();
4603*67e74705SXin Li const std::string GCCMultiarchTriple = getMultiarchTriple(
4604*67e74705SXin Li getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
4605*67e74705SXin Li const std::string TargetMultiarchTriple =
4606*67e74705SXin Li getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
4607*67e74705SXin Li const GCCVersion &Version = GCCInstallation.getVersion();
4608*67e74705SXin Li
4609*67e74705SXin Li // The primary search for libstdc++ supports multiarch variants.
4610*67e74705SXin Li if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
4611*67e74705SXin Li "/c++/" + Version.Text, TripleStr,
4612*67e74705SXin Li GCCMultiarchTriple, TargetMultiarchTriple,
4613*67e74705SXin Li Multilib.includeSuffix(), DriverArgs, CC1Args))
4614*67e74705SXin Li return;
4615*67e74705SXin Li
4616*67e74705SXin Li // Otherwise, fall back on a bunch of options which don't use multiarch
4617*67e74705SXin Li // layouts for simplicity.
4618*67e74705SXin Li const std::string LibStdCXXIncludePathCandidates[] = {
4619*67e74705SXin Li // Gentoo is weird and places its headers inside the GCC install,
4620*67e74705SXin Li // so if the first attempt to find the headers fails, try these patterns.
4621*67e74705SXin Li InstallDir.str() + "/include/g++-v" + Version.Text,
4622*67e74705SXin Li InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
4623*67e74705SXin Li Version.MinorStr,
4624*67e74705SXin Li InstallDir.str() + "/include/g++-v" + Version.MajorStr,
4625*67e74705SXin Li // Android standalone toolchain has C++ headers in yet another place.
4626*67e74705SXin Li LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4627*67e74705SXin Li // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
4628*67e74705SXin Li // without a subdirectory corresponding to the gcc version.
4629*67e74705SXin Li LibDir.str() + "/../include/c++",
4630*67e74705SXin Li };
4631*67e74705SXin Li
4632*67e74705SXin Li for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
4633*67e74705SXin Li if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
4634*67e74705SXin Li /*GCCMultiarchTriple*/ "",
4635*67e74705SXin Li /*TargetMultiarchTriple*/ "",
4636*67e74705SXin Li Multilib.includeSuffix(), DriverArgs, CC1Args))
4637*67e74705SXin Li break;
4638*67e74705SXin Li }
4639*67e74705SXin Li }
4640*67e74705SXin Li
AddCudaIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4641*67e74705SXin Li void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
4642*67e74705SXin Li ArgStringList &CC1Args) const {
4643*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nocudainc))
4644*67e74705SXin Li return;
4645*67e74705SXin Li
4646*67e74705SXin Li if (!CudaInstallation.isValid()) {
4647*67e74705SXin Li getDriver().Diag(diag::err_drv_no_cuda_installation);
4648*67e74705SXin Li return;
4649*67e74705SXin Li }
4650*67e74705SXin Li
4651*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, CudaInstallation.getIncludePath());
4652*67e74705SXin Li CC1Args.push_back("-include");
4653*67e74705SXin Li CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
4654*67e74705SXin Li }
4655*67e74705SXin Li
AddIAMCUIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4656*67e74705SXin Li void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
4657*67e74705SXin Li ArgStringList &CC1Args) const {
4658*67e74705SXin Li if (GCCInstallation.isValid()) {
4659*67e74705SXin Li CC1Args.push_back("-isystem");
4660*67e74705SXin Li CC1Args.push_back(DriverArgs.MakeArgString(
4661*67e74705SXin Li GCCInstallation.getParentLibPath() + "/../" +
4662*67e74705SXin Li GCCInstallation.getTriple().str() + "/include"));
4663*67e74705SXin Li }
4664*67e74705SXin Li }
4665*67e74705SXin Li
isPIEDefault() const4666*67e74705SXin Li bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
4667*67e74705SXin Li
getSupportedSanitizers() const4668*67e74705SXin Li SanitizerMask Linux::getSupportedSanitizers() const {
4669*67e74705SXin Li const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
4670*67e74705SXin Li const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
4671*67e74705SXin Li const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
4672*67e74705SXin Li getTriple().getArch() == llvm::Triple::mips64el;
4673*67e74705SXin Li const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
4674*67e74705SXin Li getTriple().getArch() == llvm::Triple::ppc64le;
4675*67e74705SXin Li const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
4676*67e74705SXin Li getTriple().getArch() == llvm::Triple::aarch64_be;
4677*67e74705SXin Li SanitizerMask Res = ToolChain::getSupportedSanitizers();
4678*67e74705SXin Li Res |= SanitizerKind::Address;
4679*67e74705SXin Li Res |= SanitizerKind::KernelAddress;
4680*67e74705SXin Li Res |= SanitizerKind::Vptr;
4681*67e74705SXin Li Res |= SanitizerKind::SafeStack;
4682*67e74705SXin Li if (IsX86_64 || IsMIPS64 || IsAArch64)
4683*67e74705SXin Li Res |= SanitizerKind::DataFlow;
4684*67e74705SXin Li if (IsX86_64 || IsMIPS64 || IsAArch64)
4685*67e74705SXin Li Res |= SanitizerKind::Leak;
4686*67e74705SXin Li if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
4687*67e74705SXin Li Res |= SanitizerKind::Thread;
4688*67e74705SXin Li if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
4689*67e74705SXin Li Res |= SanitizerKind::Memory;
4690*67e74705SXin Li if (IsX86_64)
4691*67e74705SXin Li Res |= SanitizerKind::Efficiency;
4692*67e74705SXin Li if (IsX86 || IsX86_64) {
4693*67e74705SXin Li Res |= SanitizerKind::Function;
4694*67e74705SXin Li }
4695*67e74705SXin Li return Res;
4696*67e74705SXin Li }
4697*67e74705SXin Li
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const4698*67e74705SXin Li void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
4699*67e74705SXin Li llvm::opt::ArgStringList &CmdArgs) const {
4700*67e74705SXin Li if (!needsProfileRT(Args)) return;
4701*67e74705SXin Li
4702*67e74705SXin Li // Add linker option -u__llvm_runtime_variable to cause runtime
4703*67e74705SXin Li // initialization module to be linked in.
4704*67e74705SXin Li if (!Args.hasArg(options::OPT_coverage))
4705*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(
4706*67e74705SXin Li Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
4707*67e74705SXin Li ToolChain::addProfileRTLibs(Args, CmdArgs);
4708*67e74705SXin Li }
4709*67e74705SXin Li
4710*67e74705SXin Li /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
4711*67e74705SXin Li
DragonFly(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)4712*67e74705SXin Li DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
4713*67e74705SXin Li const ArgList &Args)
4714*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
4715*67e74705SXin Li
4716*67e74705SXin Li // Path mangling to find libexec
4717*67e74705SXin Li getProgramPaths().push_back(getDriver().getInstalledDir());
4718*67e74705SXin Li if (getDriver().getInstalledDir() != getDriver().Dir)
4719*67e74705SXin Li getProgramPaths().push_back(getDriver().Dir);
4720*67e74705SXin Li
4721*67e74705SXin Li getFilePaths().push_back(getDriver().Dir + "/../lib");
4722*67e74705SXin Li getFilePaths().push_back("/usr/lib");
4723*67e74705SXin Li getFilePaths().push_back("/usr/lib/gcc50");
4724*67e74705SXin Li }
4725*67e74705SXin Li
buildAssembler() const4726*67e74705SXin Li Tool *DragonFly::buildAssembler() const {
4727*67e74705SXin Li return new tools::dragonfly::Assembler(*this);
4728*67e74705SXin Li }
4729*67e74705SXin Li
buildLinker() const4730*67e74705SXin Li Tool *DragonFly::buildLinker() const {
4731*67e74705SXin Li return new tools::dragonfly::Linker(*this);
4732*67e74705SXin Li }
4733*67e74705SXin Li
4734*67e74705SXin Li /// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary,
4735*67e74705SXin Li /// which isn't properly a linker but nonetheless performs the step of stitching
4736*67e74705SXin Li /// together object files from the assembler into a single blob.
4737*67e74705SXin Li
CudaToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)4738*67e74705SXin Li CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
4739*67e74705SXin Li const ArgList &Args)
4740*67e74705SXin Li : Linux(D, Triple, Args) {
4741*67e74705SXin Li if (CudaInstallation.isValid())
4742*67e74705SXin Li getProgramPaths().push_back(CudaInstallation.getBinPath());
4743*67e74705SXin Li }
4744*67e74705SXin Li
4745*67e74705SXin Li void
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const4746*67e74705SXin Li CudaToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
4747*67e74705SXin Li llvm::opt::ArgStringList &CC1Args) const {
4748*67e74705SXin Li Linux::addClangTargetOptions(DriverArgs, CC1Args);
4749*67e74705SXin Li CC1Args.push_back("-fcuda-is-device");
4750*67e74705SXin Li
4751*67e74705SXin Li if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
4752*67e74705SXin Li options::OPT_fno_cuda_flush_denormals_to_zero, false))
4753*67e74705SXin Li CC1Args.push_back("-fcuda-flush-denormals-to-zero");
4754*67e74705SXin Li
4755*67e74705SXin Li if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
4756*67e74705SXin Li options::OPT_fno_cuda_approx_transcendentals, false))
4757*67e74705SXin Li CC1Args.push_back("-fcuda-approx-transcendentals");
4758*67e74705SXin Li
4759*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nocudalib))
4760*67e74705SXin Li return;
4761*67e74705SXin Li
4762*67e74705SXin Li std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(
4763*67e74705SXin Li DriverArgs.getLastArgValue(options::OPT_march_EQ));
4764*67e74705SXin Li if (!LibDeviceFile.empty()) {
4765*67e74705SXin Li CC1Args.push_back("-mlink-cuda-bitcode");
4766*67e74705SXin Li CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
4767*67e74705SXin Li
4768*67e74705SXin Li // Libdevice in CUDA-7.0 requires PTX version that's more recent
4769*67e74705SXin Li // than LLVM defaults to. Use PTX4.2 which is the PTX version that
4770*67e74705SXin Li // came with CUDA-7.0.
4771*67e74705SXin Li CC1Args.push_back("-target-feature");
4772*67e74705SXin Li CC1Args.push_back("+ptx42");
4773*67e74705SXin Li }
4774*67e74705SXin Li }
4775*67e74705SXin Li
AddCudaIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4776*67e74705SXin Li void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
4777*67e74705SXin Li ArgStringList &CC1Args) const {
4778*67e74705SXin Li // Check our CUDA version if we're going to include the CUDA headers.
4779*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
4780*67e74705SXin Li !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
4781*67e74705SXin Li StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
4782*67e74705SXin Li assert(!Arch.empty() && "Must have an explicit GPU arch.");
4783*67e74705SXin Li CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
4784*67e74705SXin Li }
4785*67e74705SXin Li Linux::AddCudaIncludeArgs(DriverArgs, CC1Args);
4786*67e74705SXin Li }
4787*67e74705SXin Li
4788*67e74705SXin Li llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList & Args,const char * BoundArch) const4789*67e74705SXin Li CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
4790*67e74705SXin Li const char *BoundArch) const {
4791*67e74705SXin Li DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
4792*67e74705SXin Li const OptTable &Opts = getDriver().getOpts();
4793*67e74705SXin Li
4794*67e74705SXin Li for (Arg *A : Args) {
4795*67e74705SXin Li if (A->getOption().matches(options::OPT_Xarch__)) {
4796*67e74705SXin Li // Skip this argument unless the architecture matches BoundArch
4797*67e74705SXin Li if (!BoundArch || A->getValue(0) != StringRef(BoundArch))
4798*67e74705SXin Li continue;
4799*67e74705SXin Li
4800*67e74705SXin Li unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
4801*67e74705SXin Li unsigned Prev = Index;
4802*67e74705SXin Li std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
4803*67e74705SXin Li
4804*67e74705SXin Li // If the argument parsing failed or more than one argument was
4805*67e74705SXin Li // consumed, the -Xarch_ argument's parameter tried to consume
4806*67e74705SXin Li // extra arguments. Emit an error and ignore.
4807*67e74705SXin Li //
4808*67e74705SXin Li // We also want to disallow any options which would alter the
4809*67e74705SXin Li // driver behavior; that isn't going to work in our model. We
4810*67e74705SXin Li // use isDriverOption() as an approximation, although things
4811*67e74705SXin Li // like -O4 are going to slip through.
4812*67e74705SXin Li if (!XarchArg || Index > Prev + 1) {
4813*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
4814*67e74705SXin Li << A->getAsString(Args);
4815*67e74705SXin Li continue;
4816*67e74705SXin Li } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
4817*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
4818*67e74705SXin Li << A->getAsString(Args);
4819*67e74705SXin Li continue;
4820*67e74705SXin Li }
4821*67e74705SXin Li XarchArg->setBaseArg(A);
4822*67e74705SXin Li A = XarchArg.release();
4823*67e74705SXin Li DAL->AddSynthesizedArg(A);
4824*67e74705SXin Li }
4825*67e74705SXin Li DAL->append(A);
4826*67e74705SXin Li }
4827*67e74705SXin Li
4828*67e74705SXin Li if (BoundArch) {
4829*67e74705SXin Li DAL->eraseArg(options::OPT_march_EQ);
4830*67e74705SXin Li DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
4831*67e74705SXin Li }
4832*67e74705SXin Li return DAL;
4833*67e74705SXin Li }
4834*67e74705SXin Li
buildAssembler() const4835*67e74705SXin Li Tool *CudaToolChain::buildAssembler() const {
4836*67e74705SXin Li return new tools::NVPTX::Assembler(*this);
4837*67e74705SXin Li }
4838*67e74705SXin Li
buildLinker() const4839*67e74705SXin Li Tool *CudaToolChain::buildLinker() const {
4840*67e74705SXin Li return new tools::NVPTX::Linker(*this);
4841*67e74705SXin Li }
4842*67e74705SXin Li
4843*67e74705SXin Li /// XCore tool chain
XCoreToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)4844*67e74705SXin Li XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
4845*67e74705SXin Li const ArgList &Args)
4846*67e74705SXin Li : ToolChain(D, Triple, Args) {
4847*67e74705SXin Li // ProgramPaths are found via 'PATH' environment variable.
4848*67e74705SXin Li }
4849*67e74705SXin Li
buildAssembler() const4850*67e74705SXin Li Tool *XCoreToolChain::buildAssembler() const {
4851*67e74705SXin Li return new tools::XCore::Assembler(*this);
4852*67e74705SXin Li }
4853*67e74705SXin Li
buildLinker() const4854*67e74705SXin Li Tool *XCoreToolChain::buildLinker() const {
4855*67e74705SXin Li return new tools::XCore::Linker(*this);
4856*67e74705SXin Li }
4857*67e74705SXin Li
isPICDefault() const4858*67e74705SXin Li bool XCoreToolChain::isPICDefault() const { return false; }
4859*67e74705SXin Li
isPIEDefault() const4860*67e74705SXin Li bool XCoreToolChain::isPIEDefault() const { return false; }
4861*67e74705SXin Li
isPICDefaultForced() const4862*67e74705SXin Li bool XCoreToolChain::isPICDefaultForced() const { return false; }
4863*67e74705SXin Li
SupportsProfiling() const4864*67e74705SXin Li bool XCoreToolChain::SupportsProfiling() const { return false; }
4865*67e74705SXin Li
hasBlocksRuntime() const4866*67e74705SXin Li bool XCoreToolChain::hasBlocksRuntime() const { return false; }
4867*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4868*67e74705SXin Li void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4869*67e74705SXin Li ArgStringList &CC1Args) const {
4870*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc) ||
4871*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdlibinc))
4872*67e74705SXin Li return;
4873*67e74705SXin Li if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
4874*67e74705SXin Li SmallVector<StringRef, 4> Dirs;
4875*67e74705SXin Li const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
4876*67e74705SXin Li StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4877*67e74705SXin Li ArrayRef<StringRef> DirVec(Dirs);
4878*67e74705SXin Li addSystemIncludes(DriverArgs, CC1Args, DirVec);
4879*67e74705SXin Li }
4880*67e74705SXin Li }
4881*67e74705SXin Li
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args) const4882*67e74705SXin Li void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
4883*67e74705SXin Li ArgStringList &CC1Args) const {
4884*67e74705SXin Li CC1Args.push_back("-nostdsysteminc");
4885*67e74705SXin Li }
4886*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4887*67e74705SXin Li void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
4888*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
4889*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdinc) ||
4890*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4891*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
4892*67e74705SXin Li return;
4893*67e74705SXin Li if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
4894*67e74705SXin Li SmallVector<StringRef, 4> Dirs;
4895*67e74705SXin Li const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
4896*67e74705SXin Li StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4897*67e74705SXin Li ArrayRef<StringRef> DirVec(Dirs);
4898*67e74705SXin Li addSystemIncludes(DriverArgs, CC1Args, DirVec);
4899*67e74705SXin Li }
4900*67e74705SXin Li }
4901*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const4902*67e74705SXin Li void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
4903*67e74705SXin Li ArgStringList &CmdArgs) const {
4904*67e74705SXin Li // We don't output any lib args. This is handled by xcc.
4905*67e74705SXin Li }
4906*67e74705SXin Li
MyriadToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)4907*67e74705SXin Li MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
4908*67e74705SXin Li const ArgList &Args)
4909*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
4910*67e74705SXin Li // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
4911*67e74705SXin Li // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
4912*67e74705SXin Li // This won't work to find gcc. Instead we give the installation detector an
4913*67e74705SXin Li // extra triple, which is preferable to further hacks of the logic that at
4914*67e74705SXin Li // present is based solely on getArch(). In particular, it would be wrong to
4915*67e74705SXin Li // choose the myriad installation when targeting a non-myriad sparc install.
4916*67e74705SXin Li switch (Triple.getArch()) {
4917*67e74705SXin Li default:
4918*67e74705SXin Li D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
4919*67e74705SXin Li << "myriad";
4920*67e74705SXin Li case llvm::Triple::sparc:
4921*67e74705SXin Li case llvm::Triple::sparcel:
4922*67e74705SXin Li case llvm::Triple::shave:
4923*67e74705SXin Li GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
4924*67e74705SXin Li }
4925*67e74705SXin Li
4926*67e74705SXin Li if (GCCInstallation.isValid()) {
4927*67e74705SXin Li // The contents of LibDir are independent of the version of gcc.
4928*67e74705SXin Li // This contains libc, libg (a superset of libc), libm, libstdc++, libssp.
4929*67e74705SXin Li SmallString<128> LibDir(GCCInstallation.getParentLibPath());
4930*67e74705SXin Li if (Triple.getArch() == llvm::Triple::sparcel)
4931*67e74705SXin Li llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib/le");
4932*67e74705SXin Li else
4933*67e74705SXin Li llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib");
4934*67e74705SXin Li addPathIfExists(D, LibDir, getFilePaths());
4935*67e74705SXin Li
4936*67e74705SXin Li // This directory contains crt{i,n,begin,end}.o as well as libgcc.
4937*67e74705SXin Li // These files are tied to a particular version of gcc.
4938*67e74705SXin Li SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
4939*67e74705SXin Li // There are actually 4 choices: {le,be} x {fpu,nofpu}
4940*67e74705SXin Li // but as this toolchain is for LEON sparc, it can assume FPU.
4941*67e74705SXin Li if (Triple.getArch() == llvm::Triple::sparcel)
4942*67e74705SXin Li llvm::sys::path::append(CompilerSupportDir, "le");
4943*67e74705SXin Li addPathIfExists(D, CompilerSupportDir, getFilePaths());
4944*67e74705SXin Li }
4945*67e74705SXin Li }
4946*67e74705SXin Li
~MyriadToolChain()4947*67e74705SXin Li MyriadToolChain::~MyriadToolChain() {}
4948*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4949*67e74705SXin Li void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4950*67e74705SXin Li ArgStringList &CC1Args) const {
4951*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nostdinc))
4952*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
4953*67e74705SXin Li }
4954*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const4955*67e74705SXin Li void MyriadToolChain::AddClangCXXStdlibIncludeArgs(
4956*67e74705SXin Li const ArgList &DriverArgs, ArgStringList &CC1Args) const {
4957*67e74705SXin Li if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4958*67e74705SXin Li DriverArgs.hasArg(options::OPT_nostdincxx))
4959*67e74705SXin Li return;
4960*67e74705SXin Li
4961*67e74705SXin Li // Only libstdc++, for now.
4962*67e74705SXin Li StringRef LibDir = GCCInstallation.getParentLibPath();
4963*67e74705SXin Li const GCCVersion &Version = GCCInstallation.getVersion();
4964*67e74705SXin Li StringRef TripleStr = GCCInstallation.getTriple().str();
4965*67e74705SXin Li const Multilib &Multilib = GCCInstallation.getMultilib();
4966*67e74705SXin Li
4967*67e74705SXin Li addLibStdCXXIncludePaths(
4968*67e74705SXin Li LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4969*67e74705SXin Li "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
4970*67e74705SXin Li }
4971*67e74705SXin Li
4972*67e74705SXin Li // MyriadToolChain handles several triples:
4973*67e74705SXin Li // {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
SelectTool(const JobAction & JA) const4974*67e74705SXin Li Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
4975*67e74705SXin Li // The inherited method works fine if not targeting the SHAVE.
4976*67e74705SXin Li if (!isShaveCompilation(getTriple()))
4977*67e74705SXin Li return ToolChain::SelectTool(JA);
4978*67e74705SXin Li switch (JA.getKind()) {
4979*67e74705SXin Li case Action::PreprocessJobClass:
4980*67e74705SXin Li case Action::CompileJobClass:
4981*67e74705SXin Li if (!Compiler)
4982*67e74705SXin Li Compiler.reset(new tools::SHAVE::Compiler(*this));
4983*67e74705SXin Li return Compiler.get();
4984*67e74705SXin Li case Action::AssembleJobClass:
4985*67e74705SXin Li if (!Assembler)
4986*67e74705SXin Li Assembler.reset(new tools::SHAVE::Assembler(*this));
4987*67e74705SXin Li return Assembler.get();
4988*67e74705SXin Li default:
4989*67e74705SXin Li return ToolChain::getTool(JA.getKind());
4990*67e74705SXin Li }
4991*67e74705SXin Li }
4992*67e74705SXin Li
buildLinker() const4993*67e74705SXin Li Tool *MyriadToolChain::buildLinker() const {
4994*67e74705SXin Li return new tools::Myriad::Linker(*this);
4995*67e74705SXin Li }
4996*67e74705SXin Li
WebAssembly(const Driver & D,const llvm::Triple & Triple,const llvm::opt::ArgList & Args)4997*67e74705SXin Li WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
4998*67e74705SXin Li const llvm::opt::ArgList &Args)
4999*67e74705SXin Li : ToolChain(D, Triple, Args) {
5000*67e74705SXin Li
5001*67e74705SXin Li assert(Triple.isArch32Bit() != Triple.isArch64Bit());
5002*67e74705SXin Li getFilePaths().push_back(
5003*67e74705SXin Li getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
5004*67e74705SXin Li
5005*67e74705SXin Li // Use LLD by default.
5006*67e74705SXin Li DefaultLinker = "lld";
5007*67e74705SXin Li }
5008*67e74705SXin Li
IsMathErrnoDefault() const5009*67e74705SXin Li bool WebAssembly::IsMathErrnoDefault() const { return false; }
5010*67e74705SXin Li
IsObjCNonFragileABIDefault() const5011*67e74705SXin Li bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
5012*67e74705SXin Li
UseObjCMixedDispatch() const5013*67e74705SXin Li bool WebAssembly::UseObjCMixedDispatch() const { return true; }
5014*67e74705SXin Li
isPICDefault() const5015*67e74705SXin Li bool WebAssembly::isPICDefault() const { return false; }
5016*67e74705SXin Li
isPIEDefault() const5017*67e74705SXin Li bool WebAssembly::isPIEDefault() const { return false; }
5018*67e74705SXin Li
isPICDefaultForced() const5019*67e74705SXin Li bool WebAssembly::isPICDefaultForced() const { return false; }
5020*67e74705SXin Li
IsIntegratedAssemblerDefault() const5021*67e74705SXin Li bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
5022*67e74705SXin Li
5023*67e74705SXin Li // TODO: Support Objective C stuff.
SupportsObjCGC() const5024*67e74705SXin Li bool WebAssembly::SupportsObjCGC() const { return false; }
5025*67e74705SXin Li
hasBlocksRuntime() const5026*67e74705SXin Li bool WebAssembly::hasBlocksRuntime() const { return false; }
5027*67e74705SXin Li
5028*67e74705SXin Li // TODO: Support profiling.
SupportsProfiling() const5029*67e74705SXin Li bool WebAssembly::SupportsProfiling() const { return false; }
5030*67e74705SXin Li
HasNativeLLVMSupport() const5031*67e74705SXin Li bool WebAssembly::HasNativeLLVMSupport() const { return true; }
5032*67e74705SXin Li
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args) const5033*67e74705SXin Li void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
5034*67e74705SXin Li ArgStringList &CC1Args) const {
5035*67e74705SXin Li if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
5036*67e74705SXin Li options::OPT_fno_use_init_array, true))
5037*67e74705SXin Li CC1Args.push_back("-fuse-init-array");
5038*67e74705SXin Li }
5039*67e74705SXin Li
GetDefaultRuntimeLibType() const5040*67e74705SXin Li ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
5041*67e74705SXin Li return ToolChain::RLT_CompilerRT;
5042*67e74705SXin Li }
5043*67e74705SXin Li
GetCXXStdlibType(const ArgList & Args) const5044*67e74705SXin Li ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
5045*67e74705SXin Li return ToolChain::CST_Libcxx;
5046*67e74705SXin Li }
5047*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const5048*67e74705SXin Li void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
5049*67e74705SXin Li ArgStringList &CC1Args) const {
5050*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nostdinc))
5051*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
5052*67e74705SXin Li }
5053*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const5054*67e74705SXin Li void WebAssembly::AddClangCXXStdlibIncludeArgs(
5055*67e74705SXin Li const llvm::opt::ArgList &DriverArgs,
5056*67e74705SXin Li llvm::opt::ArgStringList &CC1Args) const {
5057*67e74705SXin Li if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
5058*67e74705SXin Li !DriverArgs.hasArg(options::OPT_nostdincxx))
5059*67e74705SXin Li addSystemInclude(DriverArgs, CC1Args,
5060*67e74705SXin Li getDriver().SysRoot + "/include/c++/v1");
5061*67e74705SXin Li }
5062*67e74705SXin Li
buildLinker() const5063*67e74705SXin Li Tool *WebAssembly::buildLinker() const {
5064*67e74705SXin Li return new tools::wasm::Linker(*this);
5065*67e74705SXin Li }
5066*67e74705SXin Li
PS4CPU(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)5067*67e74705SXin Li PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
5068*67e74705SXin Li : Generic_ELF(D, Triple, Args) {
5069*67e74705SXin Li if (Args.hasArg(options::OPT_static))
5070*67e74705SXin Li D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
5071*67e74705SXin Li
5072*67e74705SXin Li // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
5073*67e74705SXin Li // if it exists; otherwise use the driver's installation path, which
5074*67e74705SXin Li // should be <SDK_DIR>/host_tools/bin.
5075*67e74705SXin Li
5076*67e74705SXin Li SmallString<512> PS4SDKDir;
5077*67e74705SXin Li if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
5078*67e74705SXin Li if (!llvm::sys::fs::exists(EnvValue))
5079*67e74705SXin Li getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
5080*67e74705SXin Li PS4SDKDir = EnvValue;
5081*67e74705SXin Li } else {
5082*67e74705SXin Li PS4SDKDir = getDriver().Dir;
5083*67e74705SXin Li llvm::sys::path::append(PS4SDKDir, "/../../");
5084*67e74705SXin Li }
5085*67e74705SXin Li
5086*67e74705SXin Li // By default, the driver won't report a warning if it can't find
5087*67e74705SXin Li // PS4's include or lib directories. This behavior could be changed if
5088*67e74705SXin Li // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
5089*67e74705SXin Li // If -isysroot was passed, use that as the SDK base path.
5090*67e74705SXin Li std::string PrefixDir;
5091*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
5092*67e74705SXin Li PrefixDir = A->getValue();
5093*67e74705SXin Li if (!llvm::sys::fs::exists(PrefixDir))
5094*67e74705SXin Li getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
5095*67e74705SXin Li } else
5096*67e74705SXin Li PrefixDir = PS4SDKDir.str();
5097*67e74705SXin Li
5098*67e74705SXin Li SmallString<512> PS4SDKIncludeDir(PrefixDir);
5099*67e74705SXin Li llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
5100*67e74705SXin Li if (!Args.hasArg(options::OPT_nostdinc) &&
5101*67e74705SXin Li !Args.hasArg(options::OPT_nostdlibinc) &&
5102*67e74705SXin Li !Args.hasArg(options::OPT_isysroot) &&
5103*67e74705SXin Li !Args.hasArg(options::OPT__sysroot_EQ) &&
5104*67e74705SXin Li !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
5105*67e74705SXin Li getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5106*67e74705SXin Li << "PS4 system headers" << PS4SDKIncludeDir;
5107*67e74705SXin Li }
5108*67e74705SXin Li
5109*67e74705SXin Li SmallString<512> PS4SDKLibDir(PS4SDKDir);
5110*67e74705SXin Li llvm::sys::path::append(PS4SDKLibDir, "target/lib");
5111*67e74705SXin Li if (!Args.hasArg(options::OPT_nostdlib) &&
5112*67e74705SXin Li !Args.hasArg(options::OPT_nodefaultlibs) &&
5113*67e74705SXin Li !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
5114*67e74705SXin Li !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
5115*67e74705SXin Li !Args.hasArg(options::OPT_emit_ast) &&
5116*67e74705SXin Li !llvm::sys::fs::exists(PS4SDKLibDir)) {
5117*67e74705SXin Li getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5118*67e74705SXin Li << "PS4 system libraries" << PS4SDKLibDir;
5119*67e74705SXin Li return;
5120*67e74705SXin Li }
5121*67e74705SXin Li getFilePaths().push_back(PS4SDKLibDir.str());
5122*67e74705SXin Li }
5123*67e74705SXin Li
buildAssembler() const5124*67e74705SXin Li Tool *PS4CPU::buildAssembler() const {
5125*67e74705SXin Li return new tools::PS4cpu::Assemble(*this);
5126*67e74705SXin Li }
5127*67e74705SXin Li
buildLinker() const5128*67e74705SXin Li Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
5129*67e74705SXin Li
isPICDefault() const5130*67e74705SXin Li bool PS4CPU::isPICDefault() const { return true; }
5131*67e74705SXin Li
HasNativeLLVMSupport() const5132*67e74705SXin Li bool PS4CPU::HasNativeLLVMSupport() const { return true; }
5133*67e74705SXin Li
getSupportedSanitizers() const5134*67e74705SXin Li SanitizerMask PS4CPU::getSupportedSanitizers() const {
5135*67e74705SXin Li SanitizerMask Res = ToolChain::getSupportedSanitizers();
5136*67e74705SXin Li Res |= SanitizerKind::Address;
5137*67e74705SXin Li Res |= SanitizerKind::Vptr;
5138*67e74705SXin Li return Res;
5139*67e74705SXin Li }
5140