xref: /aosp_15_r20/external/clang/lib/Driver/ToolChains.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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