xref: /minix3/external/bsd/llvm/dist/clang/lib/Driver/ToolChains.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "ToolChains.h"
11f4a2713aSLionel Sambuc #include "clang/Basic/ObjCRuntime.h"
12f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
13*0a6a1f1dSLionel Sambuc #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
14f4a2713aSLionel Sambuc #include "clang/Driver/Compilation.h"
15f4a2713aSLionel Sambuc #include "clang/Driver/Driver.h"
16f4a2713aSLionel Sambuc #include "clang/Driver/DriverDiagnostic.h"
17f4a2713aSLionel Sambuc #include "clang/Driver/Options.h"
18f4a2713aSLionel Sambuc #include "clang/Driver/SanitizerArgs.h"
19f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
22f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
23f4a2713aSLionel Sambuc #include "llvm/Option/Arg.h"
24f4a2713aSLionel Sambuc #include "llvm/Option/ArgList.h"
25f4a2713aSLionel Sambuc #include "llvm/Option/OptTable.h"
26f4a2713aSLionel Sambuc #include "llvm/Option/Option.h"
27f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
29f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
31f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
32*0a6a1f1dSLionel Sambuc #include "llvm/Support/raw_ostream.h"
33f4a2713aSLionel Sambuc #include <cstdlib> // ::getenv
34*0a6a1f1dSLionel Sambuc #include <system_error>
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc using namespace clang::driver;
37f4a2713aSLionel Sambuc using namespace clang::driver::toolchains;
38f4a2713aSLionel Sambuc using namespace clang;
39f4a2713aSLionel Sambuc using namespace llvm::opt;
40f4a2713aSLionel Sambuc 
MachO(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)41*0a6a1f1dSLionel Sambuc MachO::MachO(const Driver &D, const llvm::Triple &Triple,
42*0a6a1f1dSLionel Sambuc                        const ArgList &Args)
43*0a6a1f1dSLionel Sambuc   : ToolChain(D, Triple, Args) {
44*0a6a1f1dSLionel Sambuc   getProgramPaths().push_back(getDriver().getInstalledDir());
45*0a6a1f1dSLionel Sambuc   if (getDriver().getInstalledDir() != getDriver().Dir)
46*0a6a1f1dSLionel Sambuc     getProgramPaths().push_back(getDriver().Dir);
47f4a2713aSLionel Sambuc 
48*0a6a1f1dSLionel Sambuc   // We expect 'as', 'ld', etc. to be adjacent to our install dir.
49*0a6a1f1dSLionel Sambuc   getProgramPaths().push_back(getDriver().getInstalledDir());
50*0a6a1f1dSLionel Sambuc   if (getDriver().getInstalledDir() != getDriver().Dir)
51*0a6a1f1dSLionel Sambuc     getProgramPaths().push_back(getDriver().Dir);
52*0a6a1f1dSLionel Sambuc }
53*0a6a1f1dSLionel Sambuc 
54*0a6a1f1dSLionel Sambuc /// Darwin - Darwin tool chain for i386 and x86_64.
Darwin(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)55*0a6a1f1dSLionel Sambuc Darwin::Darwin(const Driver & D, const llvm::Triple & Triple,
56*0a6a1f1dSLionel Sambuc                const ArgList & Args)
57*0a6a1f1dSLionel Sambuc   : MachO(D, Triple, Args), TargetInitialized(false) {
58f4a2713aSLionel Sambuc   // Compute the initial Darwin version from the triple
59f4a2713aSLionel Sambuc   unsigned Major, Minor, Micro;
60f4a2713aSLionel Sambuc   if (!Triple.getMacOSXVersion(Major, Minor, Micro))
61f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_darwin_version) <<
62f4a2713aSLionel Sambuc       Triple.getOSName();
63f4a2713aSLionel Sambuc   llvm::raw_string_ostream(MacosxVersionMin)
64f4a2713aSLionel Sambuc     << Major << '.' << Minor << '.' << Micro;
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc   // FIXME: DarwinVersion is only used to find GCC's libexec directory.
67f4a2713aSLionel Sambuc   // It should be removed when we stop supporting that.
68f4a2713aSLionel Sambuc   DarwinVersion[0] = Minor + 4;
69f4a2713aSLionel Sambuc   DarwinVersion[1] = Micro;
70f4a2713aSLionel Sambuc   DarwinVersion[2] = 0;
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc   // Compute the initial iOS version from the triple
73f4a2713aSLionel Sambuc   Triple.getiOSVersion(Major, Minor, Micro);
74f4a2713aSLionel Sambuc   llvm::raw_string_ostream(iOSVersionMin)
75f4a2713aSLionel Sambuc     << Major << '.' << Minor << '.' << Micro;
76f4a2713aSLionel Sambuc }
77f4a2713aSLionel Sambuc 
LookupTypeForExtension(const char * Ext) const78*0a6a1f1dSLionel Sambuc types::ID MachO::LookupTypeForExtension(const char *Ext) const {
79f4a2713aSLionel Sambuc   types::ID Ty = types::lookupTypeForExtension(Ext);
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc   // Darwin always preprocesses assembly files (unless -x is used explicitly).
82f4a2713aSLionel Sambuc   if (Ty == types::TY_PP_Asm)
83f4a2713aSLionel Sambuc     return types::TY_Asm;
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc   return Ty;
86f4a2713aSLionel Sambuc }
87f4a2713aSLionel Sambuc 
HasNativeLLVMSupport() const88*0a6a1f1dSLionel Sambuc bool MachO::HasNativeLLVMSupport() const {
89f4a2713aSLionel Sambuc   return true;
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc 
92f4a2713aSLionel Sambuc /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
getDefaultObjCRuntime(bool isNonFragile) const93f4a2713aSLionel Sambuc ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
94*0a6a1f1dSLionel Sambuc   if (isTargetIOSBased())
95f4a2713aSLionel Sambuc     return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
96f4a2713aSLionel Sambuc   if (isNonFragile)
97f4a2713aSLionel Sambuc     return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
98f4a2713aSLionel Sambuc   return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
hasBlocksRuntime() const102f4a2713aSLionel Sambuc bool Darwin::hasBlocksRuntime() const {
103*0a6a1f1dSLionel Sambuc   if (isTargetIOSBased())
104f4a2713aSLionel Sambuc     return !isIPhoneOSVersionLT(3, 2);
105*0a6a1f1dSLionel Sambuc   else {
106*0a6a1f1dSLionel Sambuc     assert(isTargetMacOS() && "unexpected darwin target");
107f4a2713aSLionel Sambuc     return !isMacosxVersionLT(10, 6);
108f4a2713aSLionel Sambuc   }
109*0a6a1f1dSLionel Sambuc }
110f4a2713aSLionel Sambuc 
GetArmArchForMArch(StringRef Value)111f4a2713aSLionel Sambuc static const char *GetArmArchForMArch(StringRef Value) {
112f4a2713aSLionel Sambuc   return llvm::StringSwitch<const char*>(Value)
113f4a2713aSLionel Sambuc     .Case("armv6k", "armv6")
114f4a2713aSLionel Sambuc     .Case("armv6m", "armv6m")
115f4a2713aSLionel Sambuc     .Case("armv5tej", "armv5")
116f4a2713aSLionel Sambuc     .Case("xscale", "xscale")
117f4a2713aSLionel Sambuc     .Case("armv4t", "armv4t")
118f4a2713aSLionel Sambuc     .Case("armv7", "armv7")
119f4a2713aSLionel Sambuc     .Cases("armv7a", "armv7-a", "armv7")
120f4a2713aSLionel Sambuc     .Cases("armv7r", "armv7-r", "armv7")
121f4a2713aSLionel Sambuc     .Cases("armv7em", "armv7e-m", "armv7em")
122f4a2713aSLionel Sambuc     .Cases("armv7k", "armv7-k", "armv7k")
123f4a2713aSLionel Sambuc     .Cases("armv7m", "armv7-m", "armv7m")
124f4a2713aSLionel Sambuc     .Cases("armv7s", "armv7-s", "armv7s")
125*0a6a1f1dSLionel Sambuc     .Default(nullptr);
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc 
GetArmArchForMCpu(StringRef Value)128f4a2713aSLionel Sambuc static const char *GetArmArchForMCpu(StringRef Value) {
129f4a2713aSLionel Sambuc   return llvm::StringSwitch<const char *>(Value)
130f4a2713aSLionel Sambuc     .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
131f4a2713aSLionel Sambuc     .Cases("arm10e", "arm10tdmi", "armv5")
132f4a2713aSLionel Sambuc     .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
133f4a2713aSLionel Sambuc     .Case("xscale", "xscale")
134f4a2713aSLionel Sambuc     .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
135f4a2713aSLionel Sambuc     .Case("cortex-m0", "armv6m")
136f4a2713aSLionel Sambuc     .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7")
137*0a6a1f1dSLionel Sambuc     .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", "armv7")
138f4a2713aSLionel Sambuc     .Cases("cortex-r4", "cortex-r5", "armv7r")
139f4a2713aSLionel Sambuc     .Case("cortex-m3", "armv7m")
140*0a6a1f1dSLionel Sambuc     .Cases("cortex-m4", "cortex-m7", "armv7em")
141f4a2713aSLionel Sambuc     .Case("swift", "armv7s")
142*0a6a1f1dSLionel Sambuc     .Default(nullptr);
143f4a2713aSLionel Sambuc }
144f4a2713aSLionel Sambuc 
isSoftFloatABI(const ArgList & Args)145*0a6a1f1dSLionel Sambuc static bool isSoftFloatABI(const ArgList &Args) {
146*0a6a1f1dSLionel Sambuc   Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
147*0a6a1f1dSLionel Sambuc                            options::OPT_mfloat_abi_EQ);
148*0a6a1f1dSLionel Sambuc   if (!A)
149*0a6a1f1dSLionel Sambuc     return false;
150*0a6a1f1dSLionel Sambuc 
151*0a6a1f1dSLionel Sambuc   return A->getOption().matches(options::OPT_msoft_float) ||
152*0a6a1f1dSLionel Sambuc          (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
153*0a6a1f1dSLionel Sambuc           A->getValue() == StringRef("soft"));
154*0a6a1f1dSLionel Sambuc }
155*0a6a1f1dSLionel Sambuc 
getMachOArchName(const ArgList & Args) const156*0a6a1f1dSLionel Sambuc StringRef MachO::getMachOArchName(const ArgList &Args) const {
157f4a2713aSLionel Sambuc   switch (getTriple().getArch()) {
158f4a2713aSLionel Sambuc   default:
159*0a6a1f1dSLionel Sambuc     return getDefaultUniversalArchName();
160*0a6a1f1dSLionel Sambuc 
161*0a6a1f1dSLionel Sambuc   case llvm::Triple::aarch64:
162*0a6a1f1dSLionel Sambuc     return "arm64";
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc   case llvm::Triple::thumb:
165f4a2713aSLionel Sambuc   case llvm::Triple::arm: {
166f4a2713aSLionel Sambuc     if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
167f4a2713aSLionel Sambuc       if (const char *Arch = GetArmArchForMArch(A->getValue()))
168f4a2713aSLionel Sambuc         return Arch;
169f4a2713aSLionel Sambuc 
170f4a2713aSLionel Sambuc     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
171f4a2713aSLionel Sambuc       if (const char *Arch = GetArmArchForMCpu(A->getValue()))
172f4a2713aSLionel Sambuc         return Arch;
173f4a2713aSLionel Sambuc 
174f4a2713aSLionel Sambuc     return "arm";
175f4a2713aSLionel Sambuc   }
176f4a2713aSLionel Sambuc   }
177f4a2713aSLionel Sambuc }
178f4a2713aSLionel Sambuc 
~Darwin()179f4a2713aSLionel Sambuc Darwin::~Darwin() {
180f4a2713aSLionel Sambuc }
181f4a2713aSLionel Sambuc 
~MachO()182*0a6a1f1dSLionel Sambuc MachO::~MachO() {
183*0a6a1f1dSLionel Sambuc }
184*0a6a1f1dSLionel Sambuc 
185*0a6a1f1dSLionel Sambuc 
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const186*0a6a1f1dSLionel Sambuc std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args,
187*0a6a1f1dSLionel Sambuc                                                     types::ID InputType) const {
188*0a6a1f1dSLionel Sambuc   llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
189*0a6a1f1dSLionel Sambuc 
190*0a6a1f1dSLionel Sambuc   return Triple.getTriple();
191*0a6a1f1dSLionel Sambuc }
192*0a6a1f1dSLionel Sambuc 
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const193f4a2713aSLionel Sambuc std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
194f4a2713aSLionel Sambuc                                                 types::ID InputType) const {
195f4a2713aSLionel Sambuc   llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc   // If the target isn't initialized (e.g., an unknown Darwin platform, return
198f4a2713aSLionel Sambuc   // the default triple).
199f4a2713aSLionel Sambuc   if (!isTargetInitialized())
200f4a2713aSLionel Sambuc     return Triple.getTriple();
201f4a2713aSLionel Sambuc 
202f4a2713aSLionel Sambuc   SmallString<16> Str;
203*0a6a1f1dSLionel Sambuc   Str += isTargetIOSBased() ? "ios" : "macosx";
204f4a2713aSLionel Sambuc   Str += getTargetVersion().getAsString();
205f4a2713aSLionel Sambuc   Triple.setOSName(Str);
206f4a2713aSLionel Sambuc 
207f4a2713aSLionel Sambuc   return Triple.getTriple();
208f4a2713aSLionel Sambuc }
209f4a2713aSLionel Sambuc 
anchor()210f4a2713aSLionel Sambuc void Generic_ELF::anchor() {}
211f4a2713aSLionel Sambuc 
getTool(Action::ActionClass AC) const212*0a6a1f1dSLionel Sambuc Tool *MachO::getTool(Action::ActionClass AC) const {
213f4a2713aSLionel Sambuc   switch (AC) {
214f4a2713aSLionel Sambuc   case Action::LipoJobClass:
215f4a2713aSLionel Sambuc     if (!Lipo)
216f4a2713aSLionel Sambuc       Lipo.reset(new tools::darwin::Lipo(*this));
217f4a2713aSLionel Sambuc     return Lipo.get();
218f4a2713aSLionel Sambuc   case Action::DsymutilJobClass:
219f4a2713aSLionel Sambuc     if (!Dsymutil)
220f4a2713aSLionel Sambuc       Dsymutil.reset(new tools::darwin::Dsymutil(*this));
221f4a2713aSLionel Sambuc     return Dsymutil.get();
222*0a6a1f1dSLionel Sambuc   case Action::VerifyDebugInfoJobClass:
223f4a2713aSLionel Sambuc     if (!VerifyDebug)
224f4a2713aSLionel Sambuc       VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
225f4a2713aSLionel Sambuc     return VerifyDebug.get();
226f4a2713aSLionel Sambuc   default:
227f4a2713aSLionel Sambuc     return ToolChain::getTool(AC);
228f4a2713aSLionel Sambuc   }
229f4a2713aSLionel Sambuc }
230f4a2713aSLionel Sambuc 
buildLinker() const231*0a6a1f1dSLionel Sambuc Tool *MachO::buildLinker() const {
232f4a2713aSLionel Sambuc   return new tools::darwin::Link(*this);
233f4a2713aSLionel Sambuc }
234f4a2713aSLionel Sambuc 
buildAssembler() const235*0a6a1f1dSLionel Sambuc Tool *MachO::buildAssembler() const {
236f4a2713aSLionel Sambuc   return new tools::darwin::Assemble(*this);
237f4a2713aSLionel Sambuc }
238f4a2713aSLionel Sambuc 
DarwinClang(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)239f4a2713aSLionel Sambuc DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
240f4a2713aSLionel Sambuc                          const ArgList &Args)
241*0a6a1f1dSLionel Sambuc   : Darwin(D, Triple, Args) {
242*0a6a1f1dSLionel Sambuc }
243f4a2713aSLionel Sambuc 
addClangWarningOptions(ArgStringList & CC1Args) const244*0a6a1f1dSLionel Sambuc void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
245*0a6a1f1dSLionel Sambuc   // For iOS, 64-bit, promote certain warnings to errors.
246*0a6a1f1dSLionel Sambuc   if (!isTargetMacOS() && getTriple().isArch64Bit()) {
247*0a6a1f1dSLionel Sambuc     // Always enable -Wdeprecated-objc-isa-usage and promote it
248*0a6a1f1dSLionel Sambuc     // to an error.
249*0a6a1f1dSLionel Sambuc     CC1Args.push_back("-Wdeprecated-objc-isa-usage");
250*0a6a1f1dSLionel Sambuc     CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
251*0a6a1f1dSLionel Sambuc 
252*0a6a1f1dSLionel Sambuc     // Also error about implicit function declarations, as that
253*0a6a1f1dSLionel Sambuc     // can impact calling conventions.
254*0a6a1f1dSLionel Sambuc     CC1Args.push_back("-Werror=implicit-function-declaration");
255*0a6a1f1dSLionel Sambuc   }
256*0a6a1f1dSLionel Sambuc }
257*0a6a1f1dSLionel Sambuc 
258*0a6a1f1dSLionel Sambuc /// \brief Determine whether Objective-C automated reference counting is
259*0a6a1f1dSLionel Sambuc /// enabled.
isObjCAutoRefCount(const ArgList & Args)260*0a6a1f1dSLionel Sambuc static bool isObjCAutoRefCount(const ArgList &Args) {
261*0a6a1f1dSLionel Sambuc   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
262f4a2713aSLionel Sambuc }
263f4a2713aSLionel Sambuc 
AddLinkARCArgs(const ArgList & Args,ArgStringList & CmdArgs) const264f4a2713aSLionel Sambuc void DarwinClang::AddLinkARCArgs(const ArgList &Args,
265f4a2713aSLionel Sambuc                                  ArgStringList &CmdArgs) const {
266*0a6a1f1dSLionel Sambuc   // Avoid linking compatibility stubs on i386 mac.
267*0a6a1f1dSLionel Sambuc   if (isTargetMacOS() && getArch() == llvm::Triple::x86)
268*0a6a1f1dSLionel Sambuc     return;
269*0a6a1f1dSLionel Sambuc 
270*0a6a1f1dSLionel Sambuc   ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
271*0a6a1f1dSLionel Sambuc 
272*0a6a1f1dSLionel Sambuc   if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
273*0a6a1f1dSLionel Sambuc       runtime.hasSubscripting())
274*0a6a1f1dSLionel Sambuc     return;
275f4a2713aSLionel Sambuc 
276f4a2713aSLionel Sambuc   CmdArgs.push_back("-force_load");
277f4a2713aSLionel Sambuc   SmallString<128> P(getDriver().ClangExecutable);
278f4a2713aSLionel Sambuc   llvm::sys::path::remove_filename(P); // 'clang'
279f4a2713aSLionel Sambuc   llvm::sys::path::remove_filename(P); // 'bin'
280f4a2713aSLionel Sambuc   llvm::sys::path::append(P, "lib", "arc", "libarclite_");
281f4a2713aSLionel Sambuc   // Mash in the platform.
282f4a2713aSLionel Sambuc   if (isTargetIOSSimulator())
283f4a2713aSLionel Sambuc     P += "iphonesimulator";
284f4a2713aSLionel Sambuc   else if (isTargetIPhoneOS())
285f4a2713aSLionel Sambuc     P += "iphoneos";
286f4a2713aSLionel Sambuc   else
287f4a2713aSLionel Sambuc     P += "macosx";
288f4a2713aSLionel Sambuc   P += ".a";
289f4a2713aSLionel Sambuc 
290f4a2713aSLionel Sambuc   CmdArgs.push_back(Args.MakeArgString(P));
291f4a2713aSLionel Sambuc }
292f4a2713aSLionel Sambuc 
AddLinkRuntimeLib(const ArgList & Args,ArgStringList & CmdArgs,StringRef DarwinLibName,bool AlwaysLink,bool IsEmbedded,bool AddRPath) const293*0a6a1f1dSLionel Sambuc void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
294*0a6a1f1dSLionel Sambuc                               StringRef DarwinLibName, bool AlwaysLink,
295*0a6a1f1dSLionel Sambuc                               bool IsEmbedded, bool AddRPath) const {
296*0a6a1f1dSLionel Sambuc   SmallString<128> Dir(getDriver().ResourceDir);
297*0a6a1f1dSLionel Sambuc   llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
298*0a6a1f1dSLionel Sambuc 
299*0a6a1f1dSLionel Sambuc   SmallString<128> P(Dir);
300*0a6a1f1dSLionel Sambuc   llvm::sys::path::append(P, DarwinLibName);
301f4a2713aSLionel Sambuc 
302f4a2713aSLionel Sambuc   // For now, allow missing resource libraries to support developers who may
303f4a2713aSLionel Sambuc   // not have compiler-rt checked out or integrated into their build (unless
304f4a2713aSLionel Sambuc   // we explicitly force linking with this library).
305f4a2713aSLionel Sambuc   if (AlwaysLink || llvm::sys::fs::exists(P.str()))
306f4a2713aSLionel Sambuc     CmdArgs.push_back(Args.MakeArgString(P.str()));
307*0a6a1f1dSLionel Sambuc 
308*0a6a1f1dSLionel Sambuc   // Adding the rpaths might negatively interact when other rpaths are involved,
309*0a6a1f1dSLionel Sambuc   // so we should make sure we add the rpaths last, after all user-specified
310*0a6a1f1dSLionel Sambuc   // rpaths. This is currently true from this place, but we need to be
311*0a6a1f1dSLionel Sambuc   // careful if this function is ever called before user's rpaths are emitted.
312*0a6a1f1dSLionel Sambuc   if (AddRPath) {
313*0a6a1f1dSLionel Sambuc     assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
314*0a6a1f1dSLionel Sambuc 
315*0a6a1f1dSLionel Sambuc     // Add @executable_path to rpath to support having the dylib copied with
316*0a6a1f1dSLionel Sambuc     // the executable.
317*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-rpath");
318*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("@executable_path");
319*0a6a1f1dSLionel Sambuc 
320*0a6a1f1dSLionel Sambuc     // Add the path to the resource dir to rpath to support using the dylib
321*0a6a1f1dSLionel Sambuc     // from the default location without copying.
322*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-rpath");
323*0a6a1f1dSLionel Sambuc     CmdArgs.push_back(Args.MakeArgString(Dir.str()));
324*0a6a1f1dSLionel Sambuc   }
325f4a2713aSLionel Sambuc }
326f4a2713aSLionel Sambuc 
AddLinkRuntimeLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const327f4a2713aSLionel Sambuc void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
328f4a2713aSLionel Sambuc                                         ArgStringList &CmdArgs) const {
329f4a2713aSLionel Sambuc   // Darwin only supports the compiler-rt based runtime libraries.
330f4a2713aSLionel Sambuc   switch (GetRuntimeLibType(Args)) {
331f4a2713aSLionel Sambuc   case ToolChain::RLT_CompilerRT:
332f4a2713aSLionel Sambuc     break;
333f4a2713aSLionel Sambuc   default:
334f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
335f4a2713aSLionel Sambuc       << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
336f4a2713aSLionel Sambuc     return;
337f4a2713aSLionel Sambuc   }
338f4a2713aSLionel Sambuc 
339f4a2713aSLionel Sambuc   // Darwin doesn't support real static executables, don't link any runtime
340f4a2713aSLionel Sambuc   // libraries with -static.
341f4a2713aSLionel Sambuc   if (Args.hasArg(options::OPT_static) ||
342f4a2713aSLionel Sambuc       Args.hasArg(options::OPT_fapple_kext) ||
343f4a2713aSLionel Sambuc       Args.hasArg(options::OPT_mkernel))
344f4a2713aSLionel Sambuc     return;
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc   // Reject -static-libgcc for now, we can deal with this when and if someone
347f4a2713aSLionel Sambuc   // cares. This is useful in situations where someone wants to statically link
348f4a2713aSLionel Sambuc   // something like libstdc++, and needs its runtime support routines.
349f4a2713aSLionel Sambuc   if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
350f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_unsupported_opt)
351f4a2713aSLionel Sambuc       << A->getAsString(Args);
352f4a2713aSLionel Sambuc     return;
353f4a2713aSLionel Sambuc   }
354f4a2713aSLionel Sambuc 
355f4a2713aSLionel Sambuc   // If we are building profile support, link that library in.
356*0a6a1f1dSLionel Sambuc   if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
357*0a6a1f1dSLionel Sambuc                    false) ||
358f4a2713aSLionel Sambuc       Args.hasArg(options::OPT_fprofile_generate) ||
359*0a6a1f1dSLionel Sambuc       Args.hasArg(options::OPT_fprofile_instr_generate) ||
360f4a2713aSLionel Sambuc       Args.hasArg(options::OPT_fcreate_profile) ||
361f4a2713aSLionel Sambuc       Args.hasArg(options::OPT_coverage)) {
362f4a2713aSLionel Sambuc     // Select the appropriate runtime library for the target.
363*0a6a1f1dSLionel Sambuc     if (isTargetIOSBased())
364f4a2713aSLionel Sambuc       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a");
365*0a6a1f1dSLionel Sambuc     else
366f4a2713aSLionel Sambuc       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a");
367f4a2713aSLionel Sambuc   }
368f4a2713aSLionel Sambuc 
369f4a2713aSLionel Sambuc   const SanitizerArgs &Sanitize = getSanitizerArgs();
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc   // Add Ubsan runtime library, if required.
372f4a2713aSLionel Sambuc   if (Sanitize.needsUbsanRt()) {
373f4a2713aSLionel Sambuc     // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
374*0a6a1f1dSLionel Sambuc     if (isTargetIOSBased()) {
375f4a2713aSLionel Sambuc       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
376f4a2713aSLionel Sambuc         << "-fsanitize=undefined";
377f4a2713aSLionel Sambuc     } else {
378*0a6a1f1dSLionel Sambuc       assert(isTargetMacOS() && "unexpected non OS X target");
379f4a2713aSLionel Sambuc       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
380f4a2713aSLionel Sambuc 
381f4a2713aSLionel Sambuc       // The Ubsan runtime library requires C++.
382f4a2713aSLionel Sambuc       AddCXXStdlibLibArgs(Args, CmdArgs);
383f4a2713aSLionel Sambuc     }
384f4a2713aSLionel Sambuc   }
385f4a2713aSLionel Sambuc 
386f4a2713aSLionel Sambuc   // Add ASAN runtime library, if required. Dynamic libraries and bundles
387f4a2713aSLionel Sambuc   // should not be linked with the runtime library.
388f4a2713aSLionel Sambuc   if (Sanitize.needsAsanRt()) {
389f4a2713aSLionel Sambuc     // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
390*0a6a1f1dSLionel Sambuc     if (isTargetIPhoneOS()) {
391f4a2713aSLionel Sambuc       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
392f4a2713aSLionel Sambuc         << "-fsanitize=address";
393f4a2713aSLionel Sambuc     } else {
394f4a2713aSLionel Sambuc       if (!Args.hasArg(options::OPT_dynamiclib) &&
395f4a2713aSLionel Sambuc           !Args.hasArg(options::OPT_bundle)) {
396f4a2713aSLionel Sambuc         // The ASAN runtime library requires C++.
397f4a2713aSLionel Sambuc         AddCXXStdlibLibArgs(Args, CmdArgs);
398f4a2713aSLionel Sambuc       }
399f4a2713aSLionel Sambuc       if (isTargetMacOS()) {
400f4a2713aSLionel Sambuc         AddLinkRuntimeLib(Args, CmdArgs,
401f4a2713aSLionel Sambuc                           "libclang_rt.asan_osx_dynamic.dylib",
402*0a6a1f1dSLionel Sambuc                           /*AlwaysLink*/ true, /*IsEmbedded*/ false,
403*0a6a1f1dSLionel Sambuc                           /*AddRPath*/ true);
404f4a2713aSLionel Sambuc       } else {
405f4a2713aSLionel Sambuc         if (isTargetIOSSimulator()) {
406f4a2713aSLionel Sambuc           AddLinkRuntimeLib(Args, CmdArgs,
407f4a2713aSLionel Sambuc                             "libclang_rt.asan_iossim_dynamic.dylib",
408*0a6a1f1dSLionel Sambuc                             /*AlwaysLink*/ true, /*IsEmbedded*/ false,
409*0a6a1f1dSLionel Sambuc                             /*AddRPath*/ true);
410f4a2713aSLionel Sambuc         }
411f4a2713aSLionel Sambuc       }
412f4a2713aSLionel Sambuc     }
413f4a2713aSLionel Sambuc   }
414f4a2713aSLionel Sambuc 
415f4a2713aSLionel Sambuc   // Otherwise link libSystem, then the dynamic runtime library, and finally any
416f4a2713aSLionel Sambuc   // target specific static runtime library.
417f4a2713aSLionel Sambuc   CmdArgs.push_back("-lSystem");
418f4a2713aSLionel Sambuc 
419f4a2713aSLionel Sambuc   // Select the dynamic runtime library and the target specific static library.
420*0a6a1f1dSLionel Sambuc   if (isTargetIOSBased()) {
421f4a2713aSLionel Sambuc     // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
422f4a2713aSLionel Sambuc     // it never went into the SDK.
423f4a2713aSLionel Sambuc     // Linking against libgcc_s.1 isn't needed for iOS 5.0+
424*0a6a1f1dSLionel Sambuc     if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
425*0a6a1f1dSLionel Sambuc         getTriple().getArch() != llvm::Triple::aarch64)
426f4a2713aSLionel Sambuc       CmdArgs.push_back("-lgcc_s.1");
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc     // We currently always need a static runtime library for iOS.
429f4a2713aSLionel Sambuc     AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
430f4a2713aSLionel Sambuc   } else {
431*0a6a1f1dSLionel Sambuc     assert(isTargetMacOS() && "unexpected non MacOS platform");
432f4a2713aSLionel Sambuc     // The dynamic runtime library was merged with libSystem for 10.6 and
433f4a2713aSLionel Sambuc     // beyond; only 10.4 and 10.5 need an additional runtime library.
434f4a2713aSLionel Sambuc     if (isMacosxVersionLT(10, 5))
435f4a2713aSLionel Sambuc       CmdArgs.push_back("-lgcc_s.10.4");
436f4a2713aSLionel Sambuc     else if (isMacosxVersionLT(10, 6))
437f4a2713aSLionel Sambuc       CmdArgs.push_back("-lgcc_s.10.5");
438f4a2713aSLionel Sambuc 
439f4a2713aSLionel Sambuc     // For OS X, we thought we would only need a static runtime library when
440f4a2713aSLionel Sambuc     // targeting 10.4, to provide versions of the static functions which were
441f4a2713aSLionel Sambuc     // omitted from 10.4.dylib.
442f4a2713aSLionel Sambuc     //
443f4a2713aSLionel Sambuc     // Unfortunately, that turned out to not be true, because Darwin system
444f4a2713aSLionel Sambuc     // headers can still use eprintf on i386, and it is not exported from
445f4a2713aSLionel Sambuc     // libSystem. Therefore, we still must provide a runtime library just for
446f4a2713aSLionel Sambuc     // the tiny tiny handful of projects that *might* use that symbol.
447f4a2713aSLionel Sambuc     if (isMacosxVersionLT(10, 5)) {
448f4a2713aSLionel Sambuc       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
449f4a2713aSLionel Sambuc     } else {
450f4a2713aSLionel Sambuc       if (getTriple().getArch() == llvm::Triple::x86)
451f4a2713aSLionel Sambuc         AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
452f4a2713aSLionel Sambuc       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
453f4a2713aSLionel Sambuc     }
454f4a2713aSLionel Sambuc   }
455f4a2713aSLionel Sambuc }
456f4a2713aSLionel Sambuc 
AddDeploymentTarget(DerivedArgList & Args) const457f4a2713aSLionel Sambuc void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
458f4a2713aSLionel Sambuc   const OptTable &Opts = getDriver().getOpts();
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc   // Support allowing the SDKROOT environment variable used by xcrun and other
461f4a2713aSLionel Sambuc   // Xcode tools to define the default sysroot, by making it the default for
462f4a2713aSLionel Sambuc   // isysroot.
463f4a2713aSLionel Sambuc   if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
464f4a2713aSLionel Sambuc     // Warn if the path does not exist.
465f4a2713aSLionel Sambuc     if (!llvm::sys::fs::exists(A->getValue()))
466f4a2713aSLionel Sambuc       getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
467f4a2713aSLionel Sambuc   } else {
468f4a2713aSLionel Sambuc     if (char *env = ::getenv("SDKROOT")) {
469f4a2713aSLionel Sambuc       // We only use this value as the default if it is an absolute path,
470f4a2713aSLionel Sambuc       // exists, and it is not the root path.
471f4a2713aSLionel Sambuc       if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&
472f4a2713aSLionel Sambuc           StringRef(env) != "/") {
473f4a2713aSLionel Sambuc         Args.append(Args.MakeSeparateArg(
474f4a2713aSLionel Sambuc                       0, Opts.getOption(options::OPT_isysroot), env));
475f4a2713aSLionel Sambuc       }
476f4a2713aSLionel Sambuc     }
477f4a2713aSLionel Sambuc   }
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc   Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
480f4a2713aSLionel Sambuc   Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
481f4a2713aSLionel Sambuc   Arg *iOSSimVersion = Args.getLastArg(
482f4a2713aSLionel Sambuc     options::OPT_mios_simulator_version_min_EQ);
483f4a2713aSLionel Sambuc 
484*0a6a1f1dSLionel Sambuc   if (OSXVersion && iOSVersion) {
485f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
486f4a2713aSLionel Sambuc           << OSXVersion->getAsString(Args)
487*0a6a1f1dSLionel Sambuc           << iOSVersion->getAsString(Args);
488*0a6a1f1dSLionel Sambuc     iOSVersion = nullptr;
489*0a6a1f1dSLionel Sambuc   } else if (!OSXVersion && !iOSVersion) {
490f4a2713aSLionel Sambuc     // If no deployment target was specified on the command line, check for
491f4a2713aSLionel Sambuc     // environment defines.
492f4a2713aSLionel Sambuc     StringRef OSXTarget;
493f4a2713aSLionel Sambuc     StringRef iOSTarget;
494f4a2713aSLionel Sambuc     if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
495f4a2713aSLionel Sambuc       OSXTarget = env;
496f4a2713aSLionel Sambuc     if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
497f4a2713aSLionel Sambuc       iOSTarget = env;
498f4a2713aSLionel Sambuc 
499f4a2713aSLionel Sambuc     // If no '-miphoneos-version-min' specified on the command line and
500f4a2713aSLionel Sambuc     // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default
501f4a2713aSLionel Sambuc     // based on -isysroot.
502f4a2713aSLionel Sambuc     if (iOSTarget.empty()) {
503f4a2713aSLionel Sambuc       if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
504f4a2713aSLionel Sambuc         StringRef first, second;
505f4a2713aSLionel Sambuc         StringRef isysroot = A->getValue();
506*0a6a1f1dSLionel Sambuc         std::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
507f4a2713aSLionel Sambuc         if (second != "")
508f4a2713aSLionel Sambuc           iOSTarget = second.substr(0,3);
509f4a2713aSLionel Sambuc       }
510f4a2713aSLionel Sambuc     }
511f4a2713aSLionel Sambuc 
512f4a2713aSLionel Sambuc     // If no OSX or iOS target has been specified and we're compiling for armv7,
513f4a2713aSLionel Sambuc     // go ahead as assume we're targeting iOS.
514*0a6a1f1dSLionel Sambuc     StringRef MachOArchName = getMachOArchName(Args);
515f4a2713aSLionel Sambuc     if (OSXTarget.empty() && iOSTarget.empty() &&
516*0a6a1f1dSLionel Sambuc         (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
517*0a6a1f1dSLionel Sambuc          MachOArchName == "arm64"))
518f4a2713aSLionel Sambuc         iOSTarget = iOSVersionMin;
519f4a2713aSLionel Sambuc 
520f4a2713aSLionel Sambuc     // Allow conflicts among OSX and iOS for historical reasons, but choose the
521f4a2713aSLionel Sambuc     // default platform.
522f4a2713aSLionel Sambuc     if (!OSXTarget.empty() && !iOSTarget.empty()) {
523f4a2713aSLionel Sambuc       if (getTriple().getArch() == llvm::Triple::arm ||
524*0a6a1f1dSLionel Sambuc           getTriple().getArch() == llvm::Triple::aarch64 ||
525f4a2713aSLionel Sambuc           getTriple().getArch() == llvm::Triple::thumb)
526f4a2713aSLionel Sambuc         OSXTarget = "";
527f4a2713aSLionel Sambuc       else
528f4a2713aSLionel Sambuc         iOSTarget = "";
529f4a2713aSLionel Sambuc     }
530f4a2713aSLionel Sambuc 
531f4a2713aSLionel Sambuc     if (!OSXTarget.empty()) {
532f4a2713aSLionel Sambuc       const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
533*0a6a1f1dSLionel Sambuc       OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
534f4a2713aSLionel Sambuc       Args.append(OSXVersion);
535f4a2713aSLionel Sambuc     } else if (!iOSTarget.empty()) {
536f4a2713aSLionel Sambuc       const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
537*0a6a1f1dSLionel Sambuc       iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
538f4a2713aSLionel Sambuc       Args.append(iOSVersion);
539*0a6a1f1dSLionel Sambuc     } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
540*0a6a1f1dSLionel Sambuc                MachOArchName != "armv7em") {
541f4a2713aSLionel Sambuc       // Otherwise, assume we are targeting OS X.
542f4a2713aSLionel Sambuc       const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
543*0a6a1f1dSLionel Sambuc       OSXVersion = Args.MakeJoinedArg(nullptr, O, MacosxVersionMin);
544f4a2713aSLionel Sambuc       Args.append(OSXVersion);
545f4a2713aSLionel Sambuc     }
546f4a2713aSLionel Sambuc   }
547f4a2713aSLionel Sambuc 
548*0a6a1f1dSLionel Sambuc   DarwinPlatformKind Platform;
549*0a6a1f1dSLionel Sambuc   if (OSXVersion)
550*0a6a1f1dSLionel Sambuc     Platform = MacOS;
551*0a6a1f1dSLionel Sambuc   else if (iOSVersion)
552*0a6a1f1dSLionel Sambuc     Platform = IPhoneOS;
553*0a6a1f1dSLionel Sambuc   else
554*0a6a1f1dSLionel Sambuc     llvm_unreachable("Unable to infer Darwin variant");
555f4a2713aSLionel Sambuc 
556f4a2713aSLionel Sambuc   // Set the tool chain target information.
557f4a2713aSLionel Sambuc   unsigned Major, Minor, Micro;
558f4a2713aSLionel Sambuc   bool HadExtra;
559*0a6a1f1dSLionel Sambuc   if (Platform == MacOS) {
560*0a6a1f1dSLionel Sambuc     assert(!iOSVersion && "Unknown target platform!");
561f4a2713aSLionel Sambuc     if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor,
562f4a2713aSLionel Sambuc                                    Micro, HadExtra) || HadExtra ||
563f4a2713aSLionel Sambuc         Major != 10 || Minor >= 100 || Micro >= 100)
564f4a2713aSLionel Sambuc       getDriver().Diag(diag::err_drv_invalid_version_number)
565f4a2713aSLionel Sambuc         << OSXVersion->getAsString(Args);
566*0a6a1f1dSLionel Sambuc   } else if (Platform == IPhoneOS) {
567*0a6a1f1dSLionel Sambuc     assert(iOSVersion && "Unknown target platform!");
568*0a6a1f1dSLionel Sambuc     if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor,
569f4a2713aSLionel Sambuc                                    Micro, HadExtra) || HadExtra ||
570f4a2713aSLionel Sambuc         Major >= 10 || Minor >= 100 || Micro >= 100)
571f4a2713aSLionel Sambuc       getDriver().Diag(diag::err_drv_invalid_version_number)
572*0a6a1f1dSLionel Sambuc         << iOSVersion->getAsString(Args);
573*0a6a1f1dSLionel Sambuc   } else
574*0a6a1f1dSLionel Sambuc     llvm_unreachable("unknown kind of Darwin platform");
575f4a2713aSLionel Sambuc 
576*0a6a1f1dSLionel Sambuc   // Recognize iOS targets with an x86 architecture as the iOS simulator.
577f4a2713aSLionel Sambuc   if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
578f4a2713aSLionel Sambuc                      getTriple().getArch() == llvm::Triple::x86_64))
579*0a6a1f1dSLionel Sambuc     Platform = IPhoneOSSimulator;
580f4a2713aSLionel Sambuc 
581*0a6a1f1dSLionel Sambuc   setTarget(Platform, Major, Minor, Micro);
582f4a2713aSLionel Sambuc }
583f4a2713aSLionel Sambuc 
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const584f4a2713aSLionel Sambuc void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
585f4a2713aSLionel Sambuc                                       ArgStringList &CmdArgs) const {
586f4a2713aSLionel Sambuc   CXXStdlibType Type = GetCXXStdlibType(Args);
587f4a2713aSLionel Sambuc 
588f4a2713aSLionel Sambuc   switch (Type) {
589f4a2713aSLionel Sambuc   case ToolChain::CST_Libcxx:
590f4a2713aSLionel Sambuc     CmdArgs.push_back("-lc++");
591f4a2713aSLionel Sambuc     break;
592f4a2713aSLionel Sambuc 
593f4a2713aSLionel Sambuc   case ToolChain::CST_Libstdcxx: {
594f4a2713aSLionel Sambuc     // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
595f4a2713aSLionel Sambuc     // it was previously found in the gcc lib dir. However, for all the Darwin
596f4a2713aSLionel Sambuc     // platforms we care about it was -lstdc++.6, so we search for that
597f4a2713aSLionel Sambuc     // explicitly if we can't see an obvious -lstdc++ candidate.
598f4a2713aSLionel Sambuc 
599f4a2713aSLionel Sambuc     // Check in the sysroot first.
600f4a2713aSLionel Sambuc     if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
601f4a2713aSLionel Sambuc       SmallString<128> P(A->getValue());
602f4a2713aSLionel Sambuc       llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
603f4a2713aSLionel Sambuc 
604f4a2713aSLionel Sambuc       if (!llvm::sys::fs::exists(P.str())) {
605f4a2713aSLionel Sambuc         llvm::sys::path::remove_filename(P);
606f4a2713aSLionel Sambuc         llvm::sys::path::append(P, "libstdc++.6.dylib");
607f4a2713aSLionel Sambuc         if (llvm::sys::fs::exists(P.str())) {
608f4a2713aSLionel Sambuc           CmdArgs.push_back(Args.MakeArgString(P.str()));
609f4a2713aSLionel Sambuc           return;
610f4a2713aSLionel Sambuc         }
611f4a2713aSLionel Sambuc       }
612f4a2713aSLionel Sambuc     }
613f4a2713aSLionel Sambuc 
614f4a2713aSLionel Sambuc     // Otherwise, look in the root.
615f4a2713aSLionel Sambuc     // FIXME: This should be removed someday when we don't have to care about
616f4a2713aSLionel Sambuc     // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
617f4a2713aSLionel Sambuc     if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") &&
618f4a2713aSLionel Sambuc         llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) {
619f4a2713aSLionel Sambuc       CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
620f4a2713aSLionel Sambuc       return;
621f4a2713aSLionel Sambuc     }
622f4a2713aSLionel Sambuc 
623f4a2713aSLionel Sambuc     // Otherwise, let the linker search.
624f4a2713aSLionel Sambuc     CmdArgs.push_back("-lstdc++");
625f4a2713aSLionel Sambuc     break;
626f4a2713aSLionel Sambuc   }
627f4a2713aSLionel Sambuc   }
628f4a2713aSLionel Sambuc }
629f4a2713aSLionel Sambuc 
AddCCKextLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const630f4a2713aSLionel Sambuc void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
631f4a2713aSLionel Sambuc                                    ArgStringList &CmdArgs) const {
632f4a2713aSLionel Sambuc 
633f4a2713aSLionel Sambuc   // For Darwin platforms, use the compiler-rt-based support library
634f4a2713aSLionel Sambuc   // instead of the gcc-provided one (which is also incidentally
635f4a2713aSLionel Sambuc   // only present in the gcc lib dir, which makes it hard to find).
636f4a2713aSLionel Sambuc 
637f4a2713aSLionel Sambuc   SmallString<128> P(getDriver().ResourceDir);
638f4a2713aSLionel Sambuc   llvm::sys::path::append(P, "lib", "darwin");
639f4a2713aSLionel Sambuc 
640f4a2713aSLionel Sambuc   // Use the newer cc_kext for iOS ARM after 6.0.
641f4a2713aSLionel Sambuc   if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
642*0a6a1f1dSLionel Sambuc       getTriple().getArch() == llvm::Triple::aarch64 ||
643f4a2713aSLionel Sambuc       !isIPhoneOSVersionLT(6, 0)) {
644f4a2713aSLionel Sambuc     llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
645f4a2713aSLionel Sambuc   } else {
646f4a2713aSLionel Sambuc     llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a");
647f4a2713aSLionel Sambuc   }
648f4a2713aSLionel Sambuc 
649f4a2713aSLionel Sambuc   // For now, allow missing resource libraries to support developers who may
650f4a2713aSLionel Sambuc   // not have compiler-rt checked out or integrated into their build.
651f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(P.str()))
652f4a2713aSLionel Sambuc     CmdArgs.push_back(Args.MakeArgString(P.str()));
653f4a2713aSLionel Sambuc }
654f4a2713aSLionel Sambuc 
TranslateArgs(const DerivedArgList & Args,const char * BoundArch) const655*0a6a1f1dSLionel Sambuc DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
656f4a2713aSLionel Sambuc                                      const char *BoundArch) const {
657f4a2713aSLionel Sambuc   DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
658f4a2713aSLionel Sambuc   const OptTable &Opts = getDriver().getOpts();
659f4a2713aSLionel Sambuc 
660f4a2713aSLionel Sambuc   // FIXME: We really want to get out of the tool chain level argument
661f4a2713aSLionel Sambuc   // translation business, as it makes the driver functionality much
662f4a2713aSLionel Sambuc   // more opaque. For now, we follow gcc closely solely for the
663f4a2713aSLionel Sambuc   // purpose of easily achieving feature parity & testability. Once we
664f4a2713aSLionel Sambuc   // have something that works, we should reevaluate each translation
665f4a2713aSLionel Sambuc   // and try to push it down into tool specific logic.
666f4a2713aSLionel Sambuc 
667*0a6a1f1dSLionel Sambuc   for (Arg *A : Args) {
668f4a2713aSLionel Sambuc     if (A->getOption().matches(options::OPT_Xarch__)) {
669f4a2713aSLionel Sambuc       // Skip this argument unless the architecture matches either the toolchain
670f4a2713aSLionel Sambuc       // triple arch, or the arch being bound.
671f4a2713aSLionel Sambuc       llvm::Triple::ArchType XarchArch =
672*0a6a1f1dSLionel Sambuc         tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
673f4a2713aSLionel Sambuc       if (!(XarchArch == getArch()  ||
674f4a2713aSLionel Sambuc             (BoundArch && XarchArch ==
675*0a6a1f1dSLionel Sambuc              tools::darwin::getArchTypeForMachOArchName(BoundArch))))
676f4a2713aSLionel Sambuc         continue;
677f4a2713aSLionel Sambuc 
678f4a2713aSLionel Sambuc       Arg *OriginalArg = A;
679f4a2713aSLionel Sambuc       unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
680f4a2713aSLionel Sambuc       unsigned Prev = Index;
681*0a6a1f1dSLionel Sambuc       std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
682f4a2713aSLionel Sambuc 
683f4a2713aSLionel Sambuc       // If the argument parsing failed or more than one argument was
684f4a2713aSLionel Sambuc       // consumed, the -Xarch_ argument's parameter tried to consume
685f4a2713aSLionel Sambuc       // extra arguments. Emit an error and ignore.
686f4a2713aSLionel Sambuc       //
687f4a2713aSLionel Sambuc       // We also want to disallow any options which would alter the
688f4a2713aSLionel Sambuc       // driver behavior; that isn't going to work in our model. We
689f4a2713aSLionel Sambuc       // use isDriverOption() as an approximation, although things
690f4a2713aSLionel Sambuc       // like -O4 are going to slip through.
691f4a2713aSLionel Sambuc       if (!XarchArg || Index > Prev + 1) {
692f4a2713aSLionel Sambuc         getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
693f4a2713aSLionel Sambuc           << A->getAsString(Args);
694f4a2713aSLionel Sambuc         continue;
695f4a2713aSLionel Sambuc       } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
696f4a2713aSLionel Sambuc         getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
697f4a2713aSLionel Sambuc           << A->getAsString(Args);
698f4a2713aSLionel Sambuc         continue;
699f4a2713aSLionel Sambuc       }
700f4a2713aSLionel Sambuc 
701f4a2713aSLionel Sambuc       XarchArg->setBaseArg(A);
702f4a2713aSLionel Sambuc 
703*0a6a1f1dSLionel Sambuc       A = XarchArg.release();
704f4a2713aSLionel Sambuc       DAL->AddSynthesizedArg(A);
705f4a2713aSLionel Sambuc 
706f4a2713aSLionel Sambuc       // Linker input arguments require custom handling. The problem is that we
707f4a2713aSLionel Sambuc       // have already constructed the phase actions, so we can not treat them as
708f4a2713aSLionel Sambuc       // "input arguments".
709f4a2713aSLionel Sambuc       if (A->getOption().hasFlag(options::LinkerInput)) {
710f4a2713aSLionel Sambuc         // Convert the argument into individual Zlinker_input_args.
711f4a2713aSLionel Sambuc         for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
712f4a2713aSLionel Sambuc           DAL->AddSeparateArg(OriginalArg,
713f4a2713aSLionel Sambuc                               Opts.getOption(options::OPT_Zlinker_input),
714f4a2713aSLionel Sambuc                               A->getValue(i));
715f4a2713aSLionel Sambuc 
716f4a2713aSLionel Sambuc         }
717f4a2713aSLionel Sambuc         continue;
718f4a2713aSLionel Sambuc       }
719f4a2713aSLionel Sambuc     }
720f4a2713aSLionel Sambuc 
721f4a2713aSLionel Sambuc     // Sob. These is strictly gcc compatible for the time being. Apple
722f4a2713aSLionel Sambuc     // gcc translates options twice, which means that self-expanding
723f4a2713aSLionel Sambuc     // options add duplicates.
724f4a2713aSLionel Sambuc     switch ((options::ID) A->getOption().getID()) {
725f4a2713aSLionel Sambuc     default:
726f4a2713aSLionel Sambuc       DAL->append(A);
727f4a2713aSLionel Sambuc       break;
728f4a2713aSLionel Sambuc 
729f4a2713aSLionel Sambuc     case options::OPT_mkernel:
730f4a2713aSLionel Sambuc     case options::OPT_fapple_kext:
731f4a2713aSLionel Sambuc       DAL->append(A);
732f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
733f4a2713aSLionel Sambuc       break;
734f4a2713aSLionel Sambuc 
735f4a2713aSLionel Sambuc     case options::OPT_dependency_file:
736f4a2713aSLionel Sambuc       DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
737f4a2713aSLionel Sambuc                           A->getValue());
738f4a2713aSLionel Sambuc       break;
739f4a2713aSLionel Sambuc 
740f4a2713aSLionel Sambuc     case options::OPT_gfull:
741f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
742f4a2713aSLionel Sambuc       DAL->AddFlagArg(A,
743f4a2713aSLionel Sambuc                Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
744f4a2713aSLionel Sambuc       break;
745f4a2713aSLionel Sambuc 
746f4a2713aSLionel Sambuc     case options::OPT_gused:
747f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
748f4a2713aSLionel Sambuc       DAL->AddFlagArg(A,
749f4a2713aSLionel Sambuc              Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
750f4a2713aSLionel Sambuc       break;
751f4a2713aSLionel Sambuc 
752f4a2713aSLionel Sambuc     case options::OPT_shared:
753f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
754f4a2713aSLionel Sambuc       break;
755f4a2713aSLionel Sambuc 
756f4a2713aSLionel Sambuc     case options::OPT_fconstant_cfstrings:
757f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
758f4a2713aSLionel Sambuc       break;
759f4a2713aSLionel Sambuc 
760f4a2713aSLionel Sambuc     case options::OPT_fno_constant_cfstrings:
761f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
762f4a2713aSLionel Sambuc       break;
763f4a2713aSLionel Sambuc 
764f4a2713aSLionel Sambuc     case options::OPT_Wnonportable_cfstrings:
765f4a2713aSLionel Sambuc       DAL->AddFlagArg(A,
766f4a2713aSLionel Sambuc                       Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
767f4a2713aSLionel Sambuc       break;
768f4a2713aSLionel Sambuc 
769f4a2713aSLionel Sambuc     case options::OPT_Wno_nonportable_cfstrings:
770f4a2713aSLionel Sambuc       DAL->AddFlagArg(A,
771f4a2713aSLionel Sambuc                    Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
772f4a2713aSLionel Sambuc       break;
773f4a2713aSLionel Sambuc 
774f4a2713aSLionel Sambuc     case options::OPT_fpascal_strings:
775f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
776f4a2713aSLionel Sambuc       break;
777f4a2713aSLionel Sambuc 
778f4a2713aSLionel Sambuc     case options::OPT_fno_pascal_strings:
779f4a2713aSLionel Sambuc       DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
780f4a2713aSLionel Sambuc       break;
781f4a2713aSLionel Sambuc     }
782f4a2713aSLionel Sambuc   }
783f4a2713aSLionel Sambuc 
784f4a2713aSLionel Sambuc   if (getTriple().getArch() == llvm::Triple::x86 ||
785f4a2713aSLionel Sambuc       getTriple().getArch() == llvm::Triple::x86_64)
786f4a2713aSLionel Sambuc     if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
787*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
788*0a6a1f1dSLionel Sambuc                         "core2");
789f4a2713aSLionel Sambuc 
790f4a2713aSLionel Sambuc   // Add the arch options based on the particular spelling of -arch, to match
791f4a2713aSLionel Sambuc   // how the driver driver works.
792f4a2713aSLionel Sambuc   if (BoundArch) {
793f4a2713aSLionel Sambuc     StringRef Name = BoundArch;
794f4a2713aSLionel Sambuc     const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
795f4a2713aSLionel Sambuc     const Option MArch = Opts.getOption(options::OPT_march_EQ);
796f4a2713aSLionel Sambuc 
797f4a2713aSLionel Sambuc     // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
798f4a2713aSLionel Sambuc     // which defines the list of which architectures we accept.
799f4a2713aSLionel Sambuc     if (Name == "ppc")
800f4a2713aSLionel Sambuc       ;
801f4a2713aSLionel Sambuc     else if (Name == "ppc601")
802*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "601");
803f4a2713aSLionel Sambuc     else if (Name == "ppc603")
804*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "603");
805f4a2713aSLionel Sambuc     else if (Name == "ppc604")
806*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "604");
807f4a2713aSLionel Sambuc     else if (Name == "ppc604e")
808*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "604e");
809f4a2713aSLionel Sambuc     else if (Name == "ppc750")
810*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "750");
811f4a2713aSLionel Sambuc     else if (Name == "ppc7400")
812*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "7400");
813f4a2713aSLionel Sambuc     else if (Name == "ppc7450")
814*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "7450");
815f4a2713aSLionel Sambuc     else if (Name == "ppc970")
816*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MCpu, "970");
817f4a2713aSLionel Sambuc 
818f4a2713aSLionel Sambuc     else if (Name == "ppc64" || Name == "ppc64le")
819*0a6a1f1dSLionel Sambuc       DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
820f4a2713aSLionel Sambuc 
821f4a2713aSLionel Sambuc     else if (Name == "i386")
822f4a2713aSLionel Sambuc       ;
823f4a2713aSLionel Sambuc     else if (Name == "i486")
824*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "i486");
825f4a2713aSLionel Sambuc     else if (Name == "i586")
826*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "i586");
827f4a2713aSLionel Sambuc     else if (Name == "i686")
828*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "i686");
829f4a2713aSLionel Sambuc     else if (Name == "pentium")
830*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "pentium");
831f4a2713aSLionel Sambuc     else if (Name == "pentium2")
832*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "pentium2");
833f4a2713aSLionel Sambuc     else if (Name == "pentpro")
834*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
835f4a2713aSLionel Sambuc     else if (Name == "pentIIm3")
836*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "pentium2");
837f4a2713aSLionel Sambuc 
838f4a2713aSLionel Sambuc     else if (Name == "x86_64")
839*0a6a1f1dSLionel Sambuc       DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
840f4a2713aSLionel Sambuc     else if (Name == "x86_64h") {
841*0a6a1f1dSLionel Sambuc       DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
842*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
843f4a2713aSLionel Sambuc     }
844f4a2713aSLionel Sambuc 
845f4a2713aSLionel Sambuc     else if (Name == "arm")
846*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv4t");
847f4a2713aSLionel Sambuc     else if (Name == "armv4t")
848*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv4t");
849f4a2713aSLionel Sambuc     else if (Name == "armv5")
850*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
851f4a2713aSLionel Sambuc     else if (Name == "xscale")
852*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "xscale");
853f4a2713aSLionel Sambuc     else if (Name == "armv6")
854*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv6k");
855f4a2713aSLionel Sambuc     else if (Name == "armv6m")
856*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv6m");
857f4a2713aSLionel Sambuc     else if (Name == "armv7")
858*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv7a");
859f4a2713aSLionel Sambuc     else if (Name == "armv7em")
860*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv7em");
861f4a2713aSLionel Sambuc     else if (Name == "armv7k")
862*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv7k");
863f4a2713aSLionel Sambuc     else if (Name == "armv7m")
864*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv7m");
865f4a2713aSLionel Sambuc     else if (Name == "armv7s")
866*0a6a1f1dSLionel Sambuc       DAL->AddJoinedArg(nullptr, MArch, "armv7s");
867f4a2713aSLionel Sambuc   }
868f4a2713aSLionel Sambuc 
869*0a6a1f1dSLionel Sambuc   return DAL;
870*0a6a1f1dSLionel Sambuc }
871*0a6a1f1dSLionel Sambuc 
AddLinkRuntimeLibArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const872*0a6a1f1dSLionel Sambuc void MachO::AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
873*0a6a1f1dSLionel Sambuc                                   llvm::opt::ArgStringList &CmdArgs) const {
874*0a6a1f1dSLionel Sambuc   // Embedded targets are simple at the moment, not supporting sanitizers and
875*0a6a1f1dSLionel Sambuc   // with different libraries for each member of the product { static, PIC } x
876*0a6a1f1dSLionel Sambuc   // { hard-float, soft-float }
877*0a6a1f1dSLionel Sambuc   llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
878*0a6a1f1dSLionel Sambuc   CompilerRT +=
879*0a6a1f1dSLionel Sambuc       tools::arm::getARMFloatABI(getDriver(), Args, getTriple()) == "hard"
880*0a6a1f1dSLionel Sambuc           ? "hard"
881*0a6a1f1dSLionel Sambuc           : "soft";
882*0a6a1f1dSLionel Sambuc   CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
883*0a6a1f1dSLionel Sambuc 
884*0a6a1f1dSLionel Sambuc   AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
885*0a6a1f1dSLionel Sambuc }
886*0a6a1f1dSLionel Sambuc 
887*0a6a1f1dSLionel Sambuc 
TranslateArgs(const DerivedArgList & Args,const char * BoundArch) const888*0a6a1f1dSLionel Sambuc DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
889*0a6a1f1dSLionel Sambuc                                       const char *BoundArch) const {
890*0a6a1f1dSLionel Sambuc   // First get the generic Apple args, before moving onto Darwin-specific ones.
891*0a6a1f1dSLionel Sambuc   DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch);
892*0a6a1f1dSLionel Sambuc   const OptTable &Opts = getDriver().getOpts();
893*0a6a1f1dSLionel Sambuc 
894*0a6a1f1dSLionel Sambuc   // If no architecture is bound, none of the translations here are relevant.
895*0a6a1f1dSLionel Sambuc   if (!BoundArch)
896*0a6a1f1dSLionel Sambuc     return DAL;
897*0a6a1f1dSLionel Sambuc 
898f4a2713aSLionel Sambuc   // Add an explicit version min argument for the deployment target. We do this
899f4a2713aSLionel Sambuc   // after argument translation because -Xarch_ arguments may add a version min
900f4a2713aSLionel Sambuc   // argument.
901f4a2713aSLionel Sambuc   AddDeploymentTarget(*DAL);
902f4a2713aSLionel Sambuc 
903f4a2713aSLionel Sambuc   // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
904f4a2713aSLionel Sambuc   // FIXME: It would be far better to avoid inserting those -static arguments,
905f4a2713aSLionel Sambuc   // but we can't check the deployment target in the translation code until
906f4a2713aSLionel Sambuc   // it is set here.
907*0a6a1f1dSLionel Sambuc   if (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0)) {
908f4a2713aSLionel Sambuc     for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
909f4a2713aSLionel Sambuc       Arg *A = *it;
910f4a2713aSLionel Sambuc       ++it;
911f4a2713aSLionel Sambuc       if (A->getOption().getID() != options::OPT_mkernel &&
912f4a2713aSLionel Sambuc           A->getOption().getID() != options::OPT_fapple_kext)
913f4a2713aSLionel Sambuc         continue;
914f4a2713aSLionel Sambuc       assert(it != ie && "unexpected argument translation");
915f4a2713aSLionel Sambuc       A = *it;
916f4a2713aSLionel Sambuc       assert(A->getOption().getID() == options::OPT_static &&
917f4a2713aSLionel Sambuc              "missing expected -static argument");
918f4a2713aSLionel Sambuc       it = DAL->getArgs().erase(it);
919f4a2713aSLionel Sambuc     }
920f4a2713aSLionel Sambuc   }
921f4a2713aSLionel Sambuc 
922f4a2713aSLionel Sambuc   // Default to use libc++ on OS X 10.9+ and iOS 7+.
923f4a2713aSLionel Sambuc   if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
924*0a6a1f1dSLionel Sambuc        (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0))) &&
925f4a2713aSLionel Sambuc       !Args.getLastArg(options::OPT_stdlib_EQ))
926*0a6a1f1dSLionel Sambuc     DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
927*0a6a1f1dSLionel Sambuc                       "libc++");
928f4a2713aSLionel Sambuc 
929f4a2713aSLionel Sambuc   // Validate the C++ standard library choice.
930f4a2713aSLionel Sambuc   CXXStdlibType Type = GetCXXStdlibType(*DAL);
931f4a2713aSLionel Sambuc   if (Type == ToolChain::CST_Libcxx) {
932f4a2713aSLionel Sambuc     // Check whether the target provides libc++.
933f4a2713aSLionel Sambuc     StringRef where;
934f4a2713aSLionel Sambuc 
935*0a6a1f1dSLionel Sambuc     // Complain about targeting iOS < 5.0 in any way.
936*0a6a1f1dSLionel Sambuc     if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
937f4a2713aSLionel Sambuc       where = "iOS 5.0";
938f4a2713aSLionel Sambuc 
939f4a2713aSLionel Sambuc     if (where != StringRef()) {
940f4a2713aSLionel Sambuc       getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
941f4a2713aSLionel Sambuc         << where;
942f4a2713aSLionel Sambuc     }
943f4a2713aSLionel Sambuc   }
944f4a2713aSLionel Sambuc 
945f4a2713aSLionel Sambuc   return DAL;
946f4a2713aSLionel Sambuc }
947f4a2713aSLionel Sambuc 
IsUnwindTablesDefault() const948*0a6a1f1dSLionel Sambuc bool MachO::IsUnwindTablesDefault() const {
949f4a2713aSLionel Sambuc   return getArch() == llvm::Triple::x86_64;
950f4a2713aSLionel Sambuc }
951f4a2713aSLionel Sambuc 
UseDwarfDebugFlags() const952*0a6a1f1dSLionel Sambuc bool MachO::UseDwarfDebugFlags() const {
953f4a2713aSLionel Sambuc   if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
954f4a2713aSLionel Sambuc     return S[0] != '\0';
955f4a2713aSLionel Sambuc   return false;
956f4a2713aSLionel Sambuc }
957f4a2713aSLionel Sambuc 
UseSjLjExceptions() const958f4a2713aSLionel Sambuc bool Darwin::UseSjLjExceptions() const {
959f4a2713aSLionel Sambuc   // Darwin uses SjLj exceptions on ARM.
960f4a2713aSLionel Sambuc   return (getTriple().getArch() == llvm::Triple::arm ||
961f4a2713aSLionel Sambuc           getTriple().getArch() == llvm::Triple::thumb);
962f4a2713aSLionel Sambuc }
963f4a2713aSLionel Sambuc 
isPICDefault() const964*0a6a1f1dSLionel Sambuc bool MachO::isPICDefault() const {
965f4a2713aSLionel Sambuc   return true;
966f4a2713aSLionel Sambuc }
967f4a2713aSLionel Sambuc 
isPIEDefault() const968*0a6a1f1dSLionel Sambuc bool MachO::isPIEDefault() const {
969f4a2713aSLionel Sambuc   return false;
970f4a2713aSLionel Sambuc }
971f4a2713aSLionel Sambuc 
isPICDefaultForced() const972*0a6a1f1dSLionel Sambuc bool MachO::isPICDefaultForced() const {
973*0a6a1f1dSLionel Sambuc   return (getArch() == llvm::Triple::x86_64 ||
974*0a6a1f1dSLionel Sambuc           getArch() == llvm::Triple::aarch64);
975f4a2713aSLionel Sambuc }
976f4a2713aSLionel Sambuc 
SupportsProfiling() const977*0a6a1f1dSLionel Sambuc bool MachO::SupportsProfiling() const {
978f4a2713aSLionel Sambuc   // Profiling instrumentation is only supported on x86.
979f4a2713aSLionel Sambuc   return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
980f4a2713aSLionel Sambuc }
981f4a2713aSLionel Sambuc 
addMinVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const982*0a6a1f1dSLionel Sambuc void Darwin::addMinVersionArgs(const llvm::opt::ArgList &Args,
983*0a6a1f1dSLionel Sambuc                                llvm::opt::ArgStringList &CmdArgs) const {
984*0a6a1f1dSLionel Sambuc   VersionTuple TargetVersion = getTargetVersion();
985*0a6a1f1dSLionel Sambuc 
986*0a6a1f1dSLionel Sambuc   if (isTargetIOSSimulator())
987*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-ios_simulator_version_min");
988*0a6a1f1dSLionel Sambuc   else if (isTargetIOSBased())
989*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-iphoneos_version_min");
990*0a6a1f1dSLionel Sambuc   else {
991*0a6a1f1dSLionel Sambuc     assert(isTargetMacOS() && "unexpected target");
992*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-macosx_version_min");
993*0a6a1f1dSLionel Sambuc   }
994*0a6a1f1dSLionel Sambuc 
995*0a6a1f1dSLionel Sambuc   CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
996*0a6a1f1dSLionel Sambuc }
997*0a6a1f1dSLionel Sambuc 
addStartObjectFileArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const998*0a6a1f1dSLionel Sambuc void Darwin::addStartObjectFileArgs(const llvm::opt::ArgList &Args,
999*0a6a1f1dSLionel Sambuc                                     llvm::opt::ArgStringList &CmdArgs) const {
1000*0a6a1f1dSLionel Sambuc   // Derived from startfile spec.
1001*0a6a1f1dSLionel Sambuc   if (Args.hasArg(options::OPT_dynamiclib)) {
1002*0a6a1f1dSLionel Sambuc     // Derived from darwin_dylib1 spec.
1003*0a6a1f1dSLionel Sambuc     if (isTargetIOSSimulator()) {
1004*0a6a1f1dSLionel Sambuc       ; // iOS simulator does not need dylib1.o.
1005*0a6a1f1dSLionel Sambuc     } else if (isTargetIPhoneOS()) {
1006*0a6a1f1dSLionel Sambuc       if (isIPhoneOSVersionLT(3, 1))
1007*0a6a1f1dSLionel Sambuc         CmdArgs.push_back("-ldylib1.o");
1008*0a6a1f1dSLionel Sambuc     } else {
1009*0a6a1f1dSLionel Sambuc       if (isMacosxVersionLT(10, 5))
1010*0a6a1f1dSLionel Sambuc         CmdArgs.push_back("-ldylib1.o");
1011*0a6a1f1dSLionel Sambuc       else if (isMacosxVersionLT(10, 6))
1012*0a6a1f1dSLionel Sambuc         CmdArgs.push_back("-ldylib1.10.5.o");
1013*0a6a1f1dSLionel Sambuc     }
1014*0a6a1f1dSLionel Sambuc   } else {
1015*0a6a1f1dSLionel Sambuc     if (Args.hasArg(options::OPT_bundle)) {
1016*0a6a1f1dSLionel Sambuc       if (!Args.hasArg(options::OPT_static)) {
1017*0a6a1f1dSLionel Sambuc         // Derived from darwin_bundle1 spec.
1018*0a6a1f1dSLionel Sambuc         if (isTargetIOSSimulator()) {
1019*0a6a1f1dSLionel Sambuc           ; // iOS simulator does not need bundle1.o.
1020*0a6a1f1dSLionel Sambuc         } else if (isTargetIPhoneOS()) {
1021*0a6a1f1dSLionel Sambuc           if (isIPhoneOSVersionLT(3, 1))
1022*0a6a1f1dSLionel Sambuc             CmdArgs.push_back("-lbundle1.o");
1023*0a6a1f1dSLionel Sambuc         } else {
1024*0a6a1f1dSLionel Sambuc           if (isMacosxVersionLT(10, 6))
1025*0a6a1f1dSLionel Sambuc             CmdArgs.push_back("-lbundle1.o");
1026*0a6a1f1dSLionel Sambuc         }
1027*0a6a1f1dSLionel Sambuc       }
1028*0a6a1f1dSLionel Sambuc     } else {
1029*0a6a1f1dSLionel Sambuc       if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
1030*0a6a1f1dSLionel Sambuc         if (Args.hasArg(options::OPT_static) ||
1031*0a6a1f1dSLionel Sambuc             Args.hasArg(options::OPT_object) ||
1032*0a6a1f1dSLionel Sambuc             Args.hasArg(options::OPT_preload)) {
1033*0a6a1f1dSLionel Sambuc           CmdArgs.push_back("-lgcrt0.o");
1034*0a6a1f1dSLionel Sambuc         } else {
1035*0a6a1f1dSLionel Sambuc           CmdArgs.push_back("-lgcrt1.o");
1036*0a6a1f1dSLionel Sambuc 
1037*0a6a1f1dSLionel Sambuc           // darwin_crt2 spec is empty.
1038*0a6a1f1dSLionel Sambuc         }
1039*0a6a1f1dSLionel Sambuc         // By default on OS X 10.8 and later, we don't link with a crt1.o
1040*0a6a1f1dSLionel Sambuc         // file and the linker knows to use _main as the entry point.  But,
1041*0a6a1f1dSLionel Sambuc         // when compiling with -pg, we need to link with the gcrt1.o file,
1042*0a6a1f1dSLionel Sambuc         // so pass the -no_new_main option to tell the linker to use the
1043*0a6a1f1dSLionel Sambuc         // "start" symbol as the entry point.
1044*0a6a1f1dSLionel Sambuc         if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
1045*0a6a1f1dSLionel Sambuc           CmdArgs.push_back("-no_new_main");
1046*0a6a1f1dSLionel Sambuc       } else {
1047*0a6a1f1dSLionel Sambuc         if (Args.hasArg(options::OPT_static) ||
1048*0a6a1f1dSLionel Sambuc             Args.hasArg(options::OPT_object) ||
1049*0a6a1f1dSLionel Sambuc             Args.hasArg(options::OPT_preload)) {
1050*0a6a1f1dSLionel Sambuc           CmdArgs.push_back("-lcrt0.o");
1051*0a6a1f1dSLionel Sambuc         } else {
1052*0a6a1f1dSLionel Sambuc           // Derived from darwin_crt1 spec.
1053*0a6a1f1dSLionel Sambuc           if (isTargetIOSSimulator()) {
1054*0a6a1f1dSLionel Sambuc             ; // iOS simulator does not need crt1.o.
1055*0a6a1f1dSLionel Sambuc           } else if (isTargetIPhoneOS()) {
1056*0a6a1f1dSLionel Sambuc             if (getArch() == llvm::Triple::aarch64)
1057*0a6a1f1dSLionel Sambuc               ; // iOS does not need any crt1 files for arm64
1058*0a6a1f1dSLionel Sambuc             else if (isIPhoneOSVersionLT(3, 1))
1059*0a6a1f1dSLionel Sambuc               CmdArgs.push_back("-lcrt1.o");
1060*0a6a1f1dSLionel Sambuc             else if (isIPhoneOSVersionLT(6, 0))
1061*0a6a1f1dSLionel Sambuc               CmdArgs.push_back("-lcrt1.3.1.o");
1062*0a6a1f1dSLionel Sambuc           } else {
1063*0a6a1f1dSLionel Sambuc             if (isMacosxVersionLT(10, 5))
1064*0a6a1f1dSLionel Sambuc               CmdArgs.push_back("-lcrt1.o");
1065*0a6a1f1dSLionel Sambuc             else if (isMacosxVersionLT(10, 6))
1066*0a6a1f1dSLionel Sambuc               CmdArgs.push_back("-lcrt1.10.5.o");
1067*0a6a1f1dSLionel Sambuc             else if (isMacosxVersionLT(10, 8))
1068*0a6a1f1dSLionel Sambuc               CmdArgs.push_back("-lcrt1.10.6.o");
1069*0a6a1f1dSLionel Sambuc 
1070*0a6a1f1dSLionel Sambuc             // darwin_crt2 spec is empty.
1071*0a6a1f1dSLionel Sambuc           }
1072*0a6a1f1dSLionel Sambuc         }
1073*0a6a1f1dSLionel Sambuc       }
1074*0a6a1f1dSLionel Sambuc     }
1075*0a6a1f1dSLionel Sambuc   }
1076*0a6a1f1dSLionel Sambuc 
1077*0a6a1f1dSLionel Sambuc   if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
1078*0a6a1f1dSLionel Sambuc       isMacosxVersionLT(10, 5)) {
1079*0a6a1f1dSLionel Sambuc     const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
1080*0a6a1f1dSLionel Sambuc     CmdArgs.push_back(Str);
1081*0a6a1f1dSLionel Sambuc   }
1082*0a6a1f1dSLionel Sambuc }
1083*0a6a1f1dSLionel Sambuc 
SupportsObjCGC() const1084f4a2713aSLionel Sambuc bool Darwin::SupportsObjCGC() const {
1085*0a6a1f1dSLionel Sambuc   return isTargetMacOS();
1086f4a2713aSLionel Sambuc }
1087f4a2713aSLionel Sambuc 
CheckObjCARC() const1088f4a2713aSLionel Sambuc void Darwin::CheckObjCARC() const {
1089*0a6a1f1dSLionel Sambuc   if (isTargetIOSBased()|| (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
1090f4a2713aSLionel Sambuc     return;
1091f4a2713aSLionel Sambuc   getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
1092f4a2713aSLionel Sambuc }
1093f4a2713aSLionel Sambuc 
1094f4a2713aSLionel Sambuc /// Generic_GCC - A tool chain using the 'gcc' command to perform
1095f4a2713aSLionel Sambuc /// all subcommands; this relies on gcc translating the majority of
1096f4a2713aSLionel Sambuc /// command line options.
1097f4a2713aSLionel Sambuc 
1098f4a2713aSLionel Sambuc /// \brief Parse a GCCVersion object out of a string of text.
1099f4a2713aSLionel Sambuc ///
1100f4a2713aSLionel Sambuc /// This is the primary means of forming GCCVersion objects.
1101f4a2713aSLionel Sambuc /*static*/
Parse(StringRef VersionText)1102f4a2713aSLionel Sambuc Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
1103f4a2713aSLionel Sambuc   const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
1104f4a2713aSLionel Sambuc   std::pair<StringRef, StringRef> First = VersionText.split('.');
1105f4a2713aSLionel Sambuc   std::pair<StringRef, StringRef> Second = First.second.split('.');
1106f4a2713aSLionel Sambuc 
1107f4a2713aSLionel Sambuc   GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
1108f4a2713aSLionel Sambuc   if (First.first.getAsInteger(10, GoodVersion.Major) ||
1109f4a2713aSLionel Sambuc       GoodVersion.Major < 0)
1110f4a2713aSLionel Sambuc     return BadVersion;
1111f4a2713aSLionel Sambuc   GoodVersion.MajorStr = First.first.str();
1112f4a2713aSLionel Sambuc   if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
1113f4a2713aSLionel Sambuc       GoodVersion.Minor < 0)
1114f4a2713aSLionel Sambuc     return BadVersion;
1115f4a2713aSLionel Sambuc   GoodVersion.MinorStr = Second.first.str();
1116f4a2713aSLionel Sambuc 
1117f4a2713aSLionel Sambuc   // First look for a number prefix and parse that if present. Otherwise just
1118f4a2713aSLionel Sambuc   // stash the entire patch string in the suffix, and leave the number
1119f4a2713aSLionel Sambuc   // unspecified. This covers versions strings such as:
1120f4a2713aSLionel Sambuc   //   4.4
1121f4a2713aSLionel Sambuc   //   4.4.0
1122f4a2713aSLionel Sambuc   //   4.4.x
1123f4a2713aSLionel Sambuc   //   4.4.2-rc4
1124f4a2713aSLionel Sambuc   //   4.4.x-patched
1125f4a2713aSLionel Sambuc   // And retains any patch number it finds.
1126f4a2713aSLionel Sambuc   StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
1127f4a2713aSLionel Sambuc   if (!PatchText.empty()) {
1128f4a2713aSLionel Sambuc     if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
1129f4a2713aSLionel Sambuc       // Try to parse the number and any suffix.
1130f4a2713aSLionel Sambuc       if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
1131f4a2713aSLionel Sambuc           GoodVersion.Patch < 0)
1132f4a2713aSLionel Sambuc         return BadVersion;
1133f4a2713aSLionel Sambuc       GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
1134f4a2713aSLionel Sambuc     }
1135f4a2713aSLionel Sambuc   }
1136f4a2713aSLionel Sambuc 
1137f4a2713aSLionel Sambuc   return GoodVersion;
1138f4a2713aSLionel Sambuc }
1139f4a2713aSLionel Sambuc 
1140f4a2713aSLionel Sambuc /// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
isOlderThan(int RHSMajor,int RHSMinor,int RHSPatch,StringRef RHSPatchSuffix) const1141f4a2713aSLionel Sambuc bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
1142f4a2713aSLionel Sambuc                                           int RHSPatch,
1143f4a2713aSLionel Sambuc                                           StringRef RHSPatchSuffix) const {
1144f4a2713aSLionel Sambuc   if (Major != RHSMajor)
1145f4a2713aSLionel Sambuc     return Major < RHSMajor;
1146f4a2713aSLionel Sambuc   if (Minor != RHSMinor)
1147f4a2713aSLionel Sambuc     return Minor < RHSMinor;
1148f4a2713aSLionel Sambuc   if (Patch != RHSPatch) {
1149f4a2713aSLionel Sambuc     // Note that versions without a specified patch sort higher than those with
1150f4a2713aSLionel Sambuc     // a patch.
1151f4a2713aSLionel Sambuc     if (RHSPatch == -1)
1152f4a2713aSLionel Sambuc       return true;
1153f4a2713aSLionel Sambuc     if (Patch == -1)
1154f4a2713aSLionel Sambuc       return false;
1155f4a2713aSLionel Sambuc 
1156f4a2713aSLionel Sambuc     // Otherwise just sort on the patch itself.
1157f4a2713aSLionel Sambuc     return Patch < RHSPatch;
1158f4a2713aSLionel Sambuc   }
1159f4a2713aSLionel Sambuc   if (PatchSuffix != RHSPatchSuffix) {
1160f4a2713aSLionel Sambuc     // Sort empty suffixes higher.
1161f4a2713aSLionel Sambuc     if (RHSPatchSuffix.empty())
1162f4a2713aSLionel Sambuc       return true;
1163f4a2713aSLionel Sambuc     if (PatchSuffix.empty())
1164f4a2713aSLionel Sambuc       return false;
1165f4a2713aSLionel Sambuc 
1166f4a2713aSLionel Sambuc     // Provide a lexicographic sort to make this a total ordering.
1167f4a2713aSLionel Sambuc     return PatchSuffix < RHSPatchSuffix;
1168f4a2713aSLionel Sambuc   }
1169f4a2713aSLionel Sambuc 
1170f4a2713aSLionel Sambuc   // The versions are equal.
1171f4a2713aSLionel Sambuc   return false;
1172f4a2713aSLionel Sambuc }
1173f4a2713aSLionel Sambuc 
getGCCToolchainDir(const ArgList & Args)1174*0a6a1f1dSLionel Sambuc static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
1175f4a2713aSLionel Sambuc   const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
1176f4a2713aSLionel Sambuc   if (A)
1177f4a2713aSLionel Sambuc     return A->getValue();
1178f4a2713aSLionel Sambuc   return GCC_INSTALL_PREFIX;
1179f4a2713aSLionel Sambuc }
1180f4a2713aSLionel Sambuc 
1181*0a6a1f1dSLionel Sambuc /// \brief Initialize a GCCInstallationDetector from the driver.
1182f4a2713aSLionel Sambuc ///
1183f4a2713aSLionel Sambuc /// This performs all of the autodetection and sets up the various paths.
1184f4a2713aSLionel Sambuc /// Once constructed, a GCCInstallationDetector is essentially immutable.
1185f4a2713aSLionel Sambuc ///
1186f4a2713aSLionel Sambuc /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1187f4a2713aSLionel Sambuc /// should instead pull the target out of the driver. This is currently
1188f4a2713aSLionel Sambuc /// necessary because the driver doesn't store the final version of the target
1189f4a2713aSLionel Sambuc /// triple.
1190*0a6a1f1dSLionel Sambuc void
init(const Driver & D,const llvm::Triple & TargetTriple,const ArgList & Args)1191*0a6a1f1dSLionel Sambuc Generic_GCC::GCCInstallationDetector::init(
1192*0a6a1f1dSLionel Sambuc     const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args) {
1193f4a2713aSLionel Sambuc   llvm::Triple BiarchVariantTriple =
1194f4a2713aSLionel Sambuc       TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
1195f4a2713aSLionel Sambuc                                  : TargetTriple.get32BitArchVariant();
1196f4a2713aSLionel Sambuc   // The library directories which may contain GCC installations.
1197f4a2713aSLionel Sambuc   SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
1198f4a2713aSLionel Sambuc   // The compatible GCC triples for this particular architecture.
1199*0a6a1f1dSLionel Sambuc   SmallVector<StringRef, 16> CandidateTripleAliases;
1200*0a6a1f1dSLionel Sambuc   SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
1201f4a2713aSLionel Sambuc   CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
1202f4a2713aSLionel Sambuc                            CandidateTripleAliases, CandidateBiarchLibDirs,
1203f4a2713aSLionel Sambuc                            CandidateBiarchTripleAliases);
1204f4a2713aSLionel Sambuc 
1205f4a2713aSLionel Sambuc   // Compute the set of prefixes for our search.
1206f4a2713aSLionel Sambuc   SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1207f4a2713aSLionel Sambuc                                        D.PrefixDirs.end());
1208f4a2713aSLionel Sambuc 
1209f4a2713aSLionel Sambuc   StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1210f4a2713aSLionel Sambuc   if (GCCToolchainDir != "") {
1211f4a2713aSLionel Sambuc     if (GCCToolchainDir.back() == '/')
1212f4a2713aSLionel Sambuc       GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
1213f4a2713aSLionel Sambuc 
1214f4a2713aSLionel Sambuc     Prefixes.push_back(GCCToolchainDir);
1215f4a2713aSLionel Sambuc   } else {
1216f4a2713aSLionel Sambuc     // If we have a SysRoot, try that first.
1217f4a2713aSLionel Sambuc     if (!D.SysRoot.empty()) {
1218f4a2713aSLionel Sambuc       Prefixes.push_back(D.SysRoot);
1219f4a2713aSLionel Sambuc       Prefixes.push_back(D.SysRoot + "/usr");
1220f4a2713aSLionel Sambuc     }
1221f4a2713aSLionel Sambuc 
1222f4a2713aSLionel Sambuc     // Then look for gcc installed alongside clang.
1223f4a2713aSLionel Sambuc     Prefixes.push_back(D.InstalledDir + "/..");
1224f4a2713aSLionel Sambuc 
1225f4a2713aSLionel Sambuc     // And finally in /usr.
1226f4a2713aSLionel Sambuc     if (D.SysRoot.empty())
1227f4a2713aSLionel Sambuc       Prefixes.push_back("/usr");
1228f4a2713aSLionel Sambuc   }
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc   // Loop over the various components which exist and select the best GCC
1231f4a2713aSLionel Sambuc   // installation available. GCC installs are ranked by version number.
1232f4a2713aSLionel Sambuc   Version = GCCVersion::Parse("0.0.0");
1233f4a2713aSLionel Sambuc   for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) {
1234f4a2713aSLionel Sambuc     if (!llvm::sys::fs::exists(Prefixes[i]))
1235f4a2713aSLionel Sambuc       continue;
1236f4a2713aSLionel Sambuc     for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) {
1237f4a2713aSLionel Sambuc       const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str();
1238f4a2713aSLionel Sambuc       if (!llvm::sys::fs::exists(LibDir))
1239f4a2713aSLionel Sambuc         continue;
1240f4a2713aSLionel Sambuc       for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
1241*0a6a1f1dSLionel Sambuc         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
1242f4a2713aSLionel Sambuc                                CandidateTripleAliases[k]);
1243f4a2713aSLionel Sambuc     }
1244f4a2713aSLionel Sambuc     for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) {
1245f4a2713aSLionel Sambuc       const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str();
1246f4a2713aSLionel Sambuc       if (!llvm::sys::fs::exists(LibDir))
1247f4a2713aSLionel Sambuc         continue;
1248f4a2713aSLionel Sambuc       for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke;
1249f4a2713aSLionel Sambuc            ++k)
1250*0a6a1f1dSLionel Sambuc         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
1251f4a2713aSLionel Sambuc                                CandidateBiarchTripleAliases[k],
1252f4a2713aSLionel Sambuc                                /*NeedsBiarchSuffix=*/ true);
1253f4a2713aSLionel Sambuc     }
1254f4a2713aSLionel Sambuc   }
1255f4a2713aSLionel Sambuc }
1256f4a2713aSLionel Sambuc 
print(raw_ostream & OS) const1257f4a2713aSLionel Sambuc void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
1258*0a6a1f1dSLionel Sambuc   for (const auto &InstallPath : CandidateGCCInstallPaths)
1259*0a6a1f1dSLionel Sambuc     OS << "Found candidate GCC installation: " << InstallPath << "\n";
1260f4a2713aSLionel Sambuc 
1261*0a6a1f1dSLionel Sambuc   if (!GCCInstallPath.empty())
1262f4a2713aSLionel Sambuc     OS << "Selected GCC installation: " << GCCInstallPath << "\n";
1263*0a6a1f1dSLionel Sambuc 
1264*0a6a1f1dSLionel Sambuc   for (const auto &Multilib : Multilibs)
1265*0a6a1f1dSLionel Sambuc     OS << "Candidate multilib: " << Multilib << "\n";
1266*0a6a1f1dSLionel Sambuc 
1267*0a6a1f1dSLionel Sambuc   if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
1268*0a6a1f1dSLionel Sambuc     OS << "Selected multilib: " << SelectedMultilib << "\n";
1269*0a6a1f1dSLionel Sambuc }
1270*0a6a1f1dSLionel Sambuc 
getBiarchSibling(Multilib & M) const1271*0a6a1f1dSLionel Sambuc bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
1272*0a6a1f1dSLionel Sambuc   if (BiarchSibling.hasValue()) {
1273*0a6a1f1dSLionel Sambuc     M = BiarchSibling.getValue();
1274*0a6a1f1dSLionel Sambuc     return true;
1275*0a6a1f1dSLionel Sambuc   }
1276*0a6a1f1dSLionel Sambuc   return false;
1277f4a2713aSLionel Sambuc }
1278f4a2713aSLionel Sambuc 
CollectLibDirsAndTriples(const llvm::Triple & TargetTriple,const llvm::Triple & BiarchTriple,SmallVectorImpl<StringRef> & LibDirs,SmallVectorImpl<StringRef> & TripleAliases,SmallVectorImpl<StringRef> & BiarchLibDirs,SmallVectorImpl<StringRef> & BiarchTripleAliases)1279f4a2713aSLionel Sambuc /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
1280f4a2713aSLionel Sambuc     const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
1281f4a2713aSLionel Sambuc     SmallVectorImpl<StringRef> &LibDirs,
1282f4a2713aSLionel Sambuc     SmallVectorImpl<StringRef> &TripleAliases,
1283f4a2713aSLionel Sambuc     SmallVectorImpl<StringRef> &BiarchLibDirs,
1284f4a2713aSLionel Sambuc     SmallVectorImpl<StringRef> &BiarchTripleAliases) {
1285f4a2713aSLionel Sambuc   // Declare a bunch of static data sets that we'll select between below. These
1286f4a2713aSLionel Sambuc   // are specifically designed to always refer to string literals to avoid any
1287f4a2713aSLionel Sambuc   // lifetime or initialization issues.
1288*0a6a1f1dSLionel Sambuc   static const char *const AArch64LibDirs[] = { "/lib64", "/lib" };
1289f4a2713aSLionel Sambuc   static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu",
1290*0a6a1f1dSLionel Sambuc                                                 "aarch64-linux-gnu",
1291*0a6a1f1dSLionel Sambuc                                                 "aarch64-linux-android",
1292*0a6a1f1dSLionel Sambuc                                                 "aarch64-redhat-linux" };
1293*0a6a1f1dSLionel Sambuc   static const char *const AArch64beLibDirs[] = { "/lib" };
1294*0a6a1f1dSLionel Sambuc   static const char *const AArch64beTriples[] = { "aarch64_be-none-linux-gnu",
1295*0a6a1f1dSLionel Sambuc                                                   "aarch64_be-linux-gnu" };
1296f4a2713aSLionel Sambuc 
1297f4a2713aSLionel Sambuc   static const char *const ARMLibDirs[] = { "/lib" };
1298f4a2713aSLionel Sambuc   static const char *const ARMTriples[] = { "arm-linux-gnueabi",
1299f4a2713aSLionel Sambuc                                             "arm-linux-androideabi" };
1300f4a2713aSLionel Sambuc   static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf",
1301f4a2713aSLionel Sambuc                                               "armv7hl-redhat-linux-gnueabi" };
1302*0a6a1f1dSLionel Sambuc   static const char *const ARMebLibDirs[] = { "/lib" };
1303*0a6a1f1dSLionel Sambuc   static const char *const ARMebTriples[] = { "armeb-linux-gnueabi",
1304*0a6a1f1dSLionel Sambuc                                               "armeb-linux-androideabi" };
1305*0a6a1f1dSLionel Sambuc   static const char *const ARMebHFTriples[] = { "armeb-linux-gnueabihf",
1306*0a6a1f1dSLionel Sambuc                                                 "armebv7hl-redhat-linux-gnueabi" };
1307f4a2713aSLionel Sambuc 
1308f4a2713aSLionel Sambuc   static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
1309f4a2713aSLionel Sambuc   static const char *const X86_64Triples[] = {
1310f4a2713aSLionel Sambuc     "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
1311f4a2713aSLionel Sambuc     "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
1312*0a6a1f1dSLionel Sambuc     "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux",
1313*0a6a1f1dSLionel Sambuc     "x86_64-linux-android", "x86_64-unknown-linux"
1314f4a2713aSLionel Sambuc   };
1315*0a6a1f1dSLionel Sambuc   static const char *const X32LibDirs[] = { "/libx32" };
1316f4a2713aSLionel Sambuc   static const char *const X86LibDirs[] = { "/lib32", "/lib" };
1317f4a2713aSLionel Sambuc   static const char *const X86Triples[] = {
1318f4a2713aSLionel Sambuc     "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
1319f4a2713aSLionel Sambuc     "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux",
1320f4a2713aSLionel Sambuc     "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux",
1321*0a6a1f1dSLionel Sambuc     "i686-montavista-linux", "i686-linux-android", "i586-linux-gnu"
1322f4a2713aSLionel Sambuc   };
1323f4a2713aSLionel Sambuc 
1324f4a2713aSLionel Sambuc   static const char *const MIPSLibDirs[] = { "/lib" };
1325f4a2713aSLionel Sambuc   static const char *const MIPSTriples[] = { "mips-linux-gnu",
1326*0a6a1f1dSLionel Sambuc                                              "mips-mti-linux-gnu",
1327*0a6a1f1dSLionel Sambuc                                              "mips-img-linux-gnu" };
1328f4a2713aSLionel Sambuc   static const char *const MIPSELLibDirs[] = { "/lib" };
1329f4a2713aSLionel Sambuc   static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
1330*0a6a1f1dSLionel Sambuc                                                "mipsel-linux-android",
1331*0a6a1f1dSLionel Sambuc                                                "mips-img-linux-gnu" };
1332f4a2713aSLionel Sambuc 
1333f4a2713aSLionel Sambuc   static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
1334f4a2713aSLionel Sambuc   static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
1335*0a6a1f1dSLionel Sambuc                                                "mips-mti-linux-gnu",
1336*0a6a1f1dSLionel Sambuc                                                "mips-img-linux-gnu",
1337*0a6a1f1dSLionel Sambuc                                                "mips64-linux-gnuabi64" };
1338f4a2713aSLionel Sambuc   static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
1339f4a2713aSLionel Sambuc   static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
1340*0a6a1f1dSLionel Sambuc                                                  "mips-mti-linux-gnu",
1341*0a6a1f1dSLionel Sambuc                                                  "mips-img-linux-gnu",
1342*0a6a1f1dSLionel Sambuc                                                  "mips64el-linux-android",
1343*0a6a1f1dSLionel Sambuc                                                  "mips64el-linux-gnuabi64" };
1344f4a2713aSLionel Sambuc 
1345f4a2713aSLionel Sambuc   static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
1346f4a2713aSLionel Sambuc   static const char *const PPCTriples[] = {
1347f4a2713aSLionel Sambuc     "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
1348f4a2713aSLionel Sambuc     "powerpc-suse-linux", "powerpc-montavista-linuxspe"
1349f4a2713aSLionel Sambuc   };
1350f4a2713aSLionel Sambuc   static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
1351f4a2713aSLionel Sambuc   static const char *const PPC64Triples[] = { "powerpc64-linux-gnu",
1352f4a2713aSLionel Sambuc                                               "powerpc64-unknown-linux-gnu",
1353f4a2713aSLionel Sambuc                                               "powerpc64-suse-linux",
1354f4a2713aSLionel Sambuc                                               "ppc64-redhat-linux" };
1355f4a2713aSLionel Sambuc   static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" };
1356f4a2713aSLionel Sambuc   static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu",
1357f4a2713aSLionel Sambuc                                                 "powerpc64le-unknown-linux-gnu",
1358f4a2713aSLionel Sambuc                                                 "powerpc64le-suse-linux",
1359f4a2713aSLionel Sambuc                                                 "ppc64le-redhat-linux" };
1360f4a2713aSLionel Sambuc 
1361*0a6a1f1dSLionel Sambuc   static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" };
1362*0a6a1f1dSLionel Sambuc   static const char *const SPARCv8Triples[] = { "sparc-linux-gnu",
1363*0a6a1f1dSLionel Sambuc                                                 "sparcv8-linux-gnu" };
1364*0a6a1f1dSLionel Sambuc   static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" };
1365*0a6a1f1dSLionel Sambuc   static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu",
1366*0a6a1f1dSLionel Sambuc                                                 "sparcv9-linux-gnu" };
1367*0a6a1f1dSLionel Sambuc 
1368f4a2713aSLionel Sambuc   static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
1369f4a2713aSLionel Sambuc   static const char *const SystemZTriples[] = {
1370f4a2713aSLionel Sambuc     "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
1371f4a2713aSLionel Sambuc     "s390x-suse-linux", "s390x-redhat-linux"
1372f4a2713aSLionel Sambuc   };
1373f4a2713aSLionel Sambuc 
1374*0a6a1f1dSLionel Sambuc   using std::begin;
1375*0a6a1f1dSLionel Sambuc   using std::end;
1376*0a6a1f1dSLionel Sambuc 
1377f4a2713aSLionel Sambuc   switch (TargetTriple.getArch()) {
1378f4a2713aSLionel Sambuc   case llvm::Triple::aarch64:
1379*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1380*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1381*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1382*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1383*0a6a1f1dSLionel Sambuc     break;
1384*0a6a1f1dSLionel Sambuc   case llvm::Triple::aarch64_be:
1385*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1386*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1387*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1388*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1389f4a2713aSLionel Sambuc     break;
1390f4a2713aSLionel Sambuc   case llvm::Triple::arm:
1391f4a2713aSLionel Sambuc   case llvm::Triple::thumb:
1392*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
1393f4a2713aSLionel Sambuc     if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1394*0a6a1f1dSLionel Sambuc       TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
1395f4a2713aSLionel Sambuc     } else {
1396*0a6a1f1dSLionel Sambuc       TripleAliases.append(begin(ARMTriples), end(ARMTriples));
1397*0a6a1f1dSLionel Sambuc     }
1398*0a6a1f1dSLionel Sambuc     break;
1399*0a6a1f1dSLionel Sambuc   case llvm::Triple::armeb:
1400*0a6a1f1dSLionel Sambuc   case llvm::Triple::thumbeb:
1401*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
1402*0a6a1f1dSLionel Sambuc     if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1403*0a6a1f1dSLionel Sambuc       TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
1404*0a6a1f1dSLionel Sambuc     } else {
1405*0a6a1f1dSLionel Sambuc       TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
1406f4a2713aSLionel Sambuc     }
1407f4a2713aSLionel Sambuc     break;
1408f4a2713aSLionel Sambuc   case llvm::Triple::x86_64:
1409*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1410*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1411*0a6a1f1dSLionel Sambuc     // x32 is always available when x86_64 is available, so adding it as
1412*0a6a1f1dSLionel Sambuc     // secondary arch with x86_64 triples
1413*0a6a1f1dSLionel Sambuc     if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
1414*0a6a1f1dSLionel Sambuc       BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
1415*0a6a1f1dSLionel Sambuc       BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1416*0a6a1f1dSLionel Sambuc     } else {
1417*0a6a1f1dSLionel Sambuc       BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1418*0a6a1f1dSLionel Sambuc       BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
1419*0a6a1f1dSLionel Sambuc     }
1420f4a2713aSLionel Sambuc     break;
1421f4a2713aSLionel Sambuc   case llvm::Triple::x86:
1422*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1423*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(X86Triples), end(X86Triples));
1424*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1425*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1426f4a2713aSLionel Sambuc     break;
1427f4a2713aSLionel Sambuc   case llvm::Triple::mips:
1428*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1429*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1430*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1431*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1432f4a2713aSLionel Sambuc     break;
1433f4a2713aSLionel Sambuc   case llvm::Triple::mipsel:
1434*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1435*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1436*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1437*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1438*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1439f4a2713aSLionel Sambuc     break;
1440f4a2713aSLionel Sambuc   case llvm::Triple::mips64:
1441*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1442*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1443*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1444*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1445f4a2713aSLionel Sambuc     break;
1446f4a2713aSLionel Sambuc   case llvm::Triple::mips64el:
1447*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1448*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1449*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1450*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1451*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1452f4a2713aSLionel Sambuc     break;
1453f4a2713aSLionel Sambuc   case llvm::Triple::ppc:
1454*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1455*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(PPCTriples), end(PPCTriples));
1456*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1457*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1458f4a2713aSLionel Sambuc     break;
1459f4a2713aSLionel Sambuc   case llvm::Triple::ppc64:
1460*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1461*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1462*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1463*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
1464f4a2713aSLionel Sambuc     break;
1465f4a2713aSLionel Sambuc   case llvm::Triple::ppc64le:
1466*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
1467*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
1468*0a6a1f1dSLionel Sambuc     break;
1469*0a6a1f1dSLionel Sambuc   case llvm::Triple::sparc:
1470*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1471*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1472*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1473*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1474*0a6a1f1dSLionel Sambuc     break;
1475*0a6a1f1dSLionel Sambuc   case llvm::Triple::sparcv9:
1476*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1477*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1478*0a6a1f1dSLionel Sambuc     BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1479*0a6a1f1dSLionel Sambuc     BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1480f4a2713aSLionel Sambuc     break;
1481f4a2713aSLionel Sambuc   case llvm::Triple::systemz:
1482*0a6a1f1dSLionel Sambuc     LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
1483*0a6a1f1dSLionel Sambuc     TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
1484f4a2713aSLionel Sambuc     break;
1485f4a2713aSLionel Sambuc 
1486f4a2713aSLionel Sambuc   default:
1487f4a2713aSLionel Sambuc     // By default, just rely on the standard lib directories and the original
1488f4a2713aSLionel Sambuc     // triple.
1489f4a2713aSLionel Sambuc     break;
1490f4a2713aSLionel Sambuc   }
1491f4a2713aSLionel Sambuc 
1492f4a2713aSLionel Sambuc   // Always append the drivers target triple to the end, in case it doesn't
1493f4a2713aSLionel Sambuc   // match any of our aliases.
1494f4a2713aSLionel Sambuc   TripleAliases.push_back(TargetTriple.str());
1495f4a2713aSLionel Sambuc 
1496f4a2713aSLionel Sambuc   // Also include the multiarch variant if it's different.
1497f4a2713aSLionel Sambuc   if (TargetTriple.str() != BiarchTriple.str())
1498f4a2713aSLionel Sambuc     BiarchTripleAliases.push_back(BiarchTriple.str());
1499f4a2713aSLionel Sambuc }
1500f4a2713aSLionel Sambuc 
1501*0a6a1f1dSLionel Sambuc namespace {
1502*0a6a1f1dSLionel Sambuc // Filter to remove Multilibs that don't exist as a suffix to Path
1503*0a6a1f1dSLionel Sambuc class FilterNonExistent : public MultilibSet::FilterCallback {
1504*0a6a1f1dSLionel Sambuc   std::string Base;
1505*0a6a1f1dSLionel Sambuc public:
FilterNonExistent(std::string Base)1506*0a6a1f1dSLionel Sambuc   FilterNonExistent(std::string Base) : Base(Base) {}
operator ()(const Multilib & M) const1507*0a6a1f1dSLionel Sambuc   bool operator()(const Multilib &M) const override {
1508*0a6a1f1dSLionel Sambuc     return !llvm::sys::fs::exists(Base + M.gccSuffix() + "/crtbegin.o");
1509*0a6a1f1dSLionel Sambuc   }
1510*0a6a1f1dSLionel Sambuc };
1511*0a6a1f1dSLionel Sambuc } // end anonymous namespace
1512f4a2713aSLionel Sambuc 
addMultilibFlag(bool Enabled,const char * const Flag,std::vector<std::string> & Flags)1513*0a6a1f1dSLionel Sambuc static void addMultilibFlag(bool Enabled, const char *const Flag,
1514*0a6a1f1dSLionel Sambuc                             std::vector<std::string> &Flags) {
1515*0a6a1f1dSLionel Sambuc   if (Enabled)
1516*0a6a1f1dSLionel Sambuc     Flags.push_back(std::string("+") + Flag);
1517*0a6a1f1dSLionel Sambuc   else
1518*0a6a1f1dSLionel Sambuc     Flags.push_back(std::string("-") + Flag);
1519f4a2713aSLionel Sambuc }
1520f4a2713aSLionel Sambuc 
isMipsArch(llvm::Triple::ArchType Arch)1521f4a2713aSLionel Sambuc static bool isMipsArch(llvm::Triple::ArchType Arch) {
1522*0a6a1f1dSLionel Sambuc   return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
1523*0a6a1f1dSLionel Sambuc          Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1524*0a6a1f1dSLionel Sambuc }
1525*0a6a1f1dSLionel Sambuc 
isMips32(llvm::Triple::ArchType Arch)1526*0a6a1f1dSLionel Sambuc static bool isMips32(llvm::Triple::ArchType Arch) {
1527*0a6a1f1dSLionel Sambuc   return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
1528*0a6a1f1dSLionel Sambuc }
1529*0a6a1f1dSLionel Sambuc 
isMips64(llvm::Triple::ArchType Arch)1530*0a6a1f1dSLionel Sambuc static bool isMips64(llvm::Triple::ArchType Arch) {
1531*0a6a1f1dSLionel Sambuc   return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1532*0a6a1f1dSLionel Sambuc }
1533*0a6a1f1dSLionel Sambuc 
isMipsEL(llvm::Triple::ArchType Arch)1534*0a6a1f1dSLionel Sambuc static bool isMipsEL(llvm::Triple::ArchType Arch) {
1535*0a6a1f1dSLionel Sambuc   return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
1536f4a2713aSLionel Sambuc }
1537f4a2713aSLionel Sambuc 
isMips16(const ArgList & Args)1538f4a2713aSLionel Sambuc static bool isMips16(const ArgList &Args) {
1539f4a2713aSLionel Sambuc   Arg *A = Args.getLastArg(options::OPT_mips16,
1540f4a2713aSLionel Sambuc                            options::OPT_mno_mips16);
1541f4a2713aSLionel Sambuc   return A && A->getOption().matches(options::OPT_mips16);
1542f4a2713aSLionel Sambuc }
1543f4a2713aSLionel Sambuc 
isMicroMips(const ArgList & Args)1544f4a2713aSLionel Sambuc static bool isMicroMips(const ArgList &Args) {
1545f4a2713aSLionel Sambuc   Arg *A = Args.getLastArg(options::OPT_mmicromips,
1546f4a2713aSLionel Sambuc                            options::OPT_mno_micromips);
1547f4a2713aSLionel Sambuc   return A && A->getOption().matches(options::OPT_mmicromips);
1548f4a2713aSLionel Sambuc }
1549f4a2713aSLionel Sambuc 
1550*0a6a1f1dSLionel Sambuc struct DetectedMultilibs {
1551*0a6a1f1dSLionel Sambuc   /// The set of multilibs that the detected installation supports.
1552*0a6a1f1dSLionel Sambuc   MultilibSet Multilibs;
1553*0a6a1f1dSLionel Sambuc 
1554*0a6a1f1dSLionel Sambuc   /// The primary multilib appropriate for the given flags.
1555*0a6a1f1dSLionel Sambuc   Multilib SelectedMultilib;
1556*0a6a1f1dSLionel Sambuc 
1557*0a6a1f1dSLionel Sambuc   /// On Biarch systems, this corresponds to the default multilib when
1558*0a6a1f1dSLionel Sambuc   /// targeting the non-default multilib. Otherwise, it is empty.
1559*0a6a1f1dSLionel Sambuc   llvm::Optional<Multilib> BiarchSibling;
1560*0a6a1f1dSLionel Sambuc };
1561*0a6a1f1dSLionel Sambuc 
makeMultilib(StringRef commonSuffix)1562*0a6a1f1dSLionel Sambuc static Multilib makeMultilib(StringRef commonSuffix) {
1563*0a6a1f1dSLionel Sambuc   return Multilib(commonSuffix, commonSuffix, commonSuffix);
1564f4a2713aSLionel Sambuc }
1565f4a2713aSLionel Sambuc 
findMIPSMultilibs(const llvm::Triple & TargetTriple,StringRef Path,const llvm::opt::ArgList & Args,DetectedMultilibs & Result)1566*0a6a1f1dSLionel Sambuc static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path,
1567*0a6a1f1dSLionel Sambuc                               const llvm::opt::ArgList &Args,
1568*0a6a1f1dSLionel Sambuc                               DetectedMultilibs &Result) {
1569f4a2713aSLionel Sambuc   // Some MIPS toolchains put libraries and object files compiled
1570f4a2713aSLionel Sambuc   // using different options in to the sub-directoris which names
1571f4a2713aSLionel Sambuc   // reflects the flags used for compilation. For example sysroot
1572f4a2713aSLionel Sambuc   // directory might looks like the following examples:
1573f4a2713aSLionel Sambuc   //
1574f4a2713aSLionel Sambuc   // /usr
1575f4a2713aSLionel Sambuc   //   /lib      <= crt*.o files compiled with '-mips32'
1576f4a2713aSLionel Sambuc   // /mips16
1577f4a2713aSLionel Sambuc   //   /usr
1578f4a2713aSLionel Sambuc   //     /lib    <= crt*.o files compiled with '-mips16'
1579f4a2713aSLionel Sambuc   //   /el
1580f4a2713aSLionel Sambuc   //     /usr
1581f4a2713aSLionel Sambuc   //       /lib  <= crt*.o files compiled with '-mips16 -EL'
1582f4a2713aSLionel Sambuc   //
1583f4a2713aSLionel Sambuc   // or
1584f4a2713aSLionel Sambuc   //
1585f4a2713aSLionel Sambuc   // /usr
1586f4a2713aSLionel Sambuc   //   /lib      <= crt*.o files compiled with '-mips32r2'
1587f4a2713aSLionel Sambuc   // /mips16
1588f4a2713aSLionel Sambuc   //   /usr
1589f4a2713aSLionel Sambuc   //     /lib    <= crt*.o files compiled with '-mips32r2 -mips16'
1590f4a2713aSLionel Sambuc   // /mips32
1591f4a2713aSLionel Sambuc   //     /usr
1592f4a2713aSLionel Sambuc   //       /lib  <= crt*.o files compiled with '-mips32'
1593f4a2713aSLionel Sambuc 
1594*0a6a1f1dSLionel Sambuc   FilterNonExistent NonExistent(Path);
1595f4a2713aSLionel Sambuc 
1596*0a6a1f1dSLionel Sambuc   // Check for FSF toolchain multilibs
1597*0a6a1f1dSLionel Sambuc   MultilibSet FSFMipsMultilibs;
1598*0a6a1f1dSLionel Sambuc   {
1599*0a6a1f1dSLionel Sambuc     auto MArchMips32 = makeMultilib("/mips32")
1600*0a6a1f1dSLionel Sambuc       .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32");
1601f4a2713aSLionel Sambuc 
1602*0a6a1f1dSLionel Sambuc     auto MArchMicroMips = makeMultilib("/micromips")
1603*0a6a1f1dSLionel Sambuc       .flag("+m32").flag("-m64").flag("+mmicromips");
1604f4a2713aSLionel Sambuc 
1605*0a6a1f1dSLionel Sambuc     auto MArchMips64r2 = makeMultilib("/mips64r2")
1606*0a6a1f1dSLionel Sambuc       .flag("-m32").flag("+m64").flag("+march=mips64r2");
1607f4a2713aSLionel Sambuc 
1608*0a6a1f1dSLionel Sambuc     auto MArchMips64 = makeMultilib("/mips64")
1609*0a6a1f1dSLionel Sambuc       .flag("-m32").flag("+m64").flag("-march=mips64r2");
1610*0a6a1f1dSLionel Sambuc 
1611*0a6a1f1dSLionel Sambuc     auto MArchDefault = makeMultilib("")
1612*0a6a1f1dSLionel Sambuc       .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32r2");
1613*0a6a1f1dSLionel Sambuc 
1614*0a6a1f1dSLionel Sambuc     auto Mips16 = makeMultilib("/mips16")
1615*0a6a1f1dSLionel Sambuc       .flag("+mips16");
1616*0a6a1f1dSLionel Sambuc 
1617*0a6a1f1dSLionel Sambuc     auto UCLibc = makeMultilib("/uclibc")
1618*0a6a1f1dSLionel Sambuc       .flag("+muclibc");
1619*0a6a1f1dSLionel Sambuc 
1620*0a6a1f1dSLionel Sambuc     auto MAbi64 = makeMultilib("/64")
1621*0a6a1f1dSLionel Sambuc       .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
1622*0a6a1f1dSLionel Sambuc 
1623*0a6a1f1dSLionel Sambuc     auto BigEndian = makeMultilib("")
1624*0a6a1f1dSLionel Sambuc       .flag("+EB").flag("-EL");
1625*0a6a1f1dSLionel Sambuc 
1626*0a6a1f1dSLionel Sambuc     auto LittleEndian = makeMultilib("/el")
1627*0a6a1f1dSLionel Sambuc       .flag("+EL").flag("-EB");
1628*0a6a1f1dSLionel Sambuc 
1629*0a6a1f1dSLionel Sambuc     auto SoftFloat = makeMultilib("/sof")
1630*0a6a1f1dSLionel Sambuc       .flag("+msoft-float");
1631*0a6a1f1dSLionel Sambuc 
1632*0a6a1f1dSLionel Sambuc     auto Nan2008 = makeMultilib("/nan2008")
1633*0a6a1f1dSLionel Sambuc       .flag("+mnan=2008");
1634*0a6a1f1dSLionel Sambuc 
1635*0a6a1f1dSLionel Sambuc     FSFMipsMultilibs = MultilibSet()
1636*0a6a1f1dSLionel Sambuc       .Either(MArchMips32, MArchMicroMips,
1637*0a6a1f1dSLionel Sambuc               MArchMips64r2, MArchMips64, MArchDefault)
1638*0a6a1f1dSLionel Sambuc       .Maybe(UCLibc)
1639*0a6a1f1dSLionel Sambuc       .Maybe(Mips16)
1640*0a6a1f1dSLionel Sambuc       .FilterOut("/mips64/mips16")
1641*0a6a1f1dSLionel Sambuc       .FilterOut("/mips64r2/mips16")
1642*0a6a1f1dSLionel Sambuc       .FilterOut("/micromips/mips16")
1643*0a6a1f1dSLionel Sambuc       .Maybe(MAbi64)
1644*0a6a1f1dSLionel Sambuc       .FilterOut("/micromips/64")
1645*0a6a1f1dSLionel Sambuc       .FilterOut("/mips32/64")
1646*0a6a1f1dSLionel Sambuc       .FilterOut("^/64")
1647*0a6a1f1dSLionel Sambuc       .FilterOut("/mips16/64")
1648*0a6a1f1dSLionel Sambuc       .Either(BigEndian, LittleEndian)
1649*0a6a1f1dSLionel Sambuc       .Maybe(SoftFloat)
1650*0a6a1f1dSLionel Sambuc       .Maybe(Nan2008)
1651*0a6a1f1dSLionel Sambuc       .FilterOut(".*sof/nan2008")
1652*0a6a1f1dSLionel Sambuc       .FilterOut(NonExistent)
1653*0a6a1f1dSLionel Sambuc       .setIncludeDirsCallback([](
1654*0a6a1f1dSLionel Sambuc           StringRef InstallDir, StringRef TripleStr, const Multilib &M) {
1655*0a6a1f1dSLionel Sambuc         std::vector<std::string> Dirs;
1656*0a6a1f1dSLionel Sambuc         Dirs.push_back((InstallDir + "/include").str());
1657*0a6a1f1dSLionel Sambuc         std::string SysRootInc = InstallDir.str() + "/../../../../sysroot";
1658*0a6a1f1dSLionel Sambuc         if (StringRef(M.includeSuffix()).startswith("/uclibc"))
1659*0a6a1f1dSLionel Sambuc           Dirs.push_back(SysRootInc + "/uclibc/usr/include");
1660f4a2713aSLionel Sambuc         else
1661*0a6a1f1dSLionel Sambuc           Dirs.push_back(SysRootInc + "/usr/include");
1662*0a6a1f1dSLionel Sambuc         return Dirs;
1663*0a6a1f1dSLionel Sambuc       });
1664f4a2713aSLionel Sambuc   }
1665f4a2713aSLionel Sambuc 
1666*0a6a1f1dSLionel Sambuc   // Check for Code Sourcery toolchain multilibs
1667*0a6a1f1dSLionel Sambuc   MultilibSet CSMipsMultilibs;
1668*0a6a1f1dSLionel Sambuc   {
1669*0a6a1f1dSLionel Sambuc     auto MArchMips16 = makeMultilib("/mips16")
1670*0a6a1f1dSLionel Sambuc       .flag("+m32").flag("+mips16");
1671f4a2713aSLionel Sambuc 
1672*0a6a1f1dSLionel Sambuc     auto MArchMicroMips = makeMultilib("/micromips")
1673*0a6a1f1dSLionel Sambuc       .flag("+m32").flag("+mmicromips");
1674*0a6a1f1dSLionel Sambuc 
1675*0a6a1f1dSLionel Sambuc     auto MArchDefault = makeMultilib("")
1676*0a6a1f1dSLionel Sambuc       .flag("-mips16").flag("-mmicromips");
1677*0a6a1f1dSLionel Sambuc 
1678*0a6a1f1dSLionel Sambuc     auto UCLibc = makeMultilib("/uclibc")
1679*0a6a1f1dSLionel Sambuc       .flag("+muclibc");
1680*0a6a1f1dSLionel Sambuc 
1681*0a6a1f1dSLionel Sambuc     auto SoftFloat = makeMultilib("/soft-float")
1682*0a6a1f1dSLionel Sambuc       .flag("+msoft-float");
1683*0a6a1f1dSLionel Sambuc 
1684*0a6a1f1dSLionel Sambuc     auto Nan2008 = makeMultilib("/nan2008")
1685*0a6a1f1dSLionel Sambuc       .flag("+mnan=2008");
1686*0a6a1f1dSLionel Sambuc 
1687*0a6a1f1dSLionel Sambuc     auto DefaultFloat = makeMultilib("")
1688*0a6a1f1dSLionel Sambuc       .flag("-msoft-float").flag("-mnan=2008");
1689*0a6a1f1dSLionel Sambuc 
1690*0a6a1f1dSLionel Sambuc     auto BigEndian = makeMultilib("")
1691*0a6a1f1dSLionel Sambuc       .flag("+EB").flag("-EL");
1692*0a6a1f1dSLionel Sambuc 
1693*0a6a1f1dSLionel Sambuc     auto LittleEndian = makeMultilib("/el")
1694*0a6a1f1dSLionel Sambuc       .flag("+EL").flag("-EB");
1695*0a6a1f1dSLionel Sambuc 
1696*0a6a1f1dSLionel Sambuc     // Note that this one's osSuffix is ""
1697*0a6a1f1dSLionel Sambuc     auto MAbi64 = makeMultilib("")
1698*0a6a1f1dSLionel Sambuc       .gccSuffix("/64")
1699*0a6a1f1dSLionel Sambuc       .includeSuffix("/64")
1700*0a6a1f1dSLionel Sambuc       .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
1701*0a6a1f1dSLionel Sambuc 
1702*0a6a1f1dSLionel Sambuc     CSMipsMultilibs = MultilibSet()
1703*0a6a1f1dSLionel Sambuc       .Either(MArchMips16, MArchMicroMips, MArchDefault)
1704*0a6a1f1dSLionel Sambuc       .Maybe(UCLibc)
1705*0a6a1f1dSLionel Sambuc       .Either(SoftFloat, Nan2008, DefaultFloat)
1706*0a6a1f1dSLionel Sambuc       .FilterOut("/micromips/nan2008")
1707*0a6a1f1dSLionel Sambuc       .FilterOut("/mips16/nan2008")
1708*0a6a1f1dSLionel Sambuc       .Either(BigEndian, LittleEndian)
1709*0a6a1f1dSLionel Sambuc       .Maybe(MAbi64)
1710*0a6a1f1dSLionel Sambuc       .FilterOut("/mips16.*/64")
1711*0a6a1f1dSLionel Sambuc       .FilterOut("/micromips.*/64")
1712*0a6a1f1dSLionel Sambuc       .FilterOut(NonExistent)
1713*0a6a1f1dSLionel Sambuc       .setIncludeDirsCallback([](
1714*0a6a1f1dSLionel Sambuc           StringRef InstallDir, StringRef TripleStr, const Multilib &M) {
1715*0a6a1f1dSLionel Sambuc         std::vector<std::string> Dirs;
1716*0a6a1f1dSLionel Sambuc         Dirs.push_back((InstallDir + "/include").str());
1717*0a6a1f1dSLionel Sambuc         std::string SysRootInc =
1718*0a6a1f1dSLionel Sambuc             InstallDir.str() + "/../../../../" + TripleStr.str();
1719*0a6a1f1dSLionel Sambuc         if (StringRef(M.includeSuffix()).startswith("/uclibc"))
1720*0a6a1f1dSLionel Sambuc           Dirs.push_back(SysRootInc + "/libc/uclibc/usr/include");
1721*0a6a1f1dSLionel Sambuc         else
1722*0a6a1f1dSLionel Sambuc           Dirs.push_back(SysRootInc + "/libc/usr/include");
1723*0a6a1f1dSLionel Sambuc         return Dirs;
1724*0a6a1f1dSLionel Sambuc       });
1725f4a2713aSLionel Sambuc   }
1726f4a2713aSLionel Sambuc 
1727*0a6a1f1dSLionel Sambuc   MultilibSet AndroidMipsMultilibs = MultilibSet()
1728*0a6a1f1dSLionel Sambuc     .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
1729*0a6a1f1dSLionel Sambuc     .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
1730*0a6a1f1dSLionel Sambuc     .FilterOut(NonExistent);
1731*0a6a1f1dSLionel Sambuc 
1732*0a6a1f1dSLionel Sambuc   MultilibSet DebianMipsMultilibs;
1733*0a6a1f1dSLionel Sambuc   {
1734*0a6a1f1dSLionel Sambuc     Multilib MAbiN32 = Multilib()
1735*0a6a1f1dSLionel Sambuc       .gccSuffix("/n32")
1736*0a6a1f1dSLionel Sambuc       .includeSuffix("/n32")
1737*0a6a1f1dSLionel Sambuc       .flag("+mabi=n32");
1738*0a6a1f1dSLionel Sambuc 
1739*0a6a1f1dSLionel Sambuc     Multilib M64 = Multilib()
1740*0a6a1f1dSLionel Sambuc       .gccSuffix("/64")
1741*0a6a1f1dSLionel Sambuc       .includeSuffix("/64")
1742*0a6a1f1dSLionel Sambuc       .flag("+m64").flag("-m32").flag("-mabi=n32");
1743*0a6a1f1dSLionel Sambuc 
1744*0a6a1f1dSLionel Sambuc     Multilib M32 = Multilib()
1745*0a6a1f1dSLionel Sambuc       .flag("-m64").flag("+m32").flag("-mabi=n32");
1746*0a6a1f1dSLionel Sambuc 
1747*0a6a1f1dSLionel Sambuc     DebianMipsMultilibs = MultilibSet()
1748*0a6a1f1dSLionel Sambuc       .Either(M32, M64, MAbiN32)
1749*0a6a1f1dSLionel Sambuc       .FilterOut(NonExistent);
1750*0a6a1f1dSLionel Sambuc   }
1751*0a6a1f1dSLionel Sambuc 
1752*0a6a1f1dSLionel Sambuc   MultilibSet ImgMultilibs;
1753*0a6a1f1dSLionel Sambuc   {
1754*0a6a1f1dSLionel Sambuc     auto Mips64r6 = makeMultilib("/mips64r6")
1755*0a6a1f1dSLionel Sambuc       .flag("+m64").flag("-m32");
1756*0a6a1f1dSLionel Sambuc 
1757*0a6a1f1dSLionel Sambuc     auto LittleEndian = makeMultilib("/el")
1758*0a6a1f1dSLionel Sambuc       .flag("+EL").flag("-EB");
1759*0a6a1f1dSLionel Sambuc 
1760*0a6a1f1dSLionel Sambuc     auto MAbi64 = makeMultilib("/64")
1761*0a6a1f1dSLionel Sambuc       .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
1762*0a6a1f1dSLionel Sambuc 
1763*0a6a1f1dSLionel Sambuc     ImgMultilibs = MultilibSet()
1764*0a6a1f1dSLionel Sambuc       .Maybe(Mips64r6)
1765*0a6a1f1dSLionel Sambuc       .Maybe(MAbi64)
1766*0a6a1f1dSLionel Sambuc       .Maybe(LittleEndian)
1767*0a6a1f1dSLionel Sambuc       .FilterOut(NonExistent)
1768*0a6a1f1dSLionel Sambuc       .setIncludeDirsCallback([](
1769*0a6a1f1dSLionel Sambuc           StringRef InstallDir, StringRef TripleStr, const Multilib &M) {
1770*0a6a1f1dSLionel Sambuc         std::vector<std::string> Dirs;
1771*0a6a1f1dSLionel Sambuc         Dirs.push_back((InstallDir + "/include").str());
1772*0a6a1f1dSLionel Sambuc         Dirs.push_back((InstallDir + "/../../../../sysroot/usr/include").str());
1773*0a6a1f1dSLionel Sambuc         return Dirs;
1774*0a6a1f1dSLionel Sambuc       });
1775*0a6a1f1dSLionel Sambuc   }
1776*0a6a1f1dSLionel Sambuc 
1777*0a6a1f1dSLionel Sambuc   StringRef CPUName;
1778*0a6a1f1dSLionel Sambuc   StringRef ABIName;
1779*0a6a1f1dSLionel Sambuc   tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
1780*0a6a1f1dSLionel Sambuc 
1781*0a6a1f1dSLionel Sambuc   llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
1782*0a6a1f1dSLionel Sambuc 
1783*0a6a1f1dSLionel Sambuc   Multilib::flags_list Flags;
1784*0a6a1f1dSLionel Sambuc   addMultilibFlag(isMips32(TargetArch), "m32", Flags);
1785*0a6a1f1dSLionel Sambuc   addMultilibFlag(isMips64(TargetArch), "m64", Flags);
1786*0a6a1f1dSLionel Sambuc   addMultilibFlag(isMips16(Args), "mips16", Flags);
1787*0a6a1f1dSLionel Sambuc   addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
1788*0a6a1f1dSLionel Sambuc   addMultilibFlag(CPUName == "mips32r2", "march=mips32r2", Flags);
1789*0a6a1f1dSLionel Sambuc   addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
1790*0a6a1f1dSLionel Sambuc   addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
1791*0a6a1f1dSLionel Sambuc   addMultilibFlag(CPUName == "mips64r2" || CPUName == "octeon",
1792*0a6a1f1dSLionel Sambuc                   "march=mips64r2", Flags);
1793*0a6a1f1dSLionel Sambuc   addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
1794*0a6a1f1dSLionel Sambuc   addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
1795*0a6a1f1dSLionel Sambuc   addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
1796*0a6a1f1dSLionel Sambuc                   Flags);
1797*0a6a1f1dSLionel Sambuc   addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
1798*0a6a1f1dSLionel Sambuc   addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
1799*0a6a1f1dSLionel Sambuc   addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
1800*0a6a1f1dSLionel Sambuc   addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
1801*0a6a1f1dSLionel Sambuc   addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
1802*0a6a1f1dSLionel Sambuc   addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
1803*0a6a1f1dSLionel Sambuc 
1804*0a6a1f1dSLionel Sambuc   if (TargetTriple.getEnvironment() == llvm::Triple::Android) {
1805*0a6a1f1dSLionel Sambuc     // Select Android toolchain. It's the only choice in that case.
1806*0a6a1f1dSLionel Sambuc     if (AndroidMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
1807*0a6a1f1dSLionel Sambuc       Result.Multilibs = AndroidMipsMultilibs;
1808*0a6a1f1dSLionel Sambuc       return true;
1809*0a6a1f1dSLionel Sambuc     }
1810*0a6a1f1dSLionel Sambuc     return false;
1811*0a6a1f1dSLionel Sambuc   }
1812*0a6a1f1dSLionel Sambuc 
1813*0a6a1f1dSLionel Sambuc   if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
1814*0a6a1f1dSLionel Sambuc       TargetTriple.getOS() == llvm::Triple::Linux &&
1815*0a6a1f1dSLionel Sambuc       TargetTriple.getEnvironment() == llvm::Triple::GNU) {
1816*0a6a1f1dSLionel Sambuc     // Select mips-img-linux-gnu toolchain.
1817*0a6a1f1dSLionel Sambuc     if (ImgMultilibs.select(Flags, Result.SelectedMultilib)) {
1818*0a6a1f1dSLionel Sambuc       Result.Multilibs = ImgMultilibs;
1819*0a6a1f1dSLionel Sambuc       return true;
1820*0a6a1f1dSLionel Sambuc     }
1821*0a6a1f1dSLionel Sambuc     return false;
1822*0a6a1f1dSLionel Sambuc   }
1823*0a6a1f1dSLionel Sambuc 
1824*0a6a1f1dSLionel Sambuc   // Sort candidates. Toolchain that best meets the directories goes first.
1825*0a6a1f1dSLionel Sambuc   // Then select the first toolchains matches command line flags.
1826*0a6a1f1dSLionel Sambuc   MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs,
1827*0a6a1f1dSLionel Sambuc                                 &CSMipsMultilibs };
1828*0a6a1f1dSLionel Sambuc   std::sort(
1829*0a6a1f1dSLionel Sambuc       std::begin(candidates), std::end(candidates),
1830*0a6a1f1dSLionel Sambuc       [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); });
1831*0a6a1f1dSLionel Sambuc   for (const auto &candidate : candidates) {
1832*0a6a1f1dSLionel Sambuc     if (candidate->select(Flags, Result.SelectedMultilib)) {
1833*0a6a1f1dSLionel Sambuc       if (candidate == &DebianMipsMultilibs)
1834*0a6a1f1dSLionel Sambuc         Result.BiarchSibling = Multilib();
1835*0a6a1f1dSLionel Sambuc       Result.Multilibs = *candidate;
1836*0a6a1f1dSLionel Sambuc       return true;
1837*0a6a1f1dSLionel Sambuc     }
1838*0a6a1f1dSLionel Sambuc   }
1839*0a6a1f1dSLionel Sambuc 
1840*0a6a1f1dSLionel Sambuc   {
1841*0a6a1f1dSLionel Sambuc     // Fallback to the regular toolchain-tree structure.
1842*0a6a1f1dSLionel Sambuc     Multilib Default;
1843*0a6a1f1dSLionel Sambuc     Result.Multilibs.push_back(Default);
1844*0a6a1f1dSLionel Sambuc     Result.Multilibs.FilterOut(NonExistent);
1845*0a6a1f1dSLionel Sambuc 
1846*0a6a1f1dSLionel Sambuc     if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
1847*0a6a1f1dSLionel Sambuc       Result.BiarchSibling = Multilib();
1848*0a6a1f1dSLionel Sambuc       return true;
1849*0a6a1f1dSLionel Sambuc     }
1850*0a6a1f1dSLionel Sambuc   }
1851*0a6a1f1dSLionel Sambuc 
1852*0a6a1f1dSLionel Sambuc   return false;
1853*0a6a1f1dSLionel Sambuc }
1854*0a6a1f1dSLionel Sambuc 
findBiarchMultilibs(const llvm::Triple & TargetTriple,StringRef Path,const ArgList & Args,bool NeedsBiarchSuffix,DetectedMultilibs & Result)1855*0a6a1f1dSLionel Sambuc static bool findBiarchMultilibs(const llvm::Triple &TargetTriple,
1856*0a6a1f1dSLionel Sambuc                                 StringRef Path, const ArgList &Args,
1857*0a6a1f1dSLionel Sambuc                                 bool NeedsBiarchSuffix,
1858*0a6a1f1dSLionel Sambuc                                 DetectedMultilibs &Result) {
1859*0a6a1f1dSLionel Sambuc 
1860*0a6a1f1dSLionel Sambuc   // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
1861*0a6a1f1dSLionel Sambuc   // in what would normally be GCCInstallPath and put the 64-bit
1862*0a6a1f1dSLionel Sambuc   // libs in a subdirectory named 64. The simple logic we follow is that
1863*0a6a1f1dSLionel Sambuc   // *if* there is a subdirectory of the right name with crtbegin.o in it,
1864*0a6a1f1dSLionel Sambuc   // we use that. If not, and if not a biarch triple alias, we look for
1865*0a6a1f1dSLionel Sambuc   // crtbegin.o without the subdirectory.
1866*0a6a1f1dSLionel Sambuc 
1867*0a6a1f1dSLionel Sambuc   Multilib Default;
1868*0a6a1f1dSLionel Sambuc   Multilib Alt64 = Multilib()
1869*0a6a1f1dSLionel Sambuc     .gccSuffix("/64")
1870*0a6a1f1dSLionel Sambuc     .includeSuffix("/64")
1871*0a6a1f1dSLionel Sambuc     .flag("-m32").flag("+m64").flag("-mx32");
1872*0a6a1f1dSLionel Sambuc   Multilib Alt32 = Multilib()
1873*0a6a1f1dSLionel Sambuc     .gccSuffix("/32")
1874*0a6a1f1dSLionel Sambuc     .includeSuffix("/32")
1875*0a6a1f1dSLionel Sambuc     .flag("+m32").flag("-m64").flag("-mx32");
1876*0a6a1f1dSLionel Sambuc   Multilib Altx32 = Multilib()
1877*0a6a1f1dSLionel Sambuc     .gccSuffix("/x32")
1878*0a6a1f1dSLionel Sambuc     .includeSuffix("/x32")
1879*0a6a1f1dSLionel Sambuc     .flag("-m32").flag("-m64").flag("+mx32");
1880*0a6a1f1dSLionel Sambuc 
1881*0a6a1f1dSLionel Sambuc   FilterNonExistent NonExistent(Path);
1882*0a6a1f1dSLionel Sambuc 
1883*0a6a1f1dSLionel Sambuc   // Determine default multilib from: 32, 64, x32
1884*0a6a1f1dSLionel Sambuc   // Also handle cases such as 64 on 32, 32 on 64, etc.
1885*0a6a1f1dSLionel Sambuc   enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
1886*0a6a1f1dSLionel Sambuc   const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32;
1887*0a6a1f1dSLionel Sambuc   if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
1888*0a6a1f1dSLionel Sambuc     Want = WANT64;
1889*0a6a1f1dSLionel Sambuc   else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
1890*0a6a1f1dSLionel Sambuc     Want = WANT64;
1891*0a6a1f1dSLionel Sambuc   else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
1892*0a6a1f1dSLionel Sambuc     Want = WANT32;
1893*0a6a1f1dSLionel Sambuc   else {
1894*0a6a1f1dSLionel Sambuc     if (TargetTriple.isArch32Bit())
1895*0a6a1f1dSLionel Sambuc       Want = NeedsBiarchSuffix ? WANT64 : WANT32;
1896*0a6a1f1dSLionel Sambuc     else if (IsX32)
1897*0a6a1f1dSLionel Sambuc       Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
1898*0a6a1f1dSLionel Sambuc     else
1899*0a6a1f1dSLionel Sambuc       Want = NeedsBiarchSuffix ? WANT32 : WANT64;
1900*0a6a1f1dSLionel Sambuc   }
1901*0a6a1f1dSLionel Sambuc 
1902*0a6a1f1dSLionel Sambuc   if (Want == WANT32)
1903*0a6a1f1dSLionel Sambuc     Default.flag("+m32").flag("-m64").flag("-mx32");
1904*0a6a1f1dSLionel Sambuc   else if (Want == WANT64)
1905*0a6a1f1dSLionel Sambuc     Default.flag("-m32").flag("+m64").flag("-mx32");
1906*0a6a1f1dSLionel Sambuc   else if (Want == WANTX32)
1907*0a6a1f1dSLionel Sambuc     Default.flag("-m32").flag("-m64").flag("+mx32");
1908*0a6a1f1dSLionel Sambuc   else
1909*0a6a1f1dSLionel Sambuc     return false;
1910*0a6a1f1dSLionel Sambuc 
1911*0a6a1f1dSLionel Sambuc   Result.Multilibs.push_back(Default);
1912*0a6a1f1dSLionel Sambuc   Result.Multilibs.push_back(Alt64);
1913*0a6a1f1dSLionel Sambuc   Result.Multilibs.push_back(Alt32);
1914*0a6a1f1dSLionel Sambuc   Result.Multilibs.push_back(Altx32);
1915*0a6a1f1dSLionel Sambuc 
1916*0a6a1f1dSLionel Sambuc   Result.Multilibs.FilterOut(NonExistent);
1917*0a6a1f1dSLionel Sambuc 
1918*0a6a1f1dSLionel Sambuc   Multilib::flags_list Flags;
1919*0a6a1f1dSLionel Sambuc   addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
1920*0a6a1f1dSLionel Sambuc   addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
1921*0a6a1f1dSLionel Sambuc   addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
1922*0a6a1f1dSLionel Sambuc 
1923*0a6a1f1dSLionel Sambuc   if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
1924*0a6a1f1dSLionel Sambuc     return false;
1925*0a6a1f1dSLionel Sambuc 
1926*0a6a1f1dSLionel Sambuc   if (Result.SelectedMultilib == Alt64 ||
1927*0a6a1f1dSLionel Sambuc       Result.SelectedMultilib == Alt32 ||
1928*0a6a1f1dSLionel Sambuc       Result.SelectedMultilib == Altx32)
1929*0a6a1f1dSLionel Sambuc     Result.BiarchSibling = Default;
1930*0a6a1f1dSLionel Sambuc 
1931*0a6a1f1dSLionel Sambuc   return true;
1932f4a2713aSLionel Sambuc }
1933f4a2713aSLionel Sambuc 
ScanLibDirForGCCTriple(const llvm::Triple & TargetTriple,const ArgList & Args,const std::string & LibDir,StringRef CandidateTriple,bool NeedsBiarchSuffix)1934f4a2713aSLionel Sambuc void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
1935*0a6a1f1dSLionel Sambuc     const llvm::Triple &TargetTriple, const ArgList &Args,
1936f4a2713aSLionel Sambuc     const std::string &LibDir, StringRef CandidateTriple,
1937f4a2713aSLionel Sambuc     bool NeedsBiarchSuffix) {
1938*0a6a1f1dSLionel Sambuc   llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
1939f4a2713aSLionel Sambuc   // There are various different suffixes involving the triple we
1940f4a2713aSLionel Sambuc   // check for. We also record what is necessary to walk from each back
1941f4a2713aSLionel Sambuc   // up to the lib directory.
1942f4a2713aSLionel Sambuc   const std::string LibSuffixes[] = {
1943f4a2713aSLionel Sambuc     "/gcc/" + CandidateTriple.str(),
1944f4a2713aSLionel Sambuc     // Debian puts cross-compilers in gcc-cross
1945f4a2713aSLionel Sambuc     "/gcc-cross/" + CandidateTriple.str(),
1946f4a2713aSLionel Sambuc     "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
1947f4a2713aSLionel Sambuc 
1948f4a2713aSLionel Sambuc     // The Freescale PPC SDK has the gcc libraries in
1949f4a2713aSLionel Sambuc     // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
1950f4a2713aSLionel Sambuc     "/" + CandidateTriple.str(),
1951f4a2713aSLionel Sambuc 
1952f4a2713aSLionel Sambuc     // Ubuntu has a strange mis-matched pair of triples that this happens to
1953f4a2713aSLionel Sambuc     // match.
1954f4a2713aSLionel Sambuc     // FIXME: It may be worthwhile to generalize this and look for a second
1955f4a2713aSLionel Sambuc     // triple.
1956f4a2713aSLionel Sambuc     "/i386-linux-gnu/gcc/" + CandidateTriple.str()
1957f4a2713aSLionel Sambuc   };
1958f4a2713aSLionel Sambuc   const std::string InstallSuffixes[] = {
1959f4a2713aSLionel Sambuc     "/../../..",    // gcc/
1960f4a2713aSLionel Sambuc     "/../../..",    // gcc-cross/
1961f4a2713aSLionel Sambuc     "/../../../..", // <triple>/gcc/
1962f4a2713aSLionel Sambuc     "/../..",       // <triple>/
1963f4a2713aSLionel Sambuc     "/../../../.."  // i386-linux-gnu/gcc/<triple>/
1964f4a2713aSLionel Sambuc   };
1965f4a2713aSLionel Sambuc   // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
1966f4a2713aSLionel Sambuc   const unsigned NumLibSuffixes =
1967f4a2713aSLionel Sambuc       (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
1968f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumLibSuffixes; ++i) {
1969f4a2713aSLionel Sambuc     StringRef LibSuffix = LibSuffixes[i];
1970*0a6a1f1dSLionel Sambuc     std::error_code EC;
1971f4a2713aSLionel Sambuc     for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
1972f4a2713aSLionel Sambuc          !EC && LI != LE; LI = LI.increment(EC)) {
1973f4a2713aSLionel Sambuc       StringRef VersionText = llvm::sys::path::filename(LI->path());
1974f4a2713aSLionel Sambuc       GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
1975f4a2713aSLionel Sambuc       if (CandidateVersion.Major != -1) // Filter obviously bad entries.
1976f4a2713aSLionel Sambuc         if (!CandidateGCCInstallPaths.insert(LI->path()).second)
1977f4a2713aSLionel Sambuc           continue; // Saw this path before; no need to look at it again.
1978f4a2713aSLionel Sambuc       if (CandidateVersion.isOlderThan(4, 1, 1))
1979f4a2713aSLionel Sambuc         continue;
1980f4a2713aSLionel Sambuc       if (CandidateVersion <= Version)
1981f4a2713aSLionel Sambuc         continue;
1982f4a2713aSLionel Sambuc 
1983*0a6a1f1dSLionel Sambuc       DetectedMultilibs Detected;
1984f4a2713aSLionel Sambuc 
1985*0a6a1f1dSLionel Sambuc       // Debian mips multilibs behave more like the rest of the biarch ones,
1986*0a6a1f1dSLionel Sambuc       // so handle them there
1987*0a6a1f1dSLionel Sambuc       if (isMipsArch(TargetArch)) {
1988*0a6a1f1dSLionel Sambuc         if (!findMIPSMultilibs(TargetTriple, LI->path(), Args, Detected))
1989f4a2713aSLionel Sambuc           continue;
1990*0a6a1f1dSLionel Sambuc       } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args,
1991*0a6a1f1dSLionel Sambuc                                       NeedsBiarchSuffix, Detected)) {
1992*0a6a1f1dSLionel Sambuc         continue;
1993f4a2713aSLionel Sambuc       }
1994f4a2713aSLionel Sambuc 
1995*0a6a1f1dSLionel Sambuc       Multilibs = Detected.Multilibs;
1996*0a6a1f1dSLionel Sambuc       SelectedMultilib = Detected.SelectedMultilib;
1997*0a6a1f1dSLionel Sambuc       BiarchSibling = Detected.BiarchSibling;
1998f4a2713aSLionel Sambuc       Version = CandidateVersion;
1999f4a2713aSLionel Sambuc       GCCTriple.setTriple(CandidateTriple);
2000f4a2713aSLionel Sambuc       // FIXME: We hack together the directory name here instead of
2001f4a2713aSLionel Sambuc       // using LI to ensure stable path separators across Windows and
2002f4a2713aSLionel Sambuc       // Linux.
2003f4a2713aSLionel Sambuc       GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
2004f4a2713aSLionel Sambuc       GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
2005f4a2713aSLionel Sambuc       IsValid = true;
2006f4a2713aSLionel Sambuc     }
2007f4a2713aSLionel Sambuc   }
2008f4a2713aSLionel Sambuc }
2009f4a2713aSLionel Sambuc 
Generic_GCC(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2010f4a2713aSLionel Sambuc Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
2011f4a2713aSLionel Sambuc                          const ArgList &Args)
2012*0a6a1f1dSLionel Sambuc   : ToolChain(D, Triple, Args), GCCInstallation() {
2013f4a2713aSLionel Sambuc   getProgramPaths().push_back(getDriver().getInstalledDir());
2014f4a2713aSLionel Sambuc   if (getDriver().getInstalledDir() != getDriver().Dir)
2015f4a2713aSLionel Sambuc     getProgramPaths().push_back(getDriver().Dir);
2016f4a2713aSLionel Sambuc }
2017f4a2713aSLionel Sambuc 
~Generic_GCC()2018f4a2713aSLionel Sambuc Generic_GCC::~Generic_GCC() {
2019f4a2713aSLionel Sambuc }
2020f4a2713aSLionel Sambuc 
getTool(Action::ActionClass AC) const2021f4a2713aSLionel Sambuc Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
2022f4a2713aSLionel Sambuc   switch (AC) {
2023f4a2713aSLionel Sambuc   case Action::PreprocessJobClass:
2024f4a2713aSLionel Sambuc     if (!Preprocess)
2025f4a2713aSLionel Sambuc       Preprocess.reset(new tools::gcc::Preprocess(*this));
2026f4a2713aSLionel Sambuc     return Preprocess.get();
2027f4a2713aSLionel Sambuc   case Action::CompileJobClass:
2028f4a2713aSLionel Sambuc     if (!Compile)
2029f4a2713aSLionel Sambuc       Compile.reset(new tools::gcc::Compile(*this));
2030f4a2713aSLionel Sambuc     return Compile.get();
2031f4a2713aSLionel Sambuc   default:
2032f4a2713aSLionel Sambuc     return ToolChain::getTool(AC);
2033f4a2713aSLionel Sambuc   }
2034f4a2713aSLionel Sambuc }
2035f4a2713aSLionel Sambuc 
buildAssembler() const2036f4a2713aSLionel Sambuc Tool *Generic_GCC::buildAssembler() const {
2037*0a6a1f1dSLionel Sambuc   return new tools::gnutools::Assemble(*this);
2038f4a2713aSLionel Sambuc }
2039f4a2713aSLionel Sambuc 
buildLinker() const2040f4a2713aSLionel Sambuc Tool *Generic_GCC::buildLinker() const {
2041f4a2713aSLionel Sambuc   return new tools::gcc::Link(*this);
2042f4a2713aSLionel Sambuc }
2043f4a2713aSLionel Sambuc 
printVerboseInfo(raw_ostream & OS) const2044f4a2713aSLionel Sambuc void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
2045f4a2713aSLionel Sambuc   // Print the information about how we detected the GCC installation.
2046f4a2713aSLionel Sambuc   GCCInstallation.print(OS);
2047f4a2713aSLionel Sambuc }
2048f4a2713aSLionel Sambuc 
IsUnwindTablesDefault() const2049f4a2713aSLionel Sambuc bool Generic_GCC::IsUnwindTablesDefault() const {
2050f4a2713aSLionel Sambuc   return getArch() == llvm::Triple::x86_64;
2051f4a2713aSLionel Sambuc }
2052f4a2713aSLionel Sambuc 
isPICDefault() const2053f4a2713aSLionel Sambuc bool Generic_GCC::isPICDefault() const {
2054f4a2713aSLionel Sambuc   return false;
2055f4a2713aSLionel Sambuc }
2056f4a2713aSLionel Sambuc 
isPIEDefault() const2057f4a2713aSLionel Sambuc bool Generic_GCC::isPIEDefault() const {
2058f4a2713aSLionel Sambuc   return false;
2059f4a2713aSLionel Sambuc }
2060f4a2713aSLionel Sambuc 
isPICDefaultForced() const2061f4a2713aSLionel Sambuc bool Generic_GCC::isPICDefaultForced() const {
2062f4a2713aSLionel Sambuc   return false;
2063f4a2713aSLionel Sambuc }
2064f4a2713aSLionel Sambuc 
IsIntegratedAssemblerDefault() const2065*0a6a1f1dSLionel Sambuc bool Generic_GCC::IsIntegratedAssemblerDefault() const {
2066*0a6a1f1dSLionel Sambuc   return getTriple().getArch() == llvm::Triple::x86 ||
2067*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::x86_64 ||
2068*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::aarch64 ||
2069*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::aarch64_be ||
2070*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::arm ||
2071*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::armeb ||
2072*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::thumb ||
2073*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::thumbeb ||
2074*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::ppc ||
2075*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::ppc64 ||
2076*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::ppc64le ||
2077*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::sparc ||
2078*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::sparcv9 ||
2079*0a6a1f1dSLionel Sambuc          getTriple().getArch() == llvm::Triple::systemz;
2080*0a6a1f1dSLionel Sambuc }
2081*0a6a1f1dSLionel Sambuc 
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args) const2082*0a6a1f1dSLionel Sambuc void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
2083*0a6a1f1dSLionel Sambuc                                         ArgStringList &CC1Args) const {
2084*0a6a1f1dSLionel Sambuc   const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
2085*0a6a1f1dSLionel Sambuc   bool UseInitArrayDefault =
2086*0a6a1f1dSLionel Sambuc       getTriple().getArch() == llvm::Triple::aarch64 ||
2087*0a6a1f1dSLionel Sambuc       getTriple().getArch() == llvm::Triple::aarch64_be ||
2088*0a6a1f1dSLionel Sambuc       (getTriple().getOS() == llvm::Triple::Linux &&
2089*0a6a1f1dSLionel Sambuc        (!V.isOlderThan(4, 7, 0) ||
2090*0a6a1f1dSLionel Sambuc         getTriple().getEnvironment() == llvm::Triple::Android));
2091*0a6a1f1dSLionel Sambuc 
2092*0a6a1f1dSLionel Sambuc   if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
2093*0a6a1f1dSLionel Sambuc                          options::OPT_fno_use_init_array,
2094*0a6a1f1dSLionel Sambuc                          UseInitArrayDefault))
2095*0a6a1f1dSLionel Sambuc     CC1Args.push_back("-fuse-init-array");
2096*0a6a1f1dSLionel Sambuc }
2097*0a6a1f1dSLionel Sambuc 
2098f4a2713aSLionel Sambuc /// Hexagon Toolchain
2099f4a2713aSLionel Sambuc 
GetGnuDir(const std::string & InstalledDir,const ArgList & Args)2100*0a6a1f1dSLionel Sambuc std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir,
2101*0a6a1f1dSLionel Sambuc                                   const ArgList &Args) {
2102f4a2713aSLionel Sambuc 
2103f4a2713aSLionel Sambuc   // Locate the rest of the toolchain ...
2104*0a6a1f1dSLionel Sambuc   std::string GccToolchain = getGCCToolchainDir(Args);
2105*0a6a1f1dSLionel Sambuc 
2106*0a6a1f1dSLionel Sambuc   if (!GccToolchain.empty())
2107*0a6a1f1dSLionel Sambuc     return GccToolchain;
2108f4a2713aSLionel Sambuc 
2109f4a2713aSLionel Sambuc   std::string InstallRelDir = InstalledDir + "/../../gnu";
2110f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(InstallRelDir))
2111f4a2713aSLionel Sambuc     return InstallRelDir;
2112f4a2713aSLionel Sambuc 
2113f4a2713aSLionel Sambuc   std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
2114f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(PrefixRelDir))
2115f4a2713aSLionel Sambuc     return PrefixRelDir;
2116f4a2713aSLionel Sambuc 
2117f4a2713aSLionel Sambuc   return InstallRelDir;
2118f4a2713aSLionel Sambuc }
2119f4a2713aSLionel Sambuc 
GetHexagonLibraryPaths(const ArgList & Args,const std::string & Ver,const std::string & MarchString,const std::string & InstalledDir,ToolChain::path_list * LibPaths)2120f4a2713aSLionel Sambuc static void GetHexagonLibraryPaths(
2121f4a2713aSLionel Sambuc   const ArgList &Args,
2122*0a6a1f1dSLionel Sambuc   const std::string &Ver,
2123*0a6a1f1dSLionel Sambuc   const std::string &MarchString,
2124f4a2713aSLionel Sambuc   const std::string &InstalledDir,
2125f4a2713aSLionel Sambuc   ToolChain::path_list *LibPaths)
2126f4a2713aSLionel Sambuc {
2127f4a2713aSLionel Sambuc   bool buildingLib = Args.hasArg(options::OPT_shared);
2128f4a2713aSLionel Sambuc 
2129f4a2713aSLionel Sambuc   //----------------------------------------------------------------------------
2130f4a2713aSLionel Sambuc   // -L Args
2131f4a2713aSLionel Sambuc   //----------------------------------------------------------------------------
2132f4a2713aSLionel Sambuc   for (arg_iterator
2133f4a2713aSLionel Sambuc          it = Args.filtered_begin(options::OPT_L),
2134f4a2713aSLionel Sambuc          ie = Args.filtered_end();
2135f4a2713aSLionel Sambuc        it != ie;
2136f4a2713aSLionel Sambuc        ++it) {
2137f4a2713aSLionel Sambuc     for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
2138f4a2713aSLionel Sambuc       LibPaths->push_back((*it)->getValue(i));
2139f4a2713aSLionel Sambuc   }
2140f4a2713aSLionel Sambuc 
2141f4a2713aSLionel Sambuc   //----------------------------------------------------------------------------
2142f4a2713aSLionel Sambuc   // Other standard paths
2143f4a2713aSLionel Sambuc   //----------------------------------------------------------------------------
2144f4a2713aSLionel Sambuc   const std::string MarchSuffix = "/" + MarchString;
2145f4a2713aSLionel Sambuc   const std::string G0Suffix = "/G0";
2146f4a2713aSLionel Sambuc   const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
2147*0a6a1f1dSLionel Sambuc   const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir, Args) + "/";
2148f4a2713aSLionel Sambuc 
2149f4a2713aSLionel Sambuc   // lib/gcc/hexagon/...
2150f4a2713aSLionel Sambuc   std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
2151f4a2713aSLionel Sambuc   if (buildingLib) {
2152f4a2713aSLionel Sambuc     LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
2153f4a2713aSLionel Sambuc     LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
2154f4a2713aSLionel Sambuc   }
2155f4a2713aSLionel Sambuc   LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
2156f4a2713aSLionel Sambuc   LibPaths->push_back(LibGCCHexagonDir + Ver);
2157f4a2713aSLionel Sambuc 
2158f4a2713aSLionel Sambuc   // lib/gcc/...
2159f4a2713aSLionel Sambuc   LibPaths->push_back(RootDir + "lib/gcc");
2160f4a2713aSLionel Sambuc 
2161f4a2713aSLionel Sambuc   // hexagon/lib/...
2162f4a2713aSLionel Sambuc   std::string HexagonLibDir = RootDir + "hexagon/lib";
2163f4a2713aSLionel Sambuc   if (buildingLib) {
2164f4a2713aSLionel Sambuc     LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
2165f4a2713aSLionel Sambuc     LibPaths->push_back(HexagonLibDir + G0Suffix);
2166f4a2713aSLionel Sambuc   }
2167f4a2713aSLionel Sambuc   LibPaths->push_back(HexagonLibDir + MarchSuffix);
2168f4a2713aSLionel Sambuc   LibPaths->push_back(HexagonLibDir);
2169f4a2713aSLionel Sambuc }
2170f4a2713aSLionel Sambuc 
Hexagon_TC(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2171f4a2713aSLionel Sambuc Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
2172f4a2713aSLionel Sambuc                        const ArgList &Args)
2173f4a2713aSLionel Sambuc   : Linux(D, Triple, Args) {
2174f4a2713aSLionel Sambuc   const std::string InstalledDir(getDriver().getInstalledDir());
2175*0a6a1f1dSLionel Sambuc   const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir, Args);
2176f4a2713aSLionel Sambuc 
2177f4a2713aSLionel Sambuc   // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
2178f4a2713aSLionel Sambuc   // program paths
2179f4a2713aSLionel Sambuc   const std::string BinDir(GnuDir + "/bin");
2180f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(BinDir))
2181f4a2713aSLionel Sambuc     getProgramPaths().push_back(BinDir);
2182f4a2713aSLionel Sambuc 
2183f4a2713aSLionel Sambuc   // Determine version of GCC libraries and headers to use.
2184f4a2713aSLionel Sambuc   const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
2185*0a6a1f1dSLionel Sambuc   std::error_code ec;
2186f4a2713aSLionel Sambuc   GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
2187f4a2713aSLionel Sambuc   for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
2188f4a2713aSLionel Sambuc        !ec && di != de; di = di.increment(ec)) {
2189f4a2713aSLionel Sambuc     GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
2190f4a2713aSLionel Sambuc     if (MaxVersion < cv)
2191f4a2713aSLionel Sambuc       MaxVersion = cv;
2192f4a2713aSLionel Sambuc   }
2193f4a2713aSLionel Sambuc   GCCLibAndIncVersion = MaxVersion;
2194f4a2713aSLionel Sambuc 
2195f4a2713aSLionel Sambuc   ToolChain::path_list *LibPaths= &getFilePaths();
2196f4a2713aSLionel Sambuc 
2197f4a2713aSLionel Sambuc   // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
2198f4a2713aSLionel Sambuc   // 'elf' OS type, so the Linux paths are not appropriate. When we actually
2199f4a2713aSLionel Sambuc   // support 'linux' we'll need to fix this up
2200f4a2713aSLionel Sambuc   LibPaths->clear();
2201f4a2713aSLionel Sambuc 
2202f4a2713aSLionel Sambuc   GetHexagonLibraryPaths(
2203f4a2713aSLionel Sambuc     Args,
2204f4a2713aSLionel Sambuc     GetGCCLibAndIncVersion(),
2205f4a2713aSLionel Sambuc     GetTargetCPU(Args),
2206f4a2713aSLionel Sambuc     InstalledDir,
2207f4a2713aSLionel Sambuc     LibPaths);
2208f4a2713aSLionel Sambuc }
2209f4a2713aSLionel Sambuc 
~Hexagon_TC()2210f4a2713aSLionel Sambuc Hexagon_TC::~Hexagon_TC() {
2211f4a2713aSLionel Sambuc }
2212f4a2713aSLionel Sambuc 
buildAssembler() const2213f4a2713aSLionel Sambuc Tool *Hexagon_TC::buildAssembler() const {
2214f4a2713aSLionel Sambuc   return new tools::hexagon::Assemble(*this);
2215f4a2713aSLionel Sambuc }
2216f4a2713aSLionel Sambuc 
buildLinker() const2217f4a2713aSLionel Sambuc Tool *Hexagon_TC::buildLinker() const {
2218f4a2713aSLionel Sambuc   return new tools::hexagon::Link(*this);
2219f4a2713aSLionel Sambuc }
2220f4a2713aSLionel Sambuc 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2221f4a2713aSLionel Sambuc void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2222f4a2713aSLionel Sambuc                                            ArgStringList &CC1Args) const {
2223f4a2713aSLionel Sambuc   const Driver &D = getDriver();
2224f4a2713aSLionel Sambuc 
2225f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdinc) ||
2226f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdlibinc))
2227f4a2713aSLionel Sambuc     return;
2228f4a2713aSLionel Sambuc 
2229f4a2713aSLionel Sambuc   std::string Ver(GetGCCLibAndIncVersion());
2230*0a6a1f1dSLionel Sambuc   std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir, DriverArgs);
2231f4a2713aSLionel Sambuc   std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
2232f4a2713aSLionel Sambuc   addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
2233f4a2713aSLionel Sambuc   addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
2234f4a2713aSLionel Sambuc   addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
2235f4a2713aSLionel Sambuc }
2236f4a2713aSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2237f4a2713aSLionel Sambuc void Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2238f4a2713aSLionel Sambuc                                               ArgStringList &CC1Args) const {
2239f4a2713aSLionel Sambuc 
2240f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2241f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
2242f4a2713aSLionel Sambuc     return;
2243f4a2713aSLionel Sambuc 
2244f4a2713aSLionel Sambuc   const Driver &D = getDriver();
2245f4a2713aSLionel Sambuc   std::string Ver(GetGCCLibAndIncVersion());
2246*0a6a1f1dSLionel Sambuc   SmallString<128> IncludeDir(
2247*0a6a1f1dSLionel Sambuc       Hexagon_TC::GetGnuDir(D.InstalledDir, DriverArgs));
2248f4a2713aSLionel Sambuc 
2249f4a2713aSLionel Sambuc   llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");
2250f4a2713aSLionel Sambuc   llvm::sys::path::append(IncludeDir, Ver);
2251f4a2713aSLionel Sambuc   addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
2252f4a2713aSLionel Sambuc }
2253f4a2713aSLionel Sambuc 
2254f4a2713aSLionel Sambuc ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const2255f4a2713aSLionel Sambuc Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
2256f4a2713aSLionel Sambuc   Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
2257f4a2713aSLionel Sambuc   if (!A)
2258f4a2713aSLionel Sambuc     return ToolChain::CST_Libstdcxx;
2259f4a2713aSLionel Sambuc 
2260f4a2713aSLionel Sambuc   StringRef Value = A->getValue();
2261f4a2713aSLionel Sambuc   if (Value != "libstdc++") {
2262f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2263f4a2713aSLionel Sambuc       << A->getAsString(Args);
2264f4a2713aSLionel Sambuc   }
2265f4a2713aSLionel Sambuc 
2266f4a2713aSLionel Sambuc   return ToolChain::CST_Libstdcxx;
2267f4a2713aSLionel Sambuc }
2268f4a2713aSLionel Sambuc 
getHexagonVersion(const ArgList & Args)2269f4a2713aSLionel Sambuc static int getHexagonVersion(const ArgList &Args) {
2270f4a2713aSLionel Sambuc   Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ);
2271f4a2713aSLionel Sambuc   // Select the default CPU (v4) if none was given.
2272f4a2713aSLionel Sambuc   if (!A)
2273f4a2713aSLionel Sambuc     return 4;
2274f4a2713aSLionel Sambuc 
2275f4a2713aSLionel Sambuc   // FIXME: produce errors if we cannot parse the version.
2276f4a2713aSLionel Sambuc   StringRef WhichHexagon = A->getValue();
2277f4a2713aSLionel Sambuc   if (WhichHexagon.startswith("hexagonv")) {
2278f4a2713aSLionel Sambuc     int Val;
2279f4a2713aSLionel Sambuc     if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val))
2280f4a2713aSLionel Sambuc       return Val;
2281f4a2713aSLionel Sambuc   }
2282f4a2713aSLionel Sambuc   if (WhichHexagon.startswith("v")) {
2283f4a2713aSLionel Sambuc     int Val;
2284f4a2713aSLionel Sambuc     if (!WhichHexagon.substr(1).getAsInteger(10, Val))
2285f4a2713aSLionel Sambuc       return Val;
2286f4a2713aSLionel Sambuc   }
2287f4a2713aSLionel Sambuc 
2288f4a2713aSLionel Sambuc   // FIXME: should probably be an error.
2289f4a2713aSLionel Sambuc   return 4;
2290f4a2713aSLionel Sambuc }
2291f4a2713aSLionel Sambuc 
GetTargetCPU(const ArgList & Args)2292f4a2713aSLionel Sambuc StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
2293f4a2713aSLionel Sambuc {
2294f4a2713aSLionel Sambuc   int V = getHexagonVersion(Args);
2295f4a2713aSLionel Sambuc   // FIXME: We don't support versions < 4. We should error on them.
2296f4a2713aSLionel Sambuc   switch (V) {
2297f4a2713aSLionel Sambuc   default:
2298f4a2713aSLionel Sambuc     llvm_unreachable("Unexpected version");
2299f4a2713aSLionel Sambuc   case 5:
2300f4a2713aSLionel Sambuc     return "v5";
2301f4a2713aSLionel Sambuc   case 4:
2302f4a2713aSLionel Sambuc     return "v4";
2303f4a2713aSLionel Sambuc   case 3:
2304f4a2713aSLionel Sambuc     return "v3";
2305f4a2713aSLionel Sambuc   case 2:
2306f4a2713aSLionel Sambuc     return "v2";
2307f4a2713aSLionel Sambuc   case 1:
2308f4a2713aSLionel Sambuc     return "v1";
2309f4a2713aSLionel Sambuc   }
2310f4a2713aSLionel Sambuc }
2311f4a2713aSLionel Sambuc // End Hexagon
2312f4a2713aSLionel Sambuc 
2313f4a2713aSLionel Sambuc /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
2314f4a2713aSLionel Sambuc /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
2315f4a2713aSLionel Sambuc /// Currently does not support anything else but compilation.
2316f4a2713aSLionel Sambuc 
TCEToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2317f4a2713aSLionel Sambuc TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple,
2318f4a2713aSLionel Sambuc                            const ArgList &Args)
2319f4a2713aSLionel Sambuc   : ToolChain(D, Triple, Args) {
2320f4a2713aSLionel Sambuc   // Path mangling to find libexec
2321f4a2713aSLionel Sambuc   std::string Path(getDriver().Dir);
2322f4a2713aSLionel Sambuc 
2323f4a2713aSLionel Sambuc   Path += "/../libexec";
2324f4a2713aSLionel Sambuc   getProgramPaths().push_back(Path);
2325f4a2713aSLionel Sambuc }
2326f4a2713aSLionel Sambuc 
~TCEToolChain()2327f4a2713aSLionel Sambuc TCEToolChain::~TCEToolChain() {
2328f4a2713aSLionel Sambuc }
2329f4a2713aSLionel Sambuc 
IsMathErrnoDefault() const2330f4a2713aSLionel Sambuc bool TCEToolChain::IsMathErrnoDefault() const {
2331f4a2713aSLionel Sambuc   return true;
2332f4a2713aSLionel Sambuc }
2333f4a2713aSLionel Sambuc 
isPICDefault() const2334f4a2713aSLionel Sambuc bool TCEToolChain::isPICDefault() const {
2335f4a2713aSLionel Sambuc   return false;
2336f4a2713aSLionel Sambuc }
2337f4a2713aSLionel Sambuc 
isPIEDefault() const2338f4a2713aSLionel Sambuc bool TCEToolChain::isPIEDefault() const {
2339f4a2713aSLionel Sambuc   return false;
2340f4a2713aSLionel Sambuc }
2341f4a2713aSLionel Sambuc 
isPICDefaultForced() const2342f4a2713aSLionel Sambuc bool TCEToolChain::isPICDefaultForced() const {
2343f4a2713aSLionel Sambuc   return false;
2344f4a2713aSLionel Sambuc }
2345f4a2713aSLionel Sambuc 
2346f4a2713aSLionel Sambuc /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
2347f4a2713aSLionel Sambuc 
OpenBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2348f4a2713aSLionel Sambuc OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2349f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
2350f4a2713aSLionel Sambuc   getFilePaths().push_back(getDriver().Dir + "/../lib");
2351f4a2713aSLionel Sambuc   getFilePaths().push_back("/usr/lib");
2352f4a2713aSLionel Sambuc }
2353f4a2713aSLionel Sambuc 
buildAssembler() const2354f4a2713aSLionel Sambuc Tool *OpenBSD::buildAssembler() const {
2355f4a2713aSLionel Sambuc   return new tools::openbsd::Assemble(*this);
2356f4a2713aSLionel Sambuc }
2357f4a2713aSLionel Sambuc 
buildLinker() const2358f4a2713aSLionel Sambuc Tool *OpenBSD::buildLinker() const {
2359f4a2713aSLionel Sambuc   return new tools::openbsd::Link(*this);
2360f4a2713aSLionel Sambuc }
2361f4a2713aSLionel Sambuc 
2362f4a2713aSLionel Sambuc /// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
2363f4a2713aSLionel Sambuc 
Bitrig(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2364f4a2713aSLionel Sambuc Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2365f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
2366f4a2713aSLionel Sambuc   getFilePaths().push_back(getDriver().Dir + "/../lib");
2367f4a2713aSLionel Sambuc   getFilePaths().push_back("/usr/lib");
2368f4a2713aSLionel Sambuc }
2369f4a2713aSLionel Sambuc 
buildAssembler() const2370f4a2713aSLionel Sambuc Tool *Bitrig::buildAssembler() const {
2371f4a2713aSLionel Sambuc   return new tools::bitrig::Assemble(*this);
2372f4a2713aSLionel Sambuc }
2373f4a2713aSLionel Sambuc 
buildLinker() const2374f4a2713aSLionel Sambuc Tool *Bitrig::buildLinker() const {
2375f4a2713aSLionel Sambuc   return new tools::bitrig::Link(*this);
2376f4a2713aSLionel Sambuc }
2377f4a2713aSLionel Sambuc 
2378*0a6a1f1dSLionel Sambuc ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const2379*0a6a1f1dSLionel Sambuc Bitrig::GetCXXStdlibType(const ArgList &Args) const {
2380*0a6a1f1dSLionel Sambuc   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2381*0a6a1f1dSLionel Sambuc     StringRef Value = A->getValue();
2382*0a6a1f1dSLionel Sambuc     if (Value == "libstdc++")
2383*0a6a1f1dSLionel Sambuc       return ToolChain::CST_Libstdcxx;
2384*0a6a1f1dSLionel Sambuc     if (Value == "libc++")
2385*0a6a1f1dSLionel Sambuc       return ToolChain::CST_Libcxx;
2386*0a6a1f1dSLionel Sambuc 
2387*0a6a1f1dSLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2388*0a6a1f1dSLionel Sambuc       << A->getAsString(Args);
2389*0a6a1f1dSLionel Sambuc   }
2390*0a6a1f1dSLionel Sambuc   return ToolChain::CST_Libcxx;
2391*0a6a1f1dSLionel Sambuc }
2392*0a6a1f1dSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2393f4a2713aSLionel Sambuc void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2394f4a2713aSLionel Sambuc                                           ArgStringList &CC1Args) const {
2395f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2396f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
2397f4a2713aSLionel Sambuc     return;
2398f4a2713aSLionel Sambuc 
2399f4a2713aSLionel Sambuc   switch (GetCXXStdlibType(DriverArgs)) {
2400f4a2713aSLionel Sambuc   case ToolChain::CST_Libcxx:
2401f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2402*0a6a1f1dSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/v1");
2403f4a2713aSLionel Sambuc     break;
2404f4a2713aSLionel Sambuc   case ToolChain::CST_Libstdcxx:
2405f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2406f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/stdc++");
2407f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2408f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
2409f4a2713aSLionel Sambuc 
2410f4a2713aSLionel Sambuc     StringRef Triple = getTriple().str();
2411f4a2713aSLionel Sambuc     if (Triple.startswith("amd64"))
2412f4a2713aSLionel Sambuc       addSystemInclude(DriverArgs, CC1Args,
2413f4a2713aSLionel Sambuc                        getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
2414f4a2713aSLionel Sambuc                        Triple.substr(5));
2415f4a2713aSLionel Sambuc     else
2416f4a2713aSLionel Sambuc       addSystemInclude(DriverArgs, CC1Args,
2417f4a2713aSLionel Sambuc                        getDriver().SysRoot + "/usr/include/c++/stdc++/" +
2418f4a2713aSLionel Sambuc                        Triple);
2419f4a2713aSLionel Sambuc     break;
2420f4a2713aSLionel Sambuc   }
2421f4a2713aSLionel Sambuc }
2422f4a2713aSLionel Sambuc 
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const2423f4a2713aSLionel Sambuc void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
2424f4a2713aSLionel Sambuc                                  ArgStringList &CmdArgs) const {
2425f4a2713aSLionel Sambuc   switch (GetCXXStdlibType(Args)) {
2426f4a2713aSLionel Sambuc   case ToolChain::CST_Libcxx:
2427f4a2713aSLionel Sambuc     CmdArgs.push_back("-lc++");
2428*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-lc++abi");
2429*0a6a1f1dSLionel Sambuc     CmdArgs.push_back("-lpthread");
2430f4a2713aSLionel Sambuc     break;
2431f4a2713aSLionel Sambuc   case ToolChain::CST_Libstdcxx:
2432f4a2713aSLionel Sambuc     CmdArgs.push_back("-lstdc++");
2433f4a2713aSLionel Sambuc     break;
2434f4a2713aSLionel Sambuc   }
2435f4a2713aSLionel Sambuc }
2436f4a2713aSLionel Sambuc 
2437f4a2713aSLionel Sambuc /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
2438f4a2713aSLionel Sambuc 
FreeBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2439f4a2713aSLionel Sambuc FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2440f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
2441f4a2713aSLionel Sambuc 
2442f4a2713aSLionel Sambuc   // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
2443f4a2713aSLionel Sambuc   // back to '/usr/lib' if it doesn't exist.
2444f4a2713aSLionel Sambuc   if ((Triple.getArch() == llvm::Triple::x86 ||
2445f4a2713aSLionel Sambuc        Triple.getArch() == llvm::Triple::ppc) &&
2446f4a2713aSLionel Sambuc       llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
2447f4a2713aSLionel Sambuc     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
2448f4a2713aSLionel Sambuc   else
2449f4a2713aSLionel Sambuc     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
2450f4a2713aSLionel Sambuc }
2451f4a2713aSLionel Sambuc 
2452f4a2713aSLionel Sambuc ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const2453f4a2713aSLionel Sambuc FreeBSD::GetCXXStdlibType(const ArgList &Args) const {
2454f4a2713aSLionel Sambuc   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2455f4a2713aSLionel Sambuc     StringRef Value = A->getValue();
2456f4a2713aSLionel Sambuc     if (Value == "libstdc++")
2457f4a2713aSLionel Sambuc       return ToolChain::CST_Libstdcxx;
2458f4a2713aSLionel Sambuc     if (Value == "libc++")
2459f4a2713aSLionel Sambuc       return ToolChain::CST_Libcxx;
2460f4a2713aSLionel Sambuc 
2461f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2462f4a2713aSLionel Sambuc       << A->getAsString(Args);
2463f4a2713aSLionel Sambuc   }
2464f4a2713aSLionel Sambuc   if (getTriple().getOSMajorVersion() >= 10)
2465f4a2713aSLionel Sambuc     return ToolChain::CST_Libcxx;
2466f4a2713aSLionel Sambuc   return ToolChain::CST_Libstdcxx;
2467f4a2713aSLionel Sambuc }
2468f4a2713aSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2469f4a2713aSLionel Sambuc void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2470f4a2713aSLionel Sambuc                                            ArgStringList &CC1Args) const {
2471f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2472f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
2473f4a2713aSLionel Sambuc     return;
2474f4a2713aSLionel Sambuc 
2475f4a2713aSLionel Sambuc   switch (GetCXXStdlibType(DriverArgs)) {
2476f4a2713aSLionel Sambuc   case ToolChain::CST_Libcxx:
2477f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2478f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/v1");
2479f4a2713aSLionel Sambuc     break;
2480f4a2713aSLionel Sambuc   case ToolChain::CST_Libstdcxx:
2481f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2482f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/4.2");
2483f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2484f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/4.2/backward");
2485f4a2713aSLionel Sambuc     break;
2486f4a2713aSLionel Sambuc   }
2487f4a2713aSLionel Sambuc }
2488f4a2713aSLionel Sambuc 
buildAssembler() const2489f4a2713aSLionel Sambuc Tool *FreeBSD::buildAssembler() const {
2490f4a2713aSLionel Sambuc   return new tools::freebsd::Assemble(*this);
2491f4a2713aSLionel Sambuc }
2492f4a2713aSLionel Sambuc 
buildLinker() const2493f4a2713aSLionel Sambuc Tool *FreeBSD::buildLinker() const {
2494f4a2713aSLionel Sambuc   return new tools::freebsd::Link(*this);
2495f4a2713aSLionel Sambuc }
2496f4a2713aSLionel Sambuc 
UseSjLjExceptions() const2497f4a2713aSLionel Sambuc bool FreeBSD::UseSjLjExceptions() const {
2498f4a2713aSLionel Sambuc   // FreeBSD uses SjLj exceptions on ARM oabi.
2499f4a2713aSLionel Sambuc   switch (getTriple().getEnvironment()) {
2500*0a6a1f1dSLionel Sambuc   case llvm::Triple::GNUEABIHF:
2501f4a2713aSLionel Sambuc   case llvm::Triple::GNUEABI:
2502f4a2713aSLionel Sambuc   case llvm::Triple::EABI:
2503f4a2713aSLionel Sambuc     return false;
2504f4a2713aSLionel Sambuc 
2505f4a2713aSLionel Sambuc   default:
2506f4a2713aSLionel Sambuc     return (getTriple().getArch() == llvm::Triple::arm ||
2507f4a2713aSLionel Sambuc             getTriple().getArch() == llvm::Triple::thumb);
2508f4a2713aSLionel Sambuc   }
2509f4a2713aSLionel Sambuc }
2510f4a2713aSLionel Sambuc 
HasNativeLLVMSupport() const2511*0a6a1f1dSLionel Sambuc bool FreeBSD::HasNativeLLVMSupport() const {
2512*0a6a1f1dSLionel Sambuc   return true;
2513*0a6a1f1dSLionel Sambuc }
2514*0a6a1f1dSLionel Sambuc 
isPIEDefault() const2515*0a6a1f1dSLionel Sambuc bool FreeBSD::isPIEDefault() const {
2516*0a6a1f1dSLionel Sambuc   return getSanitizerArgs().requiresPIE();
2517*0a6a1f1dSLionel Sambuc }
2518*0a6a1f1dSLionel Sambuc 
2519f4a2713aSLionel Sambuc /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
2520f4a2713aSLionel Sambuc 
NetBSD(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2521f4a2713aSLionel Sambuc NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2522f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
2523f4a2713aSLionel Sambuc 
2524f4a2713aSLionel Sambuc   if (getDriver().UseStdLib) {
2525f4a2713aSLionel Sambuc     // When targeting a 32-bit platform, try the special directory used on
2526f4a2713aSLionel Sambuc     // 64-bit hosts, and only fall back to the main library directory if that
2527f4a2713aSLionel Sambuc     // doesn't work.
2528f4a2713aSLionel Sambuc     // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
2529f4a2713aSLionel Sambuc     // what all logic is needed to emulate the '=' prefix here.
2530*0a6a1f1dSLionel Sambuc     switch (Triple.getArch()) {
2531*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86:
2532f4a2713aSLionel Sambuc       getFilePaths().push_back("=/usr/lib/i386");
2533*0a6a1f1dSLionel Sambuc       break;
2534*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
2535*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
2536*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
2537*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
2538*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
2539*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABI:
2540*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABI:
2541*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/eabi");
2542*0a6a1f1dSLionel Sambuc         break;
2543*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABIHF:
2544*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABIHF:
2545*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/eabihf");
2546*0a6a1f1dSLionel Sambuc         break;
2547*0a6a1f1dSLionel Sambuc       default:
2548*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/oabi");
2549*0a6a1f1dSLionel Sambuc         break;
2550*0a6a1f1dSLionel Sambuc       }
2551*0a6a1f1dSLionel Sambuc       break;
2552*0a6a1f1dSLionel Sambuc     case llvm::Triple::mips64:
2553*0a6a1f1dSLionel Sambuc     case llvm::Triple::mips64el:
2554*0a6a1f1dSLionel Sambuc       if (tools::mips::hasMipsAbiArg(Args, "o32"))
2555*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/o32");
2556*0a6a1f1dSLionel Sambuc       else if (tools::mips::hasMipsAbiArg(Args, "64"))
2557*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/64");
2558*0a6a1f1dSLionel Sambuc       break;
2559*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc:
2560*0a6a1f1dSLionel Sambuc       getFilePaths().push_back("=/usr/lib/powerpc");
2561*0a6a1f1dSLionel Sambuc       break;
2562*0a6a1f1dSLionel Sambuc     case llvm::Triple::sparc:
2563*0a6a1f1dSLionel Sambuc       getFilePaths().push_back("=/usr/lib/sparc");
2564*0a6a1f1dSLionel Sambuc       break;
2565*0a6a1f1dSLionel Sambuc     default:
2566*0a6a1f1dSLionel Sambuc       break;
2567*0a6a1f1dSLionel Sambuc     }
2568f4a2713aSLionel Sambuc 
2569f4a2713aSLionel Sambuc     getFilePaths().push_back("=/usr/lib");
2570f4a2713aSLionel Sambuc   }
2571f4a2713aSLionel Sambuc }
2572f4a2713aSLionel Sambuc 
buildAssembler() const2573f4a2713aSLionel Sambuc Tool *NetBSD::buildAssembler() const {
2574f4a2713aSLionel Sambuc   return new tools::netbsd::Assemble(*this);
2575f4a2713aSLionel Sambuc }
2576f4a2713aSLionel Sambuc 
buildLinker() const2577f4a2713aSLionel Sambuc Tool *NetBSD::buildLinker() const {
2578f4a2713aSLionel Sambuc   return new tools::netbsd::Link(*this);
2579f4a2713aSLionel Sambuc }
2580f4a2713aSLionel Sambuc 
2581f4a2713aSLionel Sambuc ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const2582f4a2713aSLionel Sambuc NetBSD::GetCXXStdlibType(const ArgList &Args) const {
2583f4a2713aSLionel Sambuc   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2584f4a2713aSLionel Sambuc     StringRef Value = A->getValue();
2585f4a2713aSLionel Sambuc     if (Value == "libstdc++")
2586f4a2713aSLionel Sambuc       return ToolChain::CST_Libstdcxx;
2587f4a2713aSLionel Sambuc     if (Value == "libc++")
2588f4a2713aSLionel Sambuc       return ToolChain::CST_Libcxx;
2589f4a2713aSLionel Sambuc 
2590f4a2713aSLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2591f4a2713aSLionel Sambuc       << A->getAsString(Args);
2592f4a2713aSLionel Sambuc   }
2593f4a2713aSLionel Sambuc 
2594f4a2713aSLionel Sambuc   unsigned Major, Minor, Micro;
2595f4a2713aSLionel Sambuc   getTriple().getOSVersion(Major, Minor, Micro);
2596*0a6a1f1dSLionel Sambuc   if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) {
2597*0a6a1f1dSLionel Sambuc     switch (getArch()) {
2598*0a6a1f1dSLionel Sambuc     case llvm::Triple::aarch64:
2599*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
2600*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
2601*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
2602*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
2603*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc:
2604*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64:
2605*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64le:
2606*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86:
2607*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86_64:
2608f4a2713aSLionel Sambuc       return ToolChain::CST_Libcxx;
2609*0a6a1f1dSLionel Sambuc     default:
2610*0a6a1f1dSLionel Sambuc       break;
2611*0a6a1f1dSLionel Sambuc     }
2612f4a2713aSLionel Sambuc   }
2613f4a2713aSLionel Sambuc   return ToolChain::CST_Libstdcxx;
2614f4a2713aSLionel Sambuc }
2615f4a2713aSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const2616f4a2713aSLionel Sambuc void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2617f4a2713aSLionel Sambuc                                           ArgStringList &CC1Args) const {
2618f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2619f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
2620f4a2713aSLionel Sambuc     return;
2621f4a2713aSLionel Sambuc 
2622f4a2713aSLionel Sambuc   switch (GetCXXStdlibType(DriverArgs)) {
2623f4a2713aSLionel Sambuc   case ToolChain::CST_Libcxx:
2624f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2625f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/");
2626f4a2713aSLionel Sambuc     break;
2627f4a2713aSLionel Sambuc   case ToolChain::CST_Libstdcxx:
2628f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2629f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/g++");
2630f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
2631f4a2713aSLionel Sambuc                      getDriver().SysRoot + "/usr/include/g++/backward");
2632f4a2713aSLionel Sambuc     break;
2633f4a2713aSLionel Sambuc   }
2634f4a2713aSLionel Sambuc }
2635f4a2713aSLionel Sambuc 
2636f4a2713aSLionel Sambuc /// Minix - Minix tool chain which can call as(1) and ld(1) directly.
2637f4a2713aSLionel Sambuc 
Minix(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2638f4a2713aSLionel Sambuc Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2639f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
2640*0a6a1f1dSLionel Sambuc 
26414684ddb6SLionel Sambuc   if (getDriver().UseStdLib) {
26424684ddb6SLionel Sambuc     // When targeting a 32-bit platform, try the special directory used on
26434684ddb6SLionel Sambuc     // 64-bit hosts, and only fall back to the main library directory if that
26444684ddb6SLionel Sambuc     // doesn't work.
26454684ddb6SLionel Sambuc     // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
26464684ddb6SLionel Sambuc     // what all logic is needed to emulate the '=' prefix here.
2647*0a6a1f1dSLionel Sambuc     switch (Triple.getArch()) {
2648*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86:
26494684ddb6SLionel Sambuc       getFilePaths().push_back("=/usr/lib/i386");
2650*0a6a1f1dSLionel Sambuc       break;
2651*0a6a1f1dSLionel Sambuc #if 0 // LSC: Not yet useful for MINIX, but kept to simplify comparison with NetBSD
2652*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
2653*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
2654*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
2655*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
2656*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
2657*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABI:
2658*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABI:
2659*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/eabi");
2660*0a6a1f1dSLionel Sambuc         break;
2661*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABIHF:
2662*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABIHF:
2663*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/eabihf");
2664*0a6a1f1dSLionel Sambuc         break;
2665*0a6a1f1dSLionel Sambuc       default:
2666*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/oabi");
2667*0a6a1f1dSLionel Sambuc         break;
2668*0a6a1f1dSLionel Sambuc       }
2669*0a6a1f1dSLionel Sambuc       break;
2670*0a6a1f1dSLionel Sambuc     case llvm::Triple::mips64:
2671*0a6a1f1dSLionel Sambuc     case llvm::Triple::mips64el:
2672*0a6a1f1dSLionel Sambuc       if (tools::mips::hasMipsAbiArg(Args, "o32"))
2673*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/o32");
2674*0a6a1f1dSLionel Sambuc       else if (tools::mips::hasMipsAbiArg(Args, "64"))
2675*0a6a1f1dSLionel Sambuc         getFilePaths().push_back("=/usr/lib/64");
2676*0a6a1f1dSLionel Sambuc       break;
2677*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc:
2678*0a6a1f1dSLionel Sambuc       getFilePaths().push_back("=/usr/lib/powerpc");
2679*0a6a1f1dSLionel Sambuc       break;
2680*0a6a1f1dSLionel Sambuc     case llvm::Triple::sparc:
2681*0a6a1f1dSLionel Sambuc       getFilePaths().push_back("=/usr/lib/sparc");
2682*0a6a1f1dSLionel Sambuc       break;
2683*0a6a1f1dSLionel Sambuc #endif /* 0 */
2684*0a6a1f1dSLionel Sambuc     default:
2685*0a6a1f1dSLionel Sambuc       break;
2686*0a6a1f1dSLionel Sambuc     }
26874684ddb6SLionel Sambuc 
26884684ddb6SLionel Sambuc     getFilePaths().push_back("=/usr/lib");
26894684ddb6SLionel Sambuc   }
2690f4a2713aSLionel Sambuc }
2691f4a2713aSLionel Sambuc 
buildAssembler() const2692f4a2713aSLionel Sambuc Tool *Minix::buildAssembler() const {
2693f4a2713aSLionel Sambuc   return new tools::minix::Assemble(*this);
2694f4a2713aSLionel Sambuc }
2695f4a2713aSLionel Sambuc 
buildLinker() const2696f4a2713aSLionel Sambuc Tool *Minix::buildLinker() const {
2697f4a2713aSLionel Sambuc   return new tools::minix::Link(*this);
2698f4a2713aSLionel Sambuc }
2699f4a2713aSLionel Sambuc 
27004684ddb6SLionel Sambuc ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const27014684ddb6SLionel Sambuc Minix::GetCXXStdlibType(const ArgList &Args) const {
27024684ddb6SLionel Sambuc   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
27034684ddb6SLionel Sambuc     StringRef Value = A->getValue();
27044684ddb6SLionel Sambuc     if (Value == "libstdc++")
27054684ddb6SLionel Sambuc       return ToolChain::CST_Libstdcxx;
27064684ddb6SLionel Sambuc     if (Value == "libc++")
27074684ddb6SLionel Sambuc       return ToolChain::CST_Libcxx;
27084684ddb6SLionel Sambuc 
27094684ddb6SLionel Sambuc     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
27104684ddb6SLionel Sambuc       << A->getAsString(Args);
27114684ddb6SLionel Sambuc   }
27124684ddb6SLionel Sambuc 
27134684ddb6SLionel Sambuc #if 0 /* LSC: We only us libcxx by default */
27144684ddb6SLionel Sambuc   unsigned Major, Minor, Micro;
27154684ddb6SLionel Sambuc   getTriple().getOSVersion(Major, Minor, Micro);
2716*0a6a1f1dSLionel Sambuc   if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) {
2717*0a6a1f1dSLionel Sambuc     switch (getArch()) {
2718*0a6a1f1dSLionel Sambuc     case llvm::Triple::aarch64:
2719*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
2720*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
2721*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
2722*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
2723*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc:
2724*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64:
2725*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64le:
2726*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86:
2727*0a6a1f1dSLionel Sambuc     case llvm::Triple::x86_64:
27284684ddb6SLionel Sambuc       return ToolChain::CST_Libcxx;
2729*0a6a1f1dSLionel Sambuc     default:
2730*0a6a1f1dSLionel Sambuc       break;
2731*0a6a1f1dSLionel Sambuc     }
27324684ddb6SLionel Sambuc   }
27334684ddb6SLionel Sambuc   return ToolChain::CST_Libstdcxx;
27344684ddb6SLionel Sambuc #else
27354684ddb6SLionel Sambuc   return ToolChain::CST_Libcxx;
27364684ddb6SLionel Sambuc #endif /* 0 */
27374684ddb6SLionel Sambuc }
27384684ddb6SLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const27394684ddb6SLionel Sambuc void Minix::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
27404684ddb6SLionel Sambuc                                           ArgStringList &CC1Args) const {
27414684ddb6SLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
27424684ddb6SLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
27434684ddb6SLionel Sambuc     return;
27444684ddb6SLionel Sambuc 
27454684ddb6SLionel Sambuc   switch (GetCXXStdlibType(DriverArgs)) {
27464684ddb6SLionel Sambuc   case ToolChain::CST_Libcxx:
27474684ddb6SLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
27484684ddb6SLionel Sambuc                      getDriver().SysRoot + "/usr/include/c++/");
27494684ddb6SLionel Sambuc     break;
27504684ddb6SLionel Sambuc   case ToolChain::CST_Libstdcxx:
27514684ddb6SLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
27524684ddb6SLionel Sambuc                      getDriver().SysRoot + "/usr/include/g++");
27534684ddb6SLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
27544684ddb6SLionel Sambuc                      getDriver().SysRoot + "/usr/include/g++/backward");
27554684ddb6SLionel Sambuc     break;
27564684ddb6SLionel Sambuc   }
27574684ddb6SLionel Sambuc }
27584684ddb6SLionel Sambuc 
2759f4a2713aSLionel Sambuc /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
2760f4a2713aSLionel Sambuc 
Solaris(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)2761f4a2713aSLionel Sambuc Solaris::Solaris(const Driver &D, const llvm::Triple& Triple,
2762f4a2713aSLionel Sambuc                  const ArgList &Args)
2763f4a2713aSLionel Sambuc   : Generic_GCC(D, Triple, Args) {
2764f4a2713aSLionel Sambuc 
2765f4a2713aSLionel Sambuc   getProgramPaths().push_back(getDriver().getInstalledDir());
2766f4a2713aSLionel Sambuc   if (getDriver().getInstalledDir() != getDriver().Dir)
2767f4a2713aSLionel Sambuc     getProgramPaths().push_back(getDriver().Dir);
2768f4a2713aSLionel Sambuc 
2769f4a2713aSLionel Sambuc   getFilePaths().push_back(getDriver().Dir + "/../lib");
2770f4a2713aSLionel Sambuc   getFilePaths().push_back("/usr/lib");
2771f4a2713aSLionel Sambuc }
2772f4a2713aSLionel Sambuc 
buildAssembler() const2773f4a2713aSLionel Sambuc Tool *Solaris::buildAssembler() const {
2774f4a2713aSLionel Sambuc   return new tools::solaris::Assemble(*this);
2775f4a2713aSLionel Sambuc }
2776f4a2713aSLionel Sambuc 
buildLinker() const2777f4a2713aSLionel Sambuc Tool *Solaris::buildLinker() const {
2778f4a2713aSLionel Sambuc   return new tools::solaris::Link(*this);
2779f4a2713aSLionel Sambuc }
2780f4a2713aSLionel Sambuc 
2781f4a2713aSLionel Sambuc /// Distribution (very bare-bones at the moment).
2782f4a2713aSLionel Sambuc 
2783f4a2713aSLionel Sambuc enum Distro {
2784f4a2713aSLionel Sambuc   ArchLinux,
2785f4a2713aSLionel Sambuc   DebianLenny,
2786f4a2713aSLionel Sambuc   DebianSqueeze,
2787f4a2713aSLionel Sambuc   DebianWheezy,
2788f4a2713aSLionel Sambuc   DebianJessie,
2789f4a2713aSLionel Sambuc   Exherbo,
2790f4a2713aSLionel Sambuc   RHEL4,
2791f4a2713aSLionel Sambuc   RHEL5,
2792f4a2713aSLionel Sambuc   RHEL6,
2793f4a2713aSLionel Sambuc   Fedora,
2794f4a2713aSLionel Sambuc   OpenSUSE,
2795f4a2713aSLionel Sambuc   UbuntuHardy,
2796f4a2713aSLionel Sambuc   UbuntuIntrepid,
2797f4a2713aSLionel Sambuc   UbuntuJaunty,
2798f4a2713aSLionel Sambuc   UbuntuKarmic,
2799f4a2713aSLionel Sambuc   UbuntuLucid,
2800f4a2713aSLionel Sambuc   UbuntuMaverick,
2801f4a2713aSLionel Sambuc   UbuntuNatty,
2802f4a2713aSLionel Sambuc   UbuntuOneiric,
2803f4a2713aSLionel Sambuc   UbuntuPrecise,
2804f4a2713aSLionel Sambuc   UbuntuQuantal,
2805f4a2713aSLionel Sambuc   UbuntuRaring,
2806f4a2713aSLionel Sambuc   UbuntuSaucy,
2807f4a2713aSLionel Sambuc   UbuntuTrusty,
2808f4a2713aSLionel Sambuc   UnknownDistro
2809f4a2713aSLionel Sambuc };
2810f4a2713aSLionel Sambuc 
IsRedhat(enum Distro Distro)2811f4a2713aSLionel Sambuc static bool IsRedhat(enum Distro Distro) {
2812f4a2713aSLionel Sambuc   return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6);
2813f4a2713aSLionel Sambuc }
2814f4a2713aSLionel Sambuc 
IsOpenSUSE(enum Distro Distro)2815f4a2713aSLionel Sambuc static bool IsOpenSUSE(enum Distro Distro) {
2816f4a2713aSLionel Sambuc   return Distro == OpenSUSE;
2817f4a2713aSLionel Sambuc }
2818f4a2713aSLionel Sambuc 
IsDebian(enum Distro Distro)2819f4a2713aSLionel Sambuc static bool IsDebian(enum Distro Distro) {
2820f4a2713aSLionel Sambuc   return Distro >= DebianLenny && Distro <= DebianJessie;
2821f4a2713aSLionel Sambuc }
2822f4a2713aSLionel Sambuc 
IsUbuntu(enum Distro Distro)2823f4a2713aSLionel Sambuc static bool IsUbuntu(enum Distro Distro) {
2824f4a2713aSLionel Sambuc   return Distro >= UbuntuHardy && Distro <= UbuntuTrusty;
2825f4a2713aSLionel Sambuc }
2826f4a2713aSLionel Sambuc 
DetectDistro(llvm::Triple::ArchType Arch)2827f4a2713aSLionel Sambuc static Distro DetectDistro(llvm::Triple::ArchType Arch) {
2828*0a6a1f1dSLionel Sambuc   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
2829*0a6a1f1dSLionel Sambuc       llvm::MemoryBuffer::getFile("/etc/lsb-release");
2830*0a6a1f1dSLionel Sambuc   if (File) {
2831f4a2713aSLionel Sambuc     StringRef Data = File.get()->getBuffer();
2832*0a6a1f1dSLionel Sambuc     SmallVector<StringRef, 16> Lines;
2833f4a2713aSLionel Sambuc     Data.split(Lines, "\n");
2834f4a2713aSLionel Sambuc     Distro Version = UnknownDistro;
2835f4a2713aSLionel Sambuc     for (unsigned i = 0, s = Lines.size(); i != s; ++i)
2836f4a2713aSLionel Sambuc       if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME="))
2837f4a2713aSLionel Sambuc         Version = llvm::StringSwitch<Distro>(Lines[i].substr(17))
2838f4a2713aSLionel Sambuc           .Case("hardy", UbuntuHardy)
2839f4a2713aSLionel Sambuc           .Case("intrepid", UbuntuIntrepid)
2840f4a2713aSLionel Sambuc           .Case("jaunty", UbuntuJaunty)
2841f4a2713aSLionel Sambuc           .Case("karmic", UbuntuKarmic)
2842f4a2713aSLionel Sambuc           .Case("lucid", UbuntuLucid)
2843f4a2713aSLionel Sambuc           .Case("maverick", UbuntuMaverick)
2844f4a2713aSLionel Sambuc           .Case("natty", UbuntuNatty)
2845f4a2713aSLionel Sambuc           .Case("oneiric", UbuntuOneiric)
2846f4a2713aSLionel Sambuc           .Case("precise", UbuntuPrecise)
2847f4a2713aSLionel Sambuc           .Case("quantal", UbuntuQuantal)
2848f4a2713aSLionel Sambuc           .Case("raring", UbuntuRaring)
2849f4a2713aSLionel Sambuc           .Case("saucy", UbuntuSaucy)
2850f4a2713aSLionel Sambuc           .Case("trusty", UbuntuTrusty)
2851f4a2713aSLionel Sambuc           .Default(UnknownDistro);
2852f4a2713aSLionel Sambuc     return Version;
2853f4a2713aSLionel Sambuc   }
2854f4a2713aSLionel Sambuc 
2855*0a6a1f1dSLionel Sambuc   File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
2856*0a6a1f1dSLionel Sambuc   if (File) {
2857f4a2713aSLionel Sambuc     StringRef Data = File.get()->getBuffer();
2858f4a2713aSLionel Sambuc     if (Data.startswith("Fedora release"))
2859f4a2713aSLionel Sambuc       return Fedora;
2860*0a6a1f1dSLionel Sambuc     if (Data.startswith("Red Hat Enterprise Linux") ||
2861*0a6a1f1dSLionel Sambuc         Data.startswith("CentOS")) {
2862*0a6a1f1dSLionel Sambuc       if (Data.find("release 6") != StringRef::npos)
2863f4a2713aSLionel Sambuc         return RHEL6;
2864*0a6a1f1dSLionel Sambuc       else if (Data.find("release 5") != StringRef::npos)
2865f4a2713aSLionel Sambuc         return RHEL5;
2866*0a6a1f1dSLionel Sambuc       else if (Data.find("release 4") != StringRef::npos)
2867f4a2713aSLionel Sambuc         return RHEL4;
2868*0a6a1f1dSLionel Sambuc     }
2869f4a2713aSLionel Sambuc     return UnknownDistro;
2870f4a2713aSLionel Sambuc   }
2871f4a2713aSLionel Sambuc 
2872*0a6a1f1dSLionel Sambuc   File = llvm::MemoryBuffer::getFile("/etc/debian_version");
2873*0a6a1f1dSLionel Sambuc   if (File) {
2874f4a2713aSLionel Sambuc     StringRef Data = File.get()->getBuffer();
2875f4a2713aSLionel Sambuc     if (Data[0] == '5')
2876f4a2713aSLionel Sambuc       return DebianLenny;
2877f4a2713aSLionel Sambuc     else if (Data.startswith("squeeze/sid") || Data[0] == '6')
2878f4a2713aSLionel Sambuc       return DebianSqueeze;
2879f4a2713aSLionel Sambuc     else if (Data.startswith("wheezy/sid")  || Data[0] == '7')
2880f4a2713aSLionel Sambuc       return DebianWheezy;
2881f4a2713aSLionel Sambuc     else if (Data.startswith("jessie/sid")  || Data[0] == '8')
2882f4a2713aSLionel Sambuc       return DebianJessie;
2883f4a2713aSLionel Sambuc     return UnknownDistro;
2884f4a2713aSLionel Sambuc   }
2885f4a2713aSLionel Sambuc 
2886f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists("/etc/SuSE-release"))
2887f4a2713aSLionel Sambuc     return OpenSUSE;
2888f4a2713aSLionel Sambuc 
2889f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists("/etc/exherbo-release"))
2890f4a2713aSLionel Sambuc     return Exherbo;
2891f4a2713aSLionel Sambuc 
2892f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists("/etc/arch-release"))
2893f4a2713aSLionel Sambuc     return ArchLinux;
2894f4a2713aSLionel Sambuc 
2895f4a2713aSLionel Sambuc   return UnknownDistro;
2896f4a2713aSLionel Sambuc }
2897f4a2713aSLionel Sambuc 
2898f4a2713aSLionel Sambuc /// \brief Get our best guess at the multiarch triple for a target.
2899f4a2713aSLionel Sambuc ///
2900f4a2713aSLionel Sambuc /// Debian-based systems are starting to use a multiarch setup where they use
2901f4a2713aSLionel Sambuc /// a target-triple directory in the library and header search paths.
2902f4a2713aSLionel Sambuc /// Unfortunately, this triple does not align with the vanilla target triple,
2903f4a2713aSLionel Sambuc /// so we provide a rough mapping here.
getMultiarchTriple(const llvm::Triple & TargetTriple,StringRef SysRoot)2904*0a6a1f1dSLionel Sambuc static std::string getMultiarchTriple(const llvm::Triple &TargetTriple,
2905f4a2713aSLionel Sambuc                                       StringRef SysRoot) {
2906f4a2713aSLionel Sambuc   // For most architectures, just use whatever we have rather than trying to be
2907f4a2713aSLionel Sambuc   // clever.
2908f4a2713aSLionel Sambuc   switch (TargetTriple.getArch()) {
2909f4a2713aSLionel Sambuc   default:
2910f4a2713aSLionel Sambuc     return TargetTriple.str();
2911f4a2713aSLionel Sambuc 
2912f4a2713aSLionel Sambuc     // We use the existence of '/lib/<triple>' as a directory to detect some
2913f4a2713aSLionel Sambuc     // common linux triples that don't quite match the Clang triple for both
2914f4a2713aSLionel Sambuc     // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
2915f4a2713aSLionel Sambuc     // regardless of what the actual target triple is.
2916f4a2713aSLionel Sambuc   case llvm::Triple::arm:
2917f4a2713aSLionel Sambuc   case llvm::Triple::thumb:
2918f4a2713aSLionel Sambuc     if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
2919f4a2713aSLionel Sambuc       if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
2920f4a2713aSLionel Sambuc         return "arm-linux-gnueabihf";
2921f4a2713aSLionel Sambuc     } else {
2922f4a2713aSLionel Sambuc       if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
2923f4a2713aSLionel Sambuc         return "arm-linux-gnueabi";
2924f4a2713aSLionel Sambuc     }
2925f4a2713aSLionel Sambuc     return TargetTriple.str();
2926*0a6a1f1dSLionel Sambuc   case llvm::Triple::armeb:
2927*0a6a1f1dSLionel Sambuc   case llvm::Triple::thumbeb:
2928*0a6a1f1dSLionel Sambuc     if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
2929*0a6a1f1dSLionel Sambuc       if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
2930*0a6a1f1dSLionel Sambuc         return "armeb-linux-gnueabihf";
2931*0a6a1f1dSLionel Sambuc     } else {
2932*0a6a1f1dSLionel Sambuc       if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabi"))
2933*0a6a1f1dSLionel Sambuc         return "armeb-linux-gnueabi";
2934*0a6a1f1dSLionel Sambuc     }
2935*0a6a1f1dSLionel Sambuc     return TargetTriple.str();
2936f4a2713aSLionel Sambuc   case llvm::Triple::x86:
2937f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
2938f4a2713aSLionel Sambuc       return "i386-linux-gnu";
2939f4a2713aSLionel Sambuc     return TargetTriple.str();
2940f4a2713aSLionel Sambuc   case llvm::Triple::x86_64:
2941*0a6a1f1dSLionel Sambuc     // We don't want this for x32, otherwise it will match x86_64 libs
2942*0a6a1f1dSLionel Sambuc     if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 &&
2943*0a6a1f1dSLionel Sambuc         llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
2944f4a2713aSLionel Sambuc       return "x86_64-linux-gnu";
2945f4a2713aSLionel Sambuc     return TargetTriple.str();
2946f4a2713aSLionel Sambuc   case llvm::Triple::aarch64:
2947f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
2948f4a2713aSLionel Sambuc       return "aarch64-linux-gnu";
2949f4a2713aSLionel Sambuc     return TargetTriple.str();
2950*0a6a1f1dSLionel Sambuc   case llvm::Triple::aarch64_be:
2951*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
2952*0a6a1f1dSLionel Sambuc       return "aarch64_be-linux-gnu";
2953*0a6a1f1dSLionel Sambuc     return TargetTriple.str();
2954f4a2713aSLionel Sambuc   case llvm::Triple::mips:
2955f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
2956f4a2713aSLionel Sambuc       return "mips-linux-gnu";
2957f4a2713aSLionel Sambuc     return TargetTriple.str();
2958f4a2713aSLionel Sambuc   case llvm::Triple::mipsel:
2959f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
2960f4a2713aSLionel Sambuc       return "mipsel-linux-gnu";
2961f4a2713aSLionel Sambuc     return TargetTriple.str();
2962*0a6a1f1dSLionel Sambuc   case llvm::Triple::mips64:
2963*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu"))
2964*0a6a1f1dSLionel Sambuc       return "mips64-linux-gnu";
2965*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
2966*0a6a1f1dSLionel Sambuc       return "mips64-linux-gnuabi64";
2967*0a6a1f1dSLionel Sambuc     return TargetTriple.str();
2968*0a6a1f1dSLionel Sambuc   case llvm::Triple::mips64el:
2969*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu"))
2970*0a6a1f1dSLionel Sambuc       return "mips64el-linux-gnu";
2971*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
2972*0a6a1f1dSLionel Sambuc       return "mips64el-linux-gnuabi64";
2973*0a6a1f1dSLionel Sambuc     return TargetTriple.str();
2974f4a2713aSLionel Sambuc   case llvm::Triple::ppc:
2975f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
2976f4a2713aSLionel Sambuc       return "powerpc-linux-gnuspe";
2977f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))
2978f4a2713aSLionel Sambuc       return "powerpc-linux-gnu";
2979f4a2713aSLionel Sambuc     return TargetTriple.str();
2980f4a2713aSLionel Sambuc   case llvm::Triple::ppc64:
2981f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))
2982f4a2713aSLionel Sambuc       return "powerpc64-linux-gnu";
2983f4a2713aSLionel Sambuc   case llvm::Triple::ppc64le:
2984f4a2713aSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
2985f4a2713aSLionel Sambuc       return "powerpc64le-linux-gnu";
2986f4a2713aSLionel Sambuc     return TargetTriple.str();
2987f4a2713aSLionel Sambuc   }
2988f4a2713aSLionel Sambuc }
2989f4a2713aSLionel Sambuc 
addPathIfExists(Twine Path,ToolChain::path_list & Paths)2990f4a2713aSLionel Sambuc static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
2991f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
2992f4a2713aSLionel Sambuc }
2993f4a2713aSLionel Sambuc 
getOSLibDir(const llvm::Triple & Triple,const ArgList & Args)2994*0a6a1f1dSLionel Sambuc static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
2995f4a2713aSLionel Sambuc   if (isMipsArch(Triple.getArch())) {
2996f4a2713aSLionel Sambuc     // lib32 directory has a special meaning on MIPS targets.
2997f4a2713aSLionel Sambuc     // It contains N32 ABI binaries. Use this folder if produce
2998f4a2713aSLionel Sambuc     // code for N32 ABI only.
2999*0a6a1f1dSLionel Sambuc     if (tools::mips::hasMipsAbiArg(Args, "n32"))
3000f4a2713aSLionel Sambuc       return "lib32";
3001f4a2713aSLionel Sambuc     return Triple.isArch32Bit() ? "lib" : "lib64";
3002f4a2713aSLionel Sambuc   }
3003f4a2713aSLionel Sambuc 
3004*0a6a1f1dSLionel Sambuc   // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
3005f4a2713aSLionel Sambuc   // using that variant while targeting other architectures causes problems
3006f4a2713aSLionel Sambuc   // because the libraries are laid out in shared system roots that can't cope
3007*0a6a1f1dSLionel Sambuc   // with a 'lib32' library search path being considered. So we only enable
3008f4a2713aSLionel Sambuc   // them when we know we may need it.
3009f4a2713aSLionel Sambuc   //
3010f4a2713aSLionel Sambuc   // FIXME: This is a bit of a hack. We should really unify this code for
3011*0a6a1f1dSLionel Sambuc   // reasoning about oslibdir spellings with the lib dir spellings in the
3012f4a2713aSLionel Sambuc   // GCCInstallationDetector, but that is a more significant refactoring.
3013f4a2713aSLionel Sambuc   if (Triple.getArch() == llvm::Triple::x86 ||
3014f4a2713aSLionel Sambuc       Triple.getArch() == llvm::Triple::ppc)
3015f4a2713aSLionel Sambuc     return "lib32";
3016f4a2713aSLionel Sambuc 
3017*0a6a1f1dSLionel Sambuc   if (Triple.getArch() == llvm::Triple::x86_64 &&
3018*0a6a1f1dSLionel Sambuc       Triple.getEnvironment() == llvm::Triple::GNUX32)
3019*0a6a1f1dSLionel Sambuc     return "libx32";
3020*0a6a1f1dSLionel Sambuc 
3021f4a2713aSLionel Sambuc   return Triple.isArch32Bit() ? "lib" : "lib64";
3022f4a2713aSLionel Sambuc }
3023f4a2713aSLionel Sambuc 
Linux(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3024f4a2713aSLionel Sambuc Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3025f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
3026*0a6a1f1dSLionel Sambuc   GCCInstallation.init(D, Triple, Args);
3027*0a6a1f1dSLionel Sambuc   Multilibs = GCCInstallation.getMultilibs();
3028f4a2713aSLionel Sambuc   llvm::Triple::ArchType Arch = Triple.getArch();
3029f4a2713aSLionel Sambuc   std::string SysRoot = computeSysRoot();
3030f4a2713aSLionel Sambuc 
3031f4a2713aSLionel Sambuc   // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
3032f4a2713aSLionel Sambuc   // least) put various tools in a triple-prefixed directory off of the parent
3033f4a2713aSLionel Sambuc   // of the GCC installation. We use the GCC triple here to ensure that we end
3034f4a2713aSLionel Sambuc   // up with tools that support the same amount of cross compiling as the
3035f4a2713aSLionel Sambuc   // detected GCC installation. For example, if we find a GCC installation
3036f4a2713aSLionel Sambuc   // targeting x86_64, but it is a bi-arch GCC installation, it can also be
3037f4a2713aSLionel Sambuc   // used to target i386.
3038f4a2713aSLionel Sambuc   // FIXME: This seems unlikely to be Linux-specific.
3039f4a2713aSLionel Sambuc   ToolChain::path_list &PPaths = getProgramPaths();
3040f4a2713aSLionel Sambuc   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
3041f4a2713aSLionel Sambuc                          GCCInstallation.getTriple().str() + "/bin").str());
3042f4a2713aSLionel Sambuc 
3043*0a6a1f1dSLionel Sambuc   Linker = GetLinkerPath();
3044f4a2713aSLionel Sambuc 
3045f4a2713aSLionel Sambuc   Distro Distro = DetectDistro(Arch);
3046f4a2713aSLionel Sambuc 
3047f4a2713aSLionel Sambuc   if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
3048f4a2713aSLionel Sambuc     ExtraOpts.push_back("-z");
3049f4a2713aSLionel Sambuc     ExtraOpts.push_back("relro");
3050f4a2713aSLionel Sambuc   }
3051f4a2713aSLionel Sambuc 
3052f4a2713aSLionel Sambuc   if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
3053f4a2713aSLionel Sambuc     ExtraOpts.push_back("-X");
3054f4a2713aSLionel Sambuc 
3055f4a2713aSLionel Sambuc   const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android;
3056f4a2713aSLionel Sambuc   const bool IsMips = isMipsArch(Arch);
3057f4a2713aSLionel Sambuc 
3058f4a2713aSLionel Sambuc   if (IsMips && !SysRoot.empty())
3059f4a2713aSLionel Sambuc     ExtraOpts.push_back("--sysroot=" + SysRoot);
3060f4a2713aSLionel Sambuc 
3061f4a2713aSLionel Sambuc   // Do not use 'gnu' hash style for Mips targets because .gnu.hash
3062f4a2713aSLionel Sambuc   // and the MIPS ABI require .dynsym to be sorted in different ways.
3063f4a2713aSLionel Sambuc   // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
3064f4a2713aSLionel Sambuc   // ABI requires a mapping between the GOT and the symbol table.
3065f4a2713aSLionel Sambuc   // Android loader does not support .gnu.hash.
3066f4a2713aSLionel Sambuc   if (!IsMips && !IsAndroid) {
3067f4a2713aSLionel Sambuc     if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
3068f4a2713aSLionel Sambuc         (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
3069f4a2713aSLionel Sambuc       ExtraOpts.push_back("--hash-style=gnu");
3070f4a2713aSLionel Sambuc 
3071f4a2713aSLionel Sambuc     if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
3072f4a2713aSLionel Sambuc         Distro == UbuntuJaunty || Distro == UbuntuKarmic)
3073f4a2713aSLionel Sambuc       ExtraOpts.push_back("--hash-style=both");
3074f4a2713aSLionel Sambuc   }
3075f4a2713aSLionel Sambuc 
3076f4a2713aSLionel Sambuc   if (IsRedhat(Distro))
3077f4a2713aSLionel Sambuc     ExtraOpts.push_back("--no-add-needed");
3078f4a2713aSLionel Sambuc 
3079f4a2713aSLionel Sambuc   if (Distro == DebianSqueeze || Distro == DebianWheezy ||
3080f4a2713aSLionel Sambuc       Distro == DebianJessie || IsOpenSUSE(Distro) ||
3081f4a2713aSLionel Sambuc       (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
3082f4a2713aSLionel Sambuc       (IsUbuntu(Distro) && Distro >= UbuntuKarmic))
3083f4a2713aSLionel Sambuc     ExtraOpts.push_back("--build-id");
3084f4a2713aSLionel Sambuc 
3085f4a2713aSLionel Sambuc   if (IsOpenSUSE(Distro))
3086f4a2713aSLionel Sambuc     ExtraOpts.push_back("--enable-new-dtags");
3087f4a2713aSLionel Sambuc 
3088f4a2713aSLionel Sambuc   // The selection of paths to try here is designed to match the patterns which
3089f4a2713aSLionel Sambuc   // the GCC driver itself uses, as this is part of the GCC-compatible driver.
3090f4a2713aSLionel Sambuc   // This was determined by running GCC in a fake filesystem, creating all
3091f4a2713aSLionel Sambuc   // possible permutations of these directories, and seeing which ones it added
3092f4a2713aSLionel Sambuc   // to the link paths.
3093f4a2713aSLionel Sambuc   path_list &Paths = getFilePaths();
3094f4a2713aSLionel Sambuc 
3095*0a6a1f1dSLionel Sambuc   const std::string OSLibDir = getOSLibDir(Triple, Args);
3096f4a2713aSLionel Sambuc   const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
3097f4a2713aSLionel Sambuc 
3098f4a2713aSLionel Sambuc   // Add the multilib suffixed paths where they are available.
3099f4a2713aSLionel Sambuc   if (GCCInstallation.isValid()) {
3100f4a2713aSLionel Sambuc     const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
3101f4a2713aSLionel Sambuc     const std::string &LibPath = GCCInstallation.getParentLibPath();
3102*0a6a1f1dSLionel Sambuc     const Multilib &Multilib = GCCInstallation.getMultilib();
3103f4a2713aSLionel Sambuc 
3104f4a2713aSLionel Sambuc     // Sourcery CodeBench MIPS toolchain holds some libraries under
3105f4a2713aSLionel Sambuc     // a biarch-like suffix of the GCC installation.
3106f4a2713aSLionel Sambuc     addPathIfExists((GCCInstallation.getInstallPath() +
3107*0a6a1f1dSLionel Sambuc                      Multilib.gccSuffix()),
3108f4a2713aSLionel Sambuc                     Paths);
3109f4a2713aSLionel Sambuc 
3110f4a2713aSLionel Sambuc     // GCC cross compiling toolchains will install target libraries which ship
3111f4a2713aSLionel Sambuc     // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
3112f4a2713aSLionel Sambuc     // any part of the GCC installation in
3113f4a2713aSLionel Sambuc     // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
3114f4a2713aSLionel Sambuc     // debatable, but is the reality today. We need to search this tree even
3115f4a2713aSLionel Sambuc     // when we have a sysroot somewhere else. It is the responsibility of
3116*0a6a1f1dSLionel Sambuc     // whomever is doing the cross build targeting a sysroot using a GCC
3117f4a2713aSLionel Sambuc     // installation that is *not* within the system root to ensure two things:
3118f4a2713aSLionel Sambuc     //
3119f4a2713aSLionel Sambuc     //  1) Any DSOs that are linked in from this tree or from the install path
3120*0a6a1f1dSLionel Sambuc     //     above must be present on the system root and found via an
3121f4a2713aSLionel Sambuc     //     appropriate rpath.
3122f4a2713aSLionel Sambuc     //  2) There must not be libraries installed into
3123f4a2713aSLionel Sambuc     //     <prefix>/<triple>/<libdir> unless they should be preferred over
3124f4a2713aSLionel Sambuc     //     those within the system root.
3125f4a2713aSLionel Sambuc     //
3126f4a2713aSLionel Sambuc     // Note that this matches the GCC behavior. See the below comment for where
3127f4a2713aSLionel Sambuc     // Clang diverges from GCC's behavior.
3128*0a6a1f1dSLionel Sambuc     addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
3129*0a6a1f1dSLionel Sambuc                     Multilib.osSuffix(),
3130f4a2713aSLionel Sambuc                     Paths);
3131f4a2713aSLionel Sambuc 
3132f4a2713aSLionel Sambuc     // If the GCC installation we found is inside of the sysroot, we want to
3133f4a2713aSLionel Sambuc     // prefer libraries installed in the parent prefix of the GCC installation.
3134f4a2713aSLionel Sambuc     // It is important to *not* use these paths when the GCC installation is
3135f4a2713aSLionel Sambuc     // outside of the system root as that can pick up unintended libraries.
3136f4a2713aSLionel Sambuc     // This usually happens when there is an external cross compiler on the
3137f4a2713aSLionel Sambuc     // host system, and a more minimal sysroot available that is the target of
3138f4a2713aSLionel Sambuc     // the cross. Note that GCC does include some of these directories in some
3139f4a2713aSLionel Sambuc     // configurations but this seems somewhere between questionable and simply
3140f4a2713aSLionel Sambuc     // a bug.
3141f4a2713aSLionel Sambuc     if (StringRef(LibPath).startswith(SysRoot)) {
3142f4a2713aSLionel Sambuc       addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
3143*0a6a1f1dSLionel Sambuc       addPathIfExists(LibPath + "/../" + OSLibDir, Paths);
3144f4a2713aSLionel Sambuc     }
3145f4a2713aSLionel Sambuc   }
3146*0a6a1f1dSLionel Sambuc 
3147*0a6a1f1dSLionel Sambuc   // Similar to the logic for GCC above, if we currently running Clang inside
3148*0a6a1f1dSLionel Sambuc   // of the requested system root, add its parent library paths to
3149*0a6a1f1dSLionel Sambuc   // those searched.
3150*0a6a1f1dSLionel Sambuc   // FIXME: It's not clear whether we should use the driver's installed
3151*0a6a1f1dSLionel Sambuc   // directory ('Dir' below) or the ResourceDir.
3152*0a6a1f1dSLionel Sambuc   if (StringRef(D.Dir).startswith(SysRoot)) {
3153*0a6a1f1dSLionel Sambuc     addPathIfExists(D.Dir + "/../lib/" + MultiarchTriple, Paths);
3154*0a6a1f1dSLionel Sambuc     addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);
3155*0a6a1f1dSLionel Sambuc   }
3156*0a6a1f1dSLionel Sambuc 
3157f4a2713aSLionel Sambuc   addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
3158*0a6a1f1dSLionel Sambuc   addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
3159f4a2713aSLionel Sambuc   addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
3160*0a6a1f1dSLionel Sambuc   addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);
3161f4a2713aSLionel Sambuc 
3162f4a2713aSLionel Sambuc   // Try walking via the GCC triple path in case of biarch or multiarch GCC
3163f4a2713aSLionel Sambuc   // installations with strange symlinks.
3164f4a2713aSLionel Sambuc   if (GCCInstallation.isValid()) {
3165f4a2713aSLionel Sambuc     addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
3166*0a6a1f1dSLionel Sambuc                     "/../../" + OSLibDir, Paths);
3167f4a2713aSLionel Sambuc 
3168*0a6a1f1dSLionel Sambuc     // Add the 'other' biarch variant path
3169*0a6a1f1dSLionel Sambuc     Multilib BiarchSibling;
3170*0a6a1f1dSLionel Sambuc     if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
3171f4a2713aSLionel Sambuc       addPathIfExists(GCCInstallation.getInstallPath() +
3172*0a6a1f1dSLionel Sambuc                       BiarchSibling.gccSuffix(), Paths);
3173*0a6a1f1dSLionel Sambuc     }
3174f4a2713aSLionel Sambuc 
3175f4a2713aSLionel Sambuc     // See comments above on the multilib variant for details of why this is
3176f4a2713aSLionel Sambuc     // included even from outside the sysroot.
3177*0a6a1f1dSLionel Sambuc     const std::string &LibPath = GCCInstallation.getParentLibPath();
3178*0a6a1f1dSLionel Sambuc     const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
3179*0a6a1f1dSLionel Sambuc     const Multilib &Multilib = GCCInstallation.getMultilib();
3180f4a2713aSLionel Sambuc     addPathIfExists(LibPath + "/../" + GCCTriple.str() +
3181*0a6a1f1dSLionel Sambuc                     "/lib" + Multilib.osSuffix(), Paths);
3182f4a2713aSLionel Sambuc 
3183f4a2713aSLionel Sambuc     // See comments above on the multilib variant for details of why this is
3184f4a2713aSLionel Sambuc     // only included from within the sysroot.
3185f4a2713aSLionel Sambuc     if (StringRef(LibPath).startswith(SysRoot))
3186f4a2713aSLionel Sambuc       addPathIfExists(LibPath, Paths);
3187f4a2713aSLionel Sambuc   }
3188*0a6a1f1dSLionel Sambuc 
3189*0a6a1f1dSLionel Sambuc   // Similar to the logic for GCC above, if we are currently running Clang
3190*0a6a1f1dSLionel Sambuc   // inside of the requested system root, add its parent library path to those
3191*0a6a1f1dSLionel Sambuc   // searched.
3192*0a6a1f1dSLionel Sambuc   // FIXME: It's not clear whether we should use the driver's installed
3193*0a6a1f1dSLionel Sambuc   // directory ('Dir' below) or the ResourceDir.
3194*0a6a1f1dSLionel Sambuc   if (StringRef(D.Dir).startswith(SysRoot))
3195*0a6a1f1dSLionel Sambuc     addPathIfExists(D.Dir + "/../lib", Paths);
3196*0a6a1f1dSLionel Sambuc 
3197f4a2713aSLionel Sambuc   addPathIfExists(SysRoot + "/lib", Paths);
3198f4a2713aSLionel Sambuc   addPathIfExists(SysRoot + "/usr/lib", Paths);
3199f4a2713aSLionel Sambuc }
3200f4a2713aSLionel Sambuc 
HasNativeLLVMSupport() const3201f4a2713aSLionel Sambuc bool Linux::HasNativeLLVMSupport() const {
3202f4a2713aSLionel Sambuc   return true;
3203f4a2713aSLionel Sambuc }
3204f4a2713aSLionel Sambuc 
buildLinker() const3205f4a2713aSLionel Sambuc Tool *Linux::buildLinker() const {
3206f4a2713aSLionel Sambuc   return new tools::gnutools::Link(*this);
3207f4a2713aSLionel Sambuc }
3208f4a2713aSLionel Sambuc 
buildAssembler() const3209f4a2713aSLionel Sambuc Tool *Linux::buildAssembler() const {
3210f4a2713aSLionel Sambuc   return new tools::gnutools::Assemble(*this);
3211f4a2713aSLionel Sambuc }
3212f4a2713aSLionel Sambuc 
computeSysRoot() const3213f4a2713aSLionel Sambuc std::string Linux::computeSysRoot() const {
3214f4a2713aSLionel Sambuc   if (!getDriver().SysRoot.empty())
3215f4a2713aSLionel Sambuc     return getDriver().SysRoot;
3216f4a2713aSLionel Sambuc 
3217f4a2713aSLionel Sambuc   if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
3218f4a2713aSLionel Sambuc     return std::string();
3219f4a2713aSLionel Sambuc 
3220f4a2713aSLionel Sambuc   // Standalone MIPS toolchains use different names for sysroot folder
3221f4a2713aSLionel Sambuc   // and put it into different places. Here we try to check some known
3222f4a2713aSLionel Sambuc   // variants.
3223f4a2713aSLionel Sambuc 
3224f4a2713aSLionel Sambuc   const StringRef InstallDir = GCCInstallation.getInstallPath();
3225f4a2713aSLionel Sambuc   const StringRef TripleStr = GCCInstallation.getTriple().str();
3226*0a6a1f1dSLionel Sambuc   const Multilib &Multilib = GCCInstallation.getMultilib();
3227f4a2713aSLionel Sambuc 
3228f4a2713aSLionel Sambuc   std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
3229*0a6a1f1dSLionel Sambuc                       Multilib.osSuffix()).str();
3230f4a2713aSLionel Sambuc 
3231f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(Path))
3232f4a2713aSLionel Sambuc     return Path;
3233f4a2713aSLionel Sambuc 
3234*0a6a1f1dSLionel Sambuc   Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
3235f4a2713aSLionel Sambuc 
3236f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists(Path))
3237f4a2713aSLionel Sambuc     return Path;
3238f4a2713aSLionel Sambuc 
3239f4a2713aSLionel Sambuc   return std::string();
3240f4a2713aSLionel Sambuc }
3241f4a2713aSLionel Sambuc 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3242f4a2713aSLionel Sambuc void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3243f4a2713aSLionel Sambuc                                       ArgStringList &CC1Args) const {
3244f4a2713aSLionel Sambuc   const Driver &D = getDriver();
3245f4a2713aSLionel Sambuc   std::string SysRoot = computeSysRoot();
3246f4a2713aSLionel Sambuc 
3247f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdinc))
3248f4a2713aSLionel Sambuc     return;
3249f4a2713aSLionel Sambuc 
3250f4a2713aSLionel Sambuc   if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
3251f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
3252f4a2713aSLionel Sambuc 
3253f4a2713aSLionel Sambuc   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3254f4a2713aSLionel Sambuc     SmallString<128> P(D.ResourceDir);
3255f4a2713aSLionel Sambuc     llvm::sys::path::append(P, "include");
3256f4a2713aSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args, P.str());
3257f4a2713aSLionel Sambuc   }
3258f4a2713aSLionel Sambuc 
3259f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3260f4a2713aSLionel Sambuc     return;
3261f4a2713aSLionel Sambuc 
3262f4a2713aSLionel Sambuc   // Check for configure-time C include directories.
3263f4a2713aSLionel Sambuc   StringRef CIncludeDirs(C_INCLUDE_DIRS);
3264f4a2713aSLionel Sambuc   if (CIncludeDirs != "") {
3265f4a2713aSLionel Sambuc     SmallVector<StringRef, 5> dirs;
3266f4a2713aSLionel Sambuc     CIncludeDirs.split(dirs, ":");
3267*0a6a1f1dSLionel Sambuc     for (StringRef dir : dirs) {
3268*0a6a1f1dSLionel Sambuc       StringRef Prefix =
3269*0a6a1f1dSLionel Sambuc           llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
3270*0a6a1f1dSLionel Sambuc       addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
3271f4a2713aSLionel Sambuc     }
3272f4a2713aSLionel Sambuc     return;
3273f4a2713aSLionel Sambuc   }
3274f4a2713aSLionel Sambuc 
3275f4a2713aSLionel Sambuc   // Lacking those, try to detect the correct set of system includes for the
3276f4a2713aSLionel Sambuc   // target triple.
3277f4a2713aSLionel Sambuc 
3278*0a6a1f1dSLionel Sambuc   // Add include directories specific to the selected multilib set and multilib.
3279*0a6a1f1dSLionel Sambuc   if (GCCInstallation.isValid()) {
3280*0a6a1f1dSLionel Sambuc     auto Callback = Multilibs.includeDirsCallback();
3281*0a6a1f1dSLionel Sambuc     if (Callback) {
3282*0a6a1f1dSLionel Sambuc       const auto IncludePaths = Callback(GCCInstallation.getInstallPath(),
3283*0a6a1f1dSLionel Sambuc                                          GCCInstallation.getTriple().str(),
3284*0a6a1f1dSLionel Sambuc                                          GCCInstallation.getMultilib());
3285*0a6a1f1dSLionel Sambuc       for (const auto &Path : IncludePaths)
3286*0a6a1f1dSLionel Sambuc         addExternCSystemIncludeIfExists(DriverArgs, CC1Args, Path);
3287*0a6a1f1dSLionel Sambuc     }
3288f4a2713aSLionel Sambuc   }
3289f4a2713aSLionel Sambuc 
3290f4a2713aSLionel Sambuc   // Implement generic Debian multiarch support.
3291f4a2713aSLionel Sambuc   const StringRef X86_64MultiarchIncludeDirs[] = {
3292f4a2713aSLionel Sambuc     "/usr/include/x86_64-linux-gnu",
3293f4a2713aSLionel Sambuc 
3294f4a2713aSLionel Sambuc     // FIXME: These are older forms of multiarch. It's not clear that they're
3295f4a2713aSLionel Sambuc     // in use in any released version of Debian, so we should consider
3296f4a2713aSLionel Sambuc     // removing them.
3297f4a2713aSLionel Sambuc     "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"
3298f4a2713aSLionel Sambuc   };
3299f4a2713aSLionel Sambuc   const StringRef X86MultiarchIncludeDirs[] = {
3300f4a2713aSLionel Sambuc     "/usr/include/i386-linux-gnu",
3301f4a2713aSLionel Sambuc 
3302f4a2713aSLionel Sambuc     // FIXME: These are older forms of multiarch. It's not clear that they're
3303f4a2713aSLionel Sambuc     // in use in any released version of Debian, so we should consider
3304f4a2713aSLionel Sambuc     // removing them.
3305f4a2713aSLionel Sambuc     "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
3306f4a2713aSLionel Sambuc     "/usr/include/i486-linux-gnu"
3307f4a2713aSLionel Sambuc   };
3308f4a2713aSLionel Sambuc   const StringRef AArch64MultiarchIncludeDirs[] = {
3309f4a2713aSLionel Sambuc     "/usr/include/aarch64-linux-gnu"
3310f4a2713aSLionel Sambuc   };
3311f4a2713aSLionel Sambuc   const StringRef ARMMultiarchIncludeDirs[] = {
3312f4a2713aSLionel Sambuc     "/usr/include/arm-linux-gnueabi"
3313f4a2713aSLionel Sambuc   };
3314f4a2713aSLionel Sambuc   const StringRef ARMHFMultiarchIncludeDirs[] = {
3315f4a2713aSLionel Sambuc     "/usr/include/arm-linux-gnueabihf"
3316f4a2713aSLionel Sambuc   };
3317f4a2713aSLionel Sambuc   const StringRef MIPSMultiarchIncludeDirs[] = {
3318f4a2713aSLionel Sambuc     "/usr/include/mips-linux-gnu"
3319f4a2713aSLionel Sambuc   };
3320f4a2713aSLionel Sambuc   const StringRef MIPSELMultiarchIncludeDirs[] = {
3321f4a2713aSLionel Sambuc     "/usr/include/mipsel-linux-gnu"
3322f4a2713aSLionel Sambuc   };
3323*0a6a1f1dSLionel Sambuc   const StringRef MIPS64MultiarchIncludeDirs[] = {
3324*0a6a1f1dSLionel Sambuc     "/usr/include/mips64-linux-gnu",
3325*0a6a1f1dSLionel Sambuc     "/usr/include/mips64-linux-gnuabi64"
3326*0a6a1f1dSLionel Sambuc   };
3327*0a6a1f1dSLionel Sambuc   const StringRef MIPS64ELMultiarchIncludeDirs[] = {
3328*0a6a1f1dSLionel Sambuc     "/usr/include/mips64el-linux-gnu",
3329*0a6a1f1dSLionel Sambuc     "/usr/include/mips64el-linux-gnuabi64"
3330*0a6a1f1dSLionel Sambuc   };
3331f4a2713aSLionel Sambuc   const StringRef PPCMultiarchIncludeDirs[] = {
3332f4a2713aSLionel Sambuc     "/usr/include/powerpc-linux-gnu"
3333f4a2713aSLionel Sambuc   };
3334f4a2713aSLionel Sambuc   const StringRef PPC64MultiarchIncludeDirs[] = {
3335f4a2713aSLionel Sambuc     "/usr/include/powerpc64-linux-gnu"
3336f4a2713aSLionel Sambuc   };
3337*0a6a1f1dSLionel Sambuc   const StringRef PPC64LEMultiarchIncludeDirs[] = {
3338*0a6a1f1dSLionel Sambuc     "/usr/include/powerpc64le-linux-gnu"
3339*0a6a1f1dSLionel Sambuc   };
3340f4a2713aSLionel Sambuc   ArrayRef<StringRef> MultiarchIncludeDirs;
3341f4a2713aSLionel Sambuc   if (getTriple().getArch() == llvm::Triple::x86_64) {
3342f4a2713aSLionel Sambuc     MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
3343f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::x86) {
3344f4a2713aSLionel Sambuc     MultiarchIncludeDirs = X86MultiarchIncludeDirs;
3345*0a6a1f1dSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::aarch64 ||
3346*0a6a1f1dSLionel Sambuc              getTriple().getArch() == llvm::Triple::aarch64_be) {
3347f4a2713aSLionel Sambuc     MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
3348f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::arm) {
3349f4a2713aSLionel Sambuc     if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
3350f4a2713aSLionel Sambuc       MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
3351f4a2713aSLionel Sambuc     else
3352f4a2713aSLionel Sambuc       MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
3353f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::mips) {
3354f4a2713aSLionel Sambuc     MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
3355f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::mipsel) {
3356f4a2713aSLionel Sambuc     MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
3357*0a6a1f1dSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::mips64) {
3358*0a6a1f1dSLionel Sambuc     MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
3359*0a6a1f1dSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::mips64el) {
3360*0a6a1f1dSLionel Sambuc     MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
3361f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::ppc) {
3362f4a2713aSLionel Sambuc     MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
3363f4a2713aSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::ppc64) {
3364f4a2713aSLionel Sambuc     MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
3365*0a6a1f1dSLionel Sambuc   } else if (getTriple().getArch() == llvm::Triple::ppc64le) {
3366*0a6a1f1dSLionel Sambuc     MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
3367f4a2713aSLionel Sambuc   }
3368*0a6a1f1dSLionel Sambuc   for (StringRef Dir : MultiarchIncludeDirs) {
3369*0a6a1f1dSLionel Sambuc     if (llvm::sys::fs::exists(SysRoot + Dir)) {
3370*0a6a1f1dSLionel Sambuc       addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
3371f4a2713aSLionel Sambuc       break;
3372f4a2713aSLionel Sambuc     }
3373f4a2713aSLionel Sambuc   }
3374f4a2713aSLionel Sambuc 
3375f4a2713aSLionel Sambuc   if (getTriple().getOS() == llvm::Triple::RTEMS)
3376f4a2713aSLionel Sambuc     return;
3377f4a2713aSLionel Sambuc 
3378f4a2713aSLionel Sambuc   // Add an include of '/include' directly. This isn't provided by default by
3379f4a2713aSLionel Sambuc   // system GCCs, but is often used with cross-compiling GCCs, and harmless to
3380f4a2713aSLionel Sambuc   // add even when Clang is acting as-if it were a system compiler.
3381f4a2713aSLionel Sambuc   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
3382f4a2713aSLionel Sambuc 
3383f4a2713aSLionel Sambuc   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
3384f4a2713aSLionel Sambuc }
3385f4a2713aSLionel Sambuc 
3386*0a6a1f1dSLionel Sambuc /// \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)3387*0a6a1f1dSLionel Sambuc /*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
3388*0a6a1f1dSLionel Sambuc                                                 StringRef GCCTriple,
3389*0a6a1f1dSLionel Sambuc                                                 StringRef GCCMultiarchTriple,
3390*0a6a1f1dSLionel Sambuc                                                 StringRef TargetMultiarchTriple,
3391*0a6a1f1dSLionel Sambuc                                                 Twine IncludeSuffix,
3392f4a2713aSLionel Sambuc                                                 const ArgList &DriverArgs,
3393f4a2713aSLionel Sambuc                                                 ArgStringList &CC1Args) {
3394*0a6a1f1dSLionel Sambuc   if (!llvm::sys::fs::exists(Base + Suffix))
3395f4a2713aSLionel Sambuc     return false;
3396*0a6a1f1dSLionel Sambuc 
3397*0a6a1f1dSLionel Sambuc   addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
3398*0a6a1f1dSLionel Sambuc 
3399*0a6a1f1dSLionel Sambuc   // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
3400*0a6a1f1dSLionel Sambuc   // that path exists or we have neither a GCC nor target multiarch triple, use
3401*0a6a1f1dSLionel Sambuc   // this vanilla search path.
3402*0a6a1f1dSLionel Sambuc   if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
3403*0a6a1f1dSLionel Sambuc       llvm::sys::fs::exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
3404*0a6a1f1dSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
3405*0a6a1f1dSLionel Sambuc                      Base + Suffix + "/" + GCCTriple + IncludeSuffix);
3406*0a6a1f1dSLionel Sambuc   } else {
3407*0a6a1f1dSLionel Sambuc     // Otherwise try to use multiarch naming schemes which have normalized the
3408*0a6a1f1dSLionel Sambuc     // triples and put the triple before the suffix.
3409*0a6a1f1dSLionel Sambuc     //
3410*0a6a1f1dSLionel Sambuc     // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
3411*0a6a1f1dSLionel Sambuc     // the target triple, so we support that here.
3412*0a6a1f1dSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
3413*0a6a1f1dSLionel Sambuc                      Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
3414*0a6a1f1dSLionel Sambuc     addSystemInclude(DriverArgs, CC1Args,
3415*0a6a1f1dSLionel Sambuc                      Base + "/" + TargetMultiarchTriple + Suffix);
3416f4a2713aSLionel Sambuc   }
3417f4a2713aSLionel Sambuc 
3418*0a6a1f1dSLionel Sambuc   addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
3419f4a2713aSLionel Sambuc   return true;
3420f4a2713aSLionel Sambuc }
3421f4a2713aSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3422f4a2713aSLionel Sambuc void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3423f4a2713aSLionel Sambuc                                          ArgStringList &CC1Args) const {
3424f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3425f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
3426f4a2713aSLionel Sambuc     return;
3427f4a2713aSLionel Sambuc 
3428f4a2713aSLionel Sambuc   // Check if libc++ has been enabled and provide its include paths if so.
3429f4a2713aSLionel Sambuc   if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
3430*0a6a1f1dSLionel Sambuc     const std::string LibCXXIncludePathCandidates[] = {
3431*0a6a1f1dSLionel Sambuc       // The primary location is within the Clang installation.
3432*0a6a1f1dSLionel Sambuc       // FIXME: We shouldn't hard code 'v1' here to make Clang future proof to
3433*0a6a1f1dSLionel Sambuc       // newer ABI versions.
3434*0a6a1f1dSLionel Sambuc       getDriver().Dir + "/../include/c++/v1",
3435*0a6a1f1dSLionel Sambuc 
3436*0a6a1f1dSLionel Sambuc       // We also check the system as for a long time this is the only place Clang looked.
3437*0a6a1f1dSLionel Sambuc       // FIXME: We should really remove this. It doesn't make any sense.
3438*0a6a1f1dSLionel Sambuc       getDriver().SysRoot + "/usr/include/c++/v1"
3439*0a6a1f1dSLionel Sambuc     };
3440*0a6a1f1dSLionel Sambuc     for (const auto &IncludePath : LibCXXIncludePathCandidates) {
3441*0a6a1f1dSLionel Sambuc       if (!llvm::sys::fs::exists(IncludePath))
3442*0a6a1f1dSLionel Sambuc         continue;
3443*0a6a1f1dSLionel Sambuc       // Add the first candidate that exists.
3444*0a6a1f1dSLionel Sambuc       addSystemInclude(DriverArgs, CC1Args, IncludePath);
3445*0a6a1f1dSLionel Sambuc       break;
3446*0a6a1f1dSLionel Sambuc     }
3447f4a2713aSLionel Sambuc     return;
3448f4a2713aSLionel Sambuc   }
3449f4a2713aSLionel Sambuc 
3450f4a2713aSLionel Sambuc   // We need a detected GCC installation on Linux to provide libstdc++'s
3451f4a2713aSLionel Sambuc   // headers. We handled the libc++ case above.
3452f4a2713aSLionel Sambuc   if (!GCCInstallation.isValid())
3453f4a2713aSLionel Sambuc     return;
3454f4a2713aSLionel Sambuc 
3455f4a2713aSLionel Sambuc   // By default, look for the C++ headers in an include directory adjacent to
3456f4a2713aSLionel Sambuc   // the lib directory of the GCC installation. Note that this is expect to be
3457f4a2713aSLionel Sambuc   // equivalent to '/usr/include/c++/X.Y' in almost all cases.
3458f4a2713aSLionel Sambuc   StringRef LibDir = GCCInstallation.getParentLibPath();
3459f4a2713aSLionel Sambuc   StringRef InstallDir = GCCInstallation.getInstallPath();
3460f4a2713aSLionel Sambuc   StringRef TripleStr = GCCInstallation.getTriple().str();
3461*0a6a1f1dSLionel Sambuc   const Multilib &Multilib = GCCInstallation.getMultilib();
3462*0a6a1f1dSLionel Sambuc   const std::string GCCMultiarchTriple =
3463*0a6a1f1dSLionel Sambuc       getMultiarchTriple(GCCInstallation.getTriple(), getDriver().SysRoot);
3464*0a6a1f1dSLionel Sambuc   const std::string TargetMultiarchTriple =
3465*0a6a1f1dSLionel Sambuc       getMultiarchTriple(getTriple(), getDriver().SysRoot);
3466f4a2713aSLionel Sambuc   const GCCVersion &Version = GCCInstallation.getVersion();
3467f4a2713aSLionel Sambuc 
3468*0a6a1f1dSLionel Sambuc   // The primary search for libstdc++ supports multiarch variants.
3469f4a2713aSLionel Sambuc   if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
3470*0a6a1f1dSLionel Sambuc                                "/c++/" + Version.Text, TripleStr, GCCMultiarchTriple,
3471*0a6a1f1dSLionel Sambuc                                TargetMultiarchTriple,
3472*0a6a1f1dSLionel Sambuc                                Multilib.includeSuffix(), DriverArgs, CC1Args))
3473f4a2713aSLionel Sambuc     return;
3474f4a2713aSLionel Sambuc 
3475*0a6a1f1dSLionel Sambuc   // Otherwise, fall back on a bunch of options which don't use multiarch
3476*0a6a1f1dSLionel Sambuc   // layouts for simplicity.
3477*0a6a1f1dSLionel Sambuc   const std::string LibStdCXXIncludePathCandidates[] = {
3478f4a2713aSLionel Sambuc     // Gentoo is weird and places its headers inside the GCC install, so if the
3479f4a2713aSLionel Sambuc     // first attempt to find the headers fails, try these patterns.
3480f4a2713aSLionel Sambuc     InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
3481f4a2713aSLionel Sambuc         Version.MinorStr,
3482f4a2713aSLionel Sambuc     InstallDir.str() + "/include/g++-v" + Version.MajorStr,
3483f4a2713aSLionel Sambuc     // Android standalone toolchain has C++ headers in yet another place.
3484f4a2713aSLionel Sambuc     LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
3485f4a2713aSLionel Sambuc     // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
3486f4a2713aSLionel Sambuc     // without a subdirectory corresponding to the gcc version.
3487f4a2713aSLionel Sambuc     LibDir.str() + "/../include/c++",
3488f4a2713aSLionel Sambuc   };
3489f4a2713aSLionel Sambuc 
3490*0a6a1f1dSLionel Sambuc   for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
3491*0a6a1f1dSLionel Sambuc     if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
3492*0a6a1f1dSLionel Sambuc                                  /*GCCMultiarchTriple*/ "",
3493*0a6a1f1dSLionel Sambuc                                  /*TargetMultiarchTriple*/ "",
3494*0a6a1f1dSLionel Sambuc                                  Multilib.includeSuffix(), DriverArgs, CC1Args))
3495f4a2713aSLionel Sambuc       break;
3496f4a2713aSLionel Sambuc   }
3497f4a2713aSLionel Sambuc }
3498f4a2713aSLionel Sambuc 
isPIEDefault() const3499f4a2713aSLionel Sambuc bool Linux::isPIEDefault() const {
3500*0a6a1f1dSLionel Sambuc   return getSanitizerArgs().requiresPIE();
3501f4a2713aSLionel Sambuc }
3502f4a2713aSLionel Sambuc 
3503f4a2713aSLionel Sambuc /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
3504f4a2713aSLionel Sambuc 
DragonFly(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3505f4a2713aSLionel Sambuc DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
3506f4a2713aSLionel Sambuc   : Generic_ELF(D, Triple, Args) {
3507f4a2713aSLionel Sambuc 
3508f4a2713aSLionel Sambuc   // Path mangling to find libexec
3509f4a2713aSLionel Sambuc   getProgramPaths().push_back(getDriver().getInstalledDir());
3510f4a2713aSLionel Sambuc   if (getDriver().getInstalledDir() != getDriver().Dir)
3511f4a2713aSLionel Sambuc     getProgramPaths().push_back(getDriver().Dir);
3512f4a2713aSLionel Sambuc 
3513f4a2713aSLionel Sambuc   getFilePaths().push_back(getDriver().Dir + "/../lib");
3514f4a2713aSLionel Sambuc   getFilePaths().push_back("/usr/lib");
3515f4a2713aSLionel Sambuc   if (llvm::sys::fs::exists("/usr/lib/gcc47"))
3516f4a2713aSLionel Sambuc     getFilePaths().push_back("/usr/lib/gcc47");
3517f4a2713aSLionel Sambuc   else
3518f4a2713aSLionel Sambuc     getFilePaths().push_back("/usr/lib/gcc44");
3519f4a2713aSLionel Sambuc }
3520f4a2713aSLionel Sambuc 
buildAssembler() const3521f4a2713aSLionel Sambuc Tool *DragonFly::buildAssembler() const {
3522f4a2713aSLionel Sambuc   return new tools::dragonfly::Assemble(*this);
3523f4a2713aSLionel Sambuc }
3524f4a2713aSLionel Sambuc 
buildLinker() const3525f4a2713aSLionel Sambuc Tool *DragonFly::buildLinker() const {
3526f4a2713aSLionel Sambuc   return new tools::dragonfly::Link(*this);
3527f4a2713aSLionel Sambuc }
3528f4a2713aSLionel Sambuc 
3529f4a2713aSLionel Sambuc 
3530f4a2713aSLionel Sambuc /// XCore tool chain
XCore(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3531f4a2713aSLionel Sambuc XCore::XCore(const Driver &D, const llvm::Triple &Triple,
3532f4a2713aSLionel Sambuc              const ArgList &Args) : ToolChain(D, Triple, Args) {
3533f4a2713aSLionel Sambuc   // ProgramPaths are found via 'PATH' environment variable.
3534f4a2713aSLionel Sambuc }
3535f4a2713aSLionel Sambuc 
buildAssembler() const3536f4a2713aSLionel Sambuc Tool *XCore::buildAssembler() const {
3537f4a2713aSLionel Sambuc   return new tools::XCore::Assemble(*this);
3538f4a2713aSLionel Sambuc }
3539f4a2713aSLionel Sambuc 
buildLinker() const3540f4a2713aSLionel Sambuc Tool *XCore::buildLinker() const {
3541f4a2713aSLionel Sambuc   return new tools::XCore::Link(*this);
3542f4a2713aSLionel Sambuc }
3543f4a2713aSLionel Sambuc 
isPICDefault() const3544f4a2713aSLionel Sambuc bool XCore::isPICDefault() const {
3545f4a2713aSLionel Sambuc   return false;
3546f4a2713aSLionel Sambuc }
3547f4a2713aSLionel Sambuc 
isPIEDefault() const3548f4a2713aSLionel Sambuc bool XCore::isPIEDefault() const {
3549f4a2713aSLionel Sambuc   return false;
3550f4a2713aSLionel Sambuc }
3551f4a2713aSLionel Sambuc 
isPICDefaultForced() const3552f4a2713aSLionel Sambuc bool XCore::isPICDefaultForced() const {
3553f4a2713aSLionel Sambuc   return false;
3554f4a2713aSLionel Sambuc }
3555f4a2713aSLionel Sambuc 
SupportsProfiling() const3556f4a2713aSLionel Sambuc bool XCore::SupportsProfiling() const {
3557f4a2713aSLionel Sambuc   return false;
3558f4a2713aSLionel Sambuc }
3559f4a2713aSLionel Sambuc 
hasBlocksRuntime() const3560f4a2713aSLionel Sambuc bool XCore::hasBlocksRuntime() const {
3561f4a2713aSLionel Sambuc   return false;
3562f4a2713aSLionel Sambuc }
3563f4a2713aSLionel Sambuc 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3564f4a2713aSLionel Sambuc void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3565f4a2713aSLionel Sambuc                                       ArgStringList &CC1Args) const {
3566f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3567f4a2713aSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdlibinc))
3568f4a2713aSLionel Sambuc     return;
3569f4a2713aSLionel Sambuc   if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
3570f4a2713aSLionel Sambuc     SmallVector<StringRef, 4> Dirs;
3571f4a2713aSLionel Sambuc     const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
3572f4a2713aSLionel Sambuc     StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
3573f4a2713aSLionel Sambuc     ArrayRef<StringRef> DirVec(Dirs);
3574f4a2713aSLionel Sambuc     addSystemIncludes(DriverArgs, CC1Args, DirVec);
3575f4a2713aSLionel Sambuc   }
3576f4a2713aSLionel Sambuc }
3577f4a2713aSLionel Sambuc 
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const3578f4a2713aSLionel Sambuc void XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
3579f4a2713aSLionel Sambuc                                      llvm::opt::ArgStringList &CC1Args) const {
3580f4a2713aSLionel Sambuc   CC1Args.push_back("-nostdsysteminc");
3581f4a2713aSLionel Sambuc }
3582f4a2713aSLionel Sambuc 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const3583f4a2713aSLionel Sambuc void XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3584f4a2713aSLionel Sambuc                                          ArgStringList &CC1Args) const {
3585f4a2713aSLionel Sambuc   if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3586*0a6a1f1dSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3587*0a6a1f1dSLionel Sambuc       DriverArgs.hasArg(options::OPT_nostdincxx))
3588f4a2713aSLionel Sambuc     return;
3589f4a2713aSLionel Sambuc   if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
3590f4a2713aSLionel Sambuc     SmallVector<StringRef, 4> Dirs;
3591f4a2713aSLionel Sambuc     const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
3592f4a2713aSLionel Sambuc     StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
3593f4a2713aSLionel Sambuc     ArrayRef<StringRef> DirVec(Dirs);
3594f4a2713aSLionel Sambuc     addSystemIncludes(DriverArgs, CC1Args, DirVec);
3595f4a2713aSLionel Sambuc   }
3596f4a2713aSLionel Sambuc }
3597f4a2713aSLionel Sambuc 
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const3598f4a2713aSLionel Sambuc void XCore::AddCXXStdlibLibArgs(const ArgList &Args,
3599f4a2713aSLionel Sambuc                                 ArgStringList &CmdArgs) const {
3600f4a2713aSLionel Sambuc   // We don't output any lib args. This is handled by xcc.
3601f4a2713aSLionel Sambuc }
3602