ToolChains.cpp revision 255321
1218893Sdim//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed
10193326Sed#include "ToolChains.h"
11249423Sdim#include "SanitizerArgs.h"
12249423Sdim#include "clang/Basic/ObjCRuntime.h"
13249423Sdim#include "clang/Basic/Version.h"
14193326Sed#include "clang/Driver/Arg.h"
15193326Sed#include "clang/Driver/ArgList.h"
16208600Srdivacky#include "clang/Driver/Compilation.h"
17193326Sed#include "clang/Driver/Driver.h"
18193326Sed#include "clang/Driver/DriverDiagnostic.h"
19199512Srdivacky#include "clang/Driver/OptTable.h"
20193326Sed#include "clang/Driver/Option.h"
21199512Srdivacky#include "clang/Driver/Options.h"
22249423Sdim#include "llvm/ADT/STLExtras.h"
23212904Sdim#include "llvm/ADT/SmallString.h"
24193326Sed#include "llvm/ADT/StringExtras.h"
25226633Sdim#include "llvm/ADT/StringSwitch.h"
26198092Srdivacky#include "llvm/Support/ErrorHandling.h"
27218893Sdim#include "llvm/Support/FileSystem.h"
28218893Sdim#include "llvm/Support/MemoryBuffer.h"
29249423Sdim#include "llvm/Support/Path.h"
30193326Sed#include "llvm/Support/raw_ostream.h"
31218893Sdim#include "llvm/Support/system_error.h"
32193326Sed
33249423Sdim// FIXME: This needs to be listed last until we fix the broken include guards
34249423Sdim// in these files and the LLVM config.h files.
35249423Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
36243830Sdim
37193326Sed#include <cstdlib> // ::getenv
38193326Sed
39193326Sedusing namespace clang::driver;
40193326Sedusing namespace clang::driver::toolchains;
41226633Sdimusing namespace clang;
42193326Sed
43198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64.
44193326Sed
45249423SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
46249423Sdim  : ToolChain(D, Triple, Args), TargetInitialized(false)
47198092Srdivacky{
48234353Sdim  // Compute the initial Darwin version from the triple
49234353Sdim  unsigned Major, Minor, Micro;
50234353Sdim  if (!Triple.getMacOSXVersion(Major, Minor, Micro))
51234353Sdim    getDriver().Diag(diag::err_drv_invalid_darwin_version) <<
52234353Sdim      Triple.getOSName();
53234353Sdim  llvm::raw_string_ostream(MacosxVersionMin)
54234353Sdim    << Major << '.' << Minor << '.' << Micro;
55212904Sdim
56234353Sdim  // FIXME: DarwinVersion is only used to find GCC's libexec directory.
57234353Sdim  // It should be removed when we stop supporting that.
58234353Sdim  DarwinVersion[0] = Minor + 4;
59234353Sdim  DarwinVersion[1] = Micro;
60234353Sdim  DarwinVersion[2] = 0;
61239462Sdim
62239462Sdim  // Compute the initial iOS version from the triple
63239462Sdim  Triple.getiOSVersion(Major, Minor, Micro);
64239462Sdim  llvm::raw_string_ostream(iOSVersionMin)
65239462Sdim    << Major << '.' << Minor << '.' << Micro;
66198092Srdivacky}
67198092Srdivacky
68212904Sdimtypes::ID Darwin::LookupTypeForExtension(const char *Ext) const {
69212904Sdim  types::ID Ty = types::lookupTypeForExtension(Ext);
70212904Sdim
71212904Sdim  // Darwin always preprocesses assembly files (unless -x is used explicitly).
72212904Sdim  if (Ty == types::TY_PP_Asm)
73212904Sdim    return types::TY_Asm;
74212904Sdim
75212904Sdim  return Ty;
76212904Sdim}
77212904Sdim
78218893Sdimbool Darwin::HasNativeLLVMSupport() const {
79218893Sdim  return true;
80218893Sdim}
81218893Sdim
82239462Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
83239462SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
84243830Sdim  if (isTargetIPhoneOS())
85239462Sdim    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
86243830Sdim  if (isNonFragile)
87243830Sdim    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
88243830Sdim  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
89224145Sdim}
90224145Sdim
91226633Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
92226633Sdimbool Darwin::hasBlocksRuntime() const {
93226633Sdim  if (isTargetIPhoneOS())
94226633Sdim    return !isIPhoneOSVersionLT(3, 2);
95226633Sdim  else
96226633Sdim    return !isMacosxVersionLT(10, 6);
97226633Sdim}
98202879Srdivacky
99226633Sdimstatic const char *GetArmArchForMArch(StringRef Value) {
100226633Sdim  return llvm::StringSwitch<const char*>(Value)
101226633Sdim    .Case("armv6k", "armv6")
102249423Sdim    .Case("armv6m", "armv6m")
103226633Sdim    .Case("armv5tej", "armv5")
104226633Sdim    .Case("xscale", "xscale")
105226633Sdim    .Case("armv4t", "armv4t")
106226633Sdim    .Case("armv7", "armv7")
107226633Sdim    .Cases("armv7a", "armv7-a", "armv7")
108226633Sdim    .Cases("armv7r", "armv7-r", "armv7")
109249423Sdim    .Cases("armv7em", "armv7e-m", "armv7em")
110243830Sdim    .Cases("armv7f", "armv7-f", "armv7f")
111243830Sdim    .Cases("armv7k", "armv7-k", "armv7k")
112249423Sdim    .Cases("armv7m", "armv7-m", "armv7m")
113243830Sdim    .Cases("armv7s", "armv7-s", "armv7s")
114226633Sdim    .Default(0);
115202879Srdivacky}
116202879Srdivacky
117226633Sdimstatic const char *GetArmArchForMCpu(StringRef Value) {
118226633Sdim  return llvm::StringSwitch<const char *>(Value)
119226633Sdim    .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
120226633Sdim    .Cases("arm10e", "arm10tdmi", "armv5")
121226633Sdim    .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
122226633Sdim    .Case("xscale", "xscale")
123249423Sdim    .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
124249423Sdim    .Case("cortex-m0", "armv6m")
125249423Sdim    .Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
126243830Sdim    .Case("cortex-a9-mp", "armv7f")
127249423Sdim    .Case("cortex-m3", "armv7m")
128249423Sdim    .Case("cortex-m4", "armv7em")
129243830Sdim    .Case("swift", "armv7s")
130226633Sdim    .Default(0);
131202879Srdivacky}
132202879Srdivacky
133226633SdimStringRef Darwin::getDarwinArchName(const ArgList &Args) const {
134202879Srdivacky  switch (getTriple().getArch()) {
135202879Srdivacky  default:
136202879Srdivacky    return getArchName();
137223017Sdim
138221345Sdim  case llvm::Triple::thumb:
139202879Srdivacky  case llvm::Triple::arm: {
140202879Srdivacky    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
141243830Sdim      if (const char *Arch = GetArmArchForMArch(A->getValue()))
142202879Srdivacky        return Arch;
143202879Srdivacky
144202879Srdivacky    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
145243830Sdim      if (const char *Arch = GetArmArchForMCpu(A->getValue()))
146202879Srdivacky        return Arch;
147202879Srdivacky
148202879Srdivacky    return "arm";
149202879Srdivacky  }
150202879Srdivacky  }
151202879Srdivacky}
152202879Srdivacky
153198092SrdivackyDarwin::~Darwin() {
154193326Sed}
155193326Sed
156226633Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
157226633Sdim                                                types::ID InputType) const {
158226633Sdim  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
159212904Sdim
160212904Sdim  // If the target isn't initialized (e.g., an unknown Darwin platform, return
161212904Sdim  // the default triple).
162212904Sdim  if (!isTargetInitialized())
163212904Sdim    return Triple.getTriple();
164223017Sdim
165234353Sdim  SmallString<16> Str;
166234353Sdim  Str += isTargetIPhoneOS() ? "ios" : "macosx";
167234353Sdim  Str += getTargetVersion().getAsString();
168234353Sdim  Triple.setOSName(Str);
169223017Sdim
170212904Sdim  return Triple.getTriple();
171212904Sdim}
172212904Sdim
173234353Sdimvoid Generic_ELF::anchor() {}
174234353Sdim
175249423SdimTool *Darwin::getTool(Action::ActionClass AC) const {
176249423Sdim  switch (AC) {
177249423Sdim  case Action::LipoJobClass:
178249423Sdim    if (!Lipo)
179249423Sdim      Lipo.reset(new tools::darwin::Lipo(*this));
180249423Sdim    return Lipo.get();
181249423Sdim  case Action::DsymutilJobClass:
182249423Sdim    if (!Dsymutil)
183249423Sdim      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
184249423Sdim    return Dsymutil.get();
185249423Sdim  case Action::VerifyJobClass:
186249423Sdim    if (!VerifyDebug)
187249423Sdim      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
188249423Sdim    return VerifyDebug.get();
189249423Sdim  default:
190249423Sdim    return ToolChain::getTool(AC);
191239462Sdim  }
192249423Sdim}
193193326Sed
194249423SdimTool *Darwin::buildLinker() const {
195249423Sdim  return new tools::darwin::Link(*this);
196249423Sdim}
197208600Srdivacky
198249423SdimTool *Darwin::buildAssembler() const {
199249423Sdim  return new tools::darwin::Assemble(*this);
200193326Sed}
201193326Sed
202249423SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
203249423Sdim                         const ArgList &Args)
204249423Sdim  : Darwin(D, Triple, Args)
205198092Srdivacky{
206218893Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
207218893Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
208218893Sdim    getProgramPaths().push_back(getDriver().Dir);
209218893Sdim
210198092Srdivacky  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
211212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
212212904Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
213212904Sdim    getProgramPaths().push_back(getDriver().Dir);
214226633Sdim}
215226633Sdim
216224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args,
217224145Sdim                                 ArgStringList &CmdArgs) const {
218226633Sdim
219226633Sdim  CmdArgs.push_back("-force_load");
220224145Sdim  llvm::sys::Path P(getDriver().ClangExecutable);
221224145Sdim  P.eraseComponent(); // 'clang'
222224145Sdim  P.eraseComponent(); // 'bin'
223224145Sdim  P.appendComponent("lib");
224224145Sdim  P.appendComponent("arc");
225224145Sdim  P.appendComponent("libarclite_");
226224145Sdim  std::string s = P.str();
227224145Sdim  // Mash in the platform.
228234353Sdim  if (isTargetIOSSimulator())
229234353Sdim    s += "iphonesimulator";
230234353Sdim  else if (isTargetIPhoneOS())
231224145Sdim    s += "iphoneos";
232224145Sdim  else
233224145Sdim    s += "macosx";
234224145Sdim  s += ".a";
235224145Sdim
236224145Sdim  CmdArgs.push_back(Args.MakeArgString(s));
237224145Sdim}
238224145Sdim
239224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
240226633Sdim                                    ArgStringList &CmdArgs,
241249423Sdim                                    const char *DarwinStaticLib,
242249423Sdim                                    bool AlwaysLink) const {
243224145Sdim  llvm::sys::Path P(getDriver().ResourceDir);
244224145Sdim  P.appendComponent("lib");
245224145Sdim  P.appendComponent("darwin");
246224145Sdim  P.appendComponent(DarwinStaticLib);
247226633Sdim
248224145Sdim  // For now, allow missing resource libraries to support developers who may
249249423Sdim  // not have compiler-rt checked out or integrated into their build (unless
250249423Sdim  // we explicitly force linking with this library).
251224145Sdim  bool Exists;
252249423Sdim  if (AlwaysLink || (!llvm::sys::fs::exists(P.str(), Exists) && Exists))
253224145Sdim    CmdArgs.push_back(Args.MakeArgString(P.str()));
254224145Sdim}
255224145Sdim
256198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
257198092Srdivacky                                        ArgStringList &CmdArgs) const {
258234353Sdim  // Darwin only supports the compiler-rt based runtime libraries.
259234353Sdim  switch (GetRuntimeLibType(Args)) {
260234353Sdim  case ToolChain::RLT_CompilerRT:
261234353Sdim    break;
262234353Sdim  default:
263234353Sdim    getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
264243830Sdim      << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
265234353Sdim    return;
266234353Sdim  }
267234353Sdim
268202879Srdivacky  // Darwin doesn't support real static executables, don't link any runtime
269202879Srdivacky  // libraries with -static.
270243830Sdim  if (Args.hasArg(options::OPT_static) ||
271243830Sdim      Args.hasArg(options::OPT_fapple_kext) ||
272243830Sdim      Args.hasArg(options::OPT_mkernel))
273198092Srdivacky    return;
274198092Srdivacky
275198092Srdivacky  // Reject -static-libgcc for now, we can deal with this when and if someone
276198092Srdivacky  // cares. This is useful in situations where someone wants to statically link
277198092Srdivacky  // something like libstdc++, and needs its runtime support routines.
278198092Srdivacky  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
279226633Sdim    getDriver().Diag(diag::err_drv_unsupported_opt)
280198092Srdivacky      << A->getAsString(Args);
281198092Srdivacky    return;
282198092Srdivacky  }
283198092Srdivacky
284234353Sdim  // If we are building profile support, link that library in.
285234353Sdim  if (Args.hasArg(options::OPT_fprofile_arcs) ||
286234353Sdim      Args.hasArg(options::OPT_fprofile_generate) ||
287234353Sdim      Args.hasArg(options::OPT_fcreate_profile) ||
288234353Sdim      Args.hasArg(options::OPT_coverage)) {
289234353Sdim    // Select the appropriate runtime library for the target.
290234353Sdim    if (isTargetIPhoneOS()) {
291234353Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a");
292234353Sdim    } else {
293234353Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a");
294234353Sdim    }
295234353Sdim  }
296234353Sdim
297251662Sdim  SanitizerArgs Sanitize(*this, Args);
298243830Sdim
299249423Sdim  // Add Ubsan runtime library, if required.
300249423Sdim  if (Sanitize.needsUbsanRt()) {
301249423Sdim    if (isTargetIPhoneOS()) {
302249423Sdim      getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
303249423Sdim        << "-fsanitize=undefined";
304249423Sdim    } else {
305249423Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
306249423Sdim
307249423Sdim      // The Ubsan runtime library requires C++.
308249423Sdim      AddCXXStdlibLibArgs(Args, CmdArgs);
309249423Sdim    }
310249423Sdim  }
311249423Sdim
312234353Sdim  // Add ASAN runtime library, if required. Dynamic libraries and bundles
313234353Sdim  // should not be linked with the runtime library.
314243830Sdim  if (Sanitize.needsAsanRt()) {
315249423Sdim    if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
316234353Sdim      getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
317243830Sdim        << "-fsanitize=address";
318234353Sdim    } else {
319249423Sdim      if (Args.hasArg(options::OPT_dynamiclib) ||
320249423Sdim          Args.hasArg(options::OPT_bundle)) {
321249423Sdim        // Assume the binary will provide the ASan runtime.
322249423Sdim      } else {
323249423Sdim        AddLinkRuntimeLib(Args, CmdArgs,
324249423Sdim                          "libclang_rt.asan_osx_dynamic.dylib", true);
325249423Sdim        // The ASAN runtime library requires C++.
326249423Sdim        AddCXXStdlibLibArgs(Args, CmdArgs);
327249423Sdim      }
328234353Sdim    }
329234353Sdim  }
330234353Sdim
331202879Srdivacky  // Otherwise link libSystem, then the dynamic runtime library, and finally any
332202879Srdivacky  // target specific static runtime library.
333198092Srdivacky  CmdArgs.push_back("-lSystem");
334202879Srdivacky
335202879Srdivacky  // Select the dynamic runtime library and the target specific static library.
336203955Srdivacky  if (isTargetIPhoneOS()) {
337221345Sdim    // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
338221345Sdim    // it never went into the SDK.
339226633Sdim    // Linking against libgcc_s.1 isn't needed for iOS 5.0+
340226633Sdim    if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator())
341226633Sdim      CmdArgs.push_back("-lgcc_s.1");
342202879Srdivacky
343221345Sdim    // We currently always need a static runtime library for iOS.
344224145Sdim    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
345202879Srdivacky  } else {
346202879Srdivacky    // The dynamic runtime library was merged with libSystem for 10.6 and
347202879Srdivacky    // beyond; only 10.4 and 10.5 need an additional runtime library.
348203955Srdivacky    if (isMacosxVersionLT(10, 5))
349202879Srdivacky      CmdArgs.push_back("-lgcc_s.10.4");
350203955Srdivacky    else if (isMacosxVersionLT(10, 6))
351202879Srdivacky      CmdArgs.push_back("-lgcc_s.10.5");
352202879Srdivacky
353218893Sdim    // For OS X, we thought we would only need a static runtime library when
354221345Sdim    // targeting 10.4, to provide versions of the static functions which were
355218893Sdim    // omitted from 10.4.dylib.
356218893Sdim    //
357218893Sdim    // Unfortunately, that turned out to not be true, because Darwin system
358218893Sdim    // headers can still use eprintf on i386, and it is not exported from
359218893Sdim    // libSystem. Therefore, we still must provide a runtime library just for
360218893Sdim    // the tiny tiny handful of projects that *might* use that symbol.
361218893Sdim    if (isMacosxVersionLT(10, 5)) {
362224145Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
363218893Sdim    } else {
364218893Sdim      if (getTriple().getArch() == llvm::Triple::x86)
365224145Sdim        AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
366224145Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
367218893Sdim    }
368202879Srdivacky  }
369224145Sdim}
370202879Srdivacky
371212904Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
372201361Srdivacky  const OptTable &Opts = getDriver().getOpts();
373193326Sed
374243830Sdim  // Support allowing the SDKROOT environment variable used by xcrun and other
375243830Sdim  // Xcode tools to define the default sysroot, by making it the default for
376243830Sdim  // isysroot.
377249423Sdim  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
378249423Sdim    // Warn if the path does not exist.
379249423Sdim    bool Exists;
380249423Sdim    if (llvm::sys::fs::exists(A->getValue(), Exists) || !Exists)
381249423Sdim      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
382249423Sdim  } else {
383243830Sdim    if (char *env = ::getenv("SDKROOT")) {
384249423Sdim      // We only use this value as the default if it is an absolute path,
385249423Sdim      // exists, and it is not the root path.
386249423Sdim      if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&
387249423Sdim          StringRef(env) != "/") {
388243830Sdim        Args.append(Args.MakeSeparateArg(
389243830Sdim                      0, Opts.getOption(options::OPT_isysroot), env));
390243830Sdim      }
391243830Sdim    }
392243830Sdim  }
393243830Sdim
394203955Srdivacky  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
395221345Sdim  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
396221345Sdim  Arg *iOSSimVersion = Args.getLastArg(
397221345Sdim    options::OPT_mios_simulator_version_min_EQ);
398224145Sdim
399221345Sdim  if (OSXVersion && (iOSVersion || iOSSimVersion)) {
400226633Sdim    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
401193326Sed          << OSXVersion->getAsString(Args)
402221345Sdim          << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args);
403221345Sdim    iOSVersion = iOSSimVersion = 0;
404221345Sdim  } else if (iOSVersion && iOSSimVersion) {
405226633Sdim    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
406221345Sdim          << iOSVersion->getAsString(Args)
407221345Sdim          << iOSSimVersion->getAsString(Args);
408221345Sdim    iOSSimVersion = 0;
409221345Sdim  } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) {
410226633Sdim    // If no deployment target was specified on the command line, check for
411203955Srdivacky    // environment defines.
412226633Sdim    StringRef OSXTarget;
413226633Sdim    StringRef iOSTarget;
414226633Sdim    StringRef iOSSimTarget;
415226633Sdim    if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
416226633Sdim      OSXTarget = env;
417226633Sdim    if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
418226633Sdim      iOSTarget = env;
419226633Sdim    if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET"))
420226633Sdim      iOSSimTarget = env;
421203955Srdivacky
422226633Sdim    // If no '-miphoneos-version-min' specified on the command line and
423226633Sdim    // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default
424234982Sdim    // based on -isysroot.
425226633Sdim    if (iOSTarget.empty()) {
426226633Sdim      if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
427226633Sdim        StringRef first, second;
428243830Sdim        StringRef isysroot = A->getValue();
429226633Sdim        llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
430226633Sdim        if (second != "")
431226633Sdim          iOSTarget = second.substr(0,3);
432226633Sdim      }
433226633Sdim    }
434203955Srdivacky
435226633Sdim    // If no OSX or iOS target has been specified and we're compiling for armv7,
436226633Sdim    // go ahead as assume we're targeting iOS.
437239462Sdim    if (OSXTarget.empty() && iOSTarget.empty() &&
438243830Sdim        (getDarwinArchName(Args) == "armv7" ||
439243830Sdim         getDarwinArchName(Args) == "armv7s"))
440239462Sdim        iOSTarget = iOSVersionMin;
441226633Sdim
442221345Sdim    // Handle conflicting deployment targets
443193326Sed    //
444203955Srdivacky    // FIXME: Don't hardcode default here.
445221345Sdim
446221345Sdim    // Do not allow conflicts with the iOS simulator target.
447226633Sdim    if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) {
448226633Sdim      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
449221345Sdim        << "IOS_SIMULATOR_DEPLOYMENT_TARGET"
450226633Sdim        << (!OSXTarget.empty() ? "MACOSX_DEPLOYMENT_TARGET" :
451221345Sdim            "IPHONEOS_DEPLOYMENT_TARGET");
452221345Sdim    }
453221345Sdim
454221345Sdim    // Allow conflicts among OSX and iOS for historical reasons, but choose the
455221345Sdim    // default platform.
456226633Sdim    if (!OSXTarget.empty() && !iOSTarget.empty()) {
457203955Srdivacky      if (getTriple().getArch() == llvm::Triple::arm ||
458203955Srdivacky          getTriple().getArch() == llvm::Triple::thumb)
459226633Sdim        OSXTarget = "";
460203955Srdivacky      else
461226633Sdim        iOSTarget = "";
462203955Srdivacky    }
463193326Sed
464226633Sdim    if (!OSXTarget.empty()) {
465243830Sdim      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
466212904Sdim      OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
467212904Sdim      Args.append(OSXVersion);
468226633Sdim    } else if (!iOSTarget.empty()) {
469243830Sdim      const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
470221345Sdim      iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget);
471221345Sdim      Args.append(iOSVersion);
472226633Sdim    } else if (!iOSSimTarget.empty()) {
473243830Sdim      const Option O = Opts.getOption(
474221345Sdim        options::OPT_mios_simulator_version_min_EQ);
475221345Sdim      iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
476221345Sdim      Args.append(iOSSimVersion);
477198092Srdivacky    } else {
478210299Sed      // Otherwise, assume we are targeting OS X.
479243830Sdim      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
480212904Sdim      OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
481212904Sdim      Args.append(OSXVersion);
482198092Srdivacky    }
483193326Sed  }
484198092Srdivacky
485221345Sdim  // Reject invalid architecture combinations.
486221345Sdim  if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 &&
487221345Sdim                        getTriple().getArch() != llvm::Triple::x86_64)) {
488226633Sdim    getDriver().Diag(diag::err_drv_invalid_arch_for_deployment_target)
489221345Sdim      << getTriple().getArchName() << iOSSimVersion->getAsString(Args);
490221345Sdim  }
491221345Sdim
492203955Srdivacky  // Set the tool chain target information.
493203955Srdivacky  unsigned Major, Minor, Micro;
494203955Srdivacky  bool HadExtra;
495203955Srdivacky  if (OSXVersion) {
496221345Sdim    assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!");
497243830Sdim    if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor,
498203955Srdivacky                                   Micro, HadExtra) || HadExtra ||
499221345Sdim        Major != 10 || Minor >= 100 || Micro >= 100)
500226633Sdim      getDriver().Diag(diag::err_drv_invalid_version_number)
501203955Srdivacky        << OSXVersion->getAsString(Args);
502203955Srdivacky  } else {
503221345Sdim    const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
504221345Sdim    assert(Version && "Unknown target platform!");
505243830Sdim    if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor,
506203955Srdivacky                                   Micro, HadExtra) || HadExtra ||
507203955Srdivacky        Major >= 10 || Minor >= 100 || Micro >= 100)
508226633Sdim      getDriver().Diag(diag::err_drv_invalid_version_number)
509221345Sdim        << Version->getAsString(Args);
510203955Srdivacky  }
511221345Sdim
512221345Sdim  bool IsIOSSim = bool(iOSSimVersion);
513221345Sdim
514221345Sdim  // In GCC, the simulator historically was treated as being OS X in some
515221345Sdim  // contexts, like determining the link logic, despite generally being called
516221345Sdim  // with an iOS deployment target. For compatibility, we detect the
517221345Sdim  // simulator as iOS + x86, and treat it differently in a few contexts.
518221345Sdim  if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
519221345Sdim                     getTriple().getArch() == llvm::Triple::x86_64))
520221345Sdim    IsIOSSim = true;
521221345Sdim
522221345Sdim  setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim);
523212904Sdim}
524203955Srdivacky
525218893Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
526218893Sdim                                      ArgStringList &CmdArgs) const {
527218893Sdim  CXXStdlibType Type = GetCXXStdlibType(Args);
528218893Sdim
529218893Sdim  switch (Type) {
530218893Sdim  case ToolChain::CST_Libcxx:
531218893Sdim    CmdArgs.push_back("-lc++");
532218893Sdim    break;
533218893Sdim
534218893Sdim  case ToolChain::CST_Libstdcxx: {
535218893Sdim    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
536218893Sdim    // it was previously found in the gcc lib dir. However, for all the Darwin
537218893Sdim    // platforms we care about it was -lstdc++.6, so we search for that
538218893Sdim    // explicitly if we can't see an obvious -lstdc++ candidate.
539218893Sdim
540218893Sdim    // Check in the sysroot first.
541218893Sdim    bool Exists;
542218893Sdim    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
543243830Sdim      llvm::sys::Path P(A->getValue());
544218893Sdim      P.appendComponent("usr");
545218893Sdim      P.appendComponent("lib");
546218893Sdim      P.appendComponent("libstdc++.dylib");
547218893Sdim
548218893Sdim      if (llvm::sys::fs::exists(P.str(), Exists) || !Exists) {
549218893Sdim        P.eraseComponent();
550218893Sdim        P.appendComponent("libstdc++.6.dylib");
551218893Sdim        if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) {
552218893Sdim          CmdArgs.push_back(Args.MakeArgString(P.str()));
553218893Sdim          return;
554218893Sdim        }
555218893Sdim      }
556218893Sdim    }
557218893Sdim
558218893Sdim    // Otherwise, look in the root.
559234353Sdim    // FIXME: This should be removed someday when we don't have to care about
560234353Sdim    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
561218893Sdim    if ((llvm::sys::fs::exists("/usr/lib/libstdc++.dylib", Exists) || !Exists)&&
562218893Sdim      (!llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib", Exists) && Exists)){
563218893Sdim      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
564218893Sdim      return;
565218893Sdim    }
566218893Sdim
567218893Sdim    // Otherwise, let the linker search.
568218893Sdim    CmdArgs.push_back("-lstdc++");
569218893Sdim    break;
570218893Sdim  }
571218893Sdim  }
572218893Sdim}
573218893Sdim
574218893Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args,
575218893Sdim                                   ArgStringList &CmdArgs) const {
576218893Sdim
577218893Sdim  // For Darwin platforms, use the compiler-rt-based support library
578218893Sdim  // instead of the gcc-provided one (which is also incidentally
579218893Sdim  // only present in the gcc lib dir, which makes it hard to find).
580218893Sdim
581218893Sdim  llvm::sys::Path P(getDriver().ResourceDir);
582218893Sdim  P.appendComponent("lib");
583218893Sdim  P.appendComponent("darwin");
584223017Sdim
585243830Sdim  // Use the newer cc_kext for iOS ARM after 6.0.
586243830Sdim  if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
587243830Sdim      !isIPhoneOSVersionLT(6, 0)) {
588243830Sdim    P.appendComponent("libclang_rt.cc_kext.a");
589243830Sdim  } else {
590243830Sdim    P.appendComponent("libclang_rt.cc_kext_ios5.a");
591243830Sdim  }
592243830Sdim
593218893Sdim  // For now, allow missing resource libraries to support developers who may
594218893Sdim  // not have compiler-rt checked out or integrated into their build.
595218893Sdim  bool Exists;
596218893Sdim  if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
597218893Sdim    CmdArgs.push_back(Args.MakeArgString(P.str()));
598218893Sdim}
599218893Sdim
600212904SdimDerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
601212904Sdim                                      const char *BoundArch) const {
602212904Sdim  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
603212904Sdim  const OptTable &Opts = getDriver().getOpts();
604212904Sdim
605212904Sdim  // FIXME: We really want to get out of the tool chain level argument
606212904Sdim  // translation business, as it makes the driver functionality much
607212904Sdim  // more opaque. For now, we follow gcc closely solely for the
608212904Sdim  // purpose of easily achieving feature parity & testability. Once we
609212904Sdim  // have something that works, we should reevaluate each translation
610212904Sdim  // and try to push it down into tool specific logic.
611212904Sdim
612210299Sed  for (ArgList::const_iterator it = Args.begin(),
613210299Sed         ie = Args.end(); it != ie; ++it) {
614193326Sed    Arg *A = *it;
615193326Sed
616193326Sed    if (A->getOption().matches(options::OPT_Xarch__)) {
617224145Sdim      // Skip this argument unless the architecture matches either the toolchain
618224145Sdim      // triple arch, or the arch being bound.
619243830Sdim      llvm::Triple::ArchType XarchArch =
620243830Sdim        tools::darwin::getArchTypeForDarwinArchName(A->getValue(0));
621243830Sdim      if (!(XarchArch == getArch()  ||
622243830Sdim            (BoundArch && XarchArch ==
623243830Sdim             tools::darwin::getArchTypeForDarwinArchName(BoundArch))))
624193326Sed        continue;
625193326Sed
626218893Sdim      Arg *OriginalArg = A;
627243830Sdim      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
628210299Sed      unsigned Prev = Index;
629193326Sed      Arg *XarchArg = Opts.ParseOneArg(Args, Index);
630198092Srdivacky
631193326Sed      // If the argument parsing failed or more than one argument was
632193326Sed      // consumed, the -Xarch_ argument's parameter tried to consume
633193326Sed      // extra arguments. Emit an error and ignore.
634193326Sed      //
635193326Sed      // We also want to disallow any options which would alter the
636193326Sed      // driver behavior; that isn't going to work in our model. We
637193326Sed      // use isDriverOption() as an approximation, although things
638193326Sed      // like -O4 are going to slip through.
639221345Sdim      if (!XarchArg || Index > Prev + 1) {
640226633Sdim        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
641193326Sed          << A->getAsString(Args);
642193326Sed        continue;
643243830Sdim      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
644226633Sdim        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
645221345Sdim          << A->getAsString(Args);
646221345Sdim        continue;
647193326Sed      }
648193326Sed
649193326Sed      XarchArg->setBaseArg(A);
650193326Sed      A = XarchArg;
651210299Sed
652210299Sed      DAL->AddSynthesizedArg(A);
653218893Sdim
654218893Sdim      // Linker input arguments require custom handling. The problem is that we
655218893Sdim      // have already constructed the phase actions, so we can not treat them as
656218893Sdim      // "input arguments".
657243830Sdim      if (A->getOption().hasFlag(options::LinkerInput)) {
658218893Sdim        // Convert the argument into individual Zlinker_input_args.
659218893Sdim        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
660218893Sdim          DAL->AddSeparateArg(OriginalArg,
661218893Sdim                              Opts.getOption(options::OPT_Zlinker_input),
662243830Sdim                              A->getValue(i));
663223017Sdim
664218893Sdim        }
665218893Sdim        continue;
666218893Sdim      }
667198092Srdivacky    }
668193326Sed
669193326Sed    // Sob. These is strictly gcc compatible for the time being. Apple
670193326Sed    // gcc translates options twice, which means that self-expanding
671193326Sed    // options add duplicates.
672199512Srdivacky    switch ((options::ID) A->getOption().getID()) {
673193326Sed    default:
674193326Sed      DAL->append(A);
675193326Sed      break;
676193326Sed
677193326Sed    case options::OPT_mkernel:
678193326Sed    case options::OPT_fapple_kext:
679193326Sed      DAL->append(A);
680210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
681193326Sed      break;
682198092Srdivacky
683193326Sed    case options::OPT_dependency_file:
684210299Sed      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
685243830Sdim                          A->getValue());
686193326Sed      break;
687193326Sed
688193326Sed    case options::OPT_gfull:
689210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
690210299Sed      DAL->AddFlagArg(A,
691210299Sed               Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
692193326Sed      break;
693193326Sed
694193326Sed    case options::OPT_gused:
695210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
696210299Sed      DAL->AddFlagArg(A,
697210299Sed             Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
698193326Sed      break;
699193326Sed
700193326Sed    case options::OPT_shared:
701210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
702193326Sed      break;
703193326Sed
704193326Sed    case options::OPT_fconstant_cfstrings:
705210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
706193326Sed      break;
707193326Sed
708193326Sed    case options::OPT_fno_constant_cfstrings:
709210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
710193326Sed      break;
711193326Sed
712193326Sed    case options::OPT_Wnonportable_cfstrings:
713210299Sed      DAL->AddFlagArg(A,
714210299Sed                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
715193326Sed      break;
716193326Sed
717193326Sed    case options::OPT_Wno_nonportable_cfstrings:
718210299Sed      DAL->AddFlagArg(A,
719210299Sed                   Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
720193326Sed      break;
721193326Sed
722193326Sed    case options::OPT_fpascal_strings:
723210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
724193326Sed      break;
725193326Sed
726193326Sed    case options::OPT_fno_pascal_strings:
727210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
728193326Sed      break;
729193326Sed    }
730193326Sed  }
731193326Sed
732198092Srdivacky  if (getTriple().getArch() == llvm::Triple::x86 ||
733198092Srdivacky      getTriple().getArch() == llvm::Triple::x86_64)
734199512Srdivacky    if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
735210299Sed      DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2");
736198092Srdivacky
737198092Srdivacky  // Add the arch options based on the particular spelling of -arch, to match
738198092Srdivacky  // how the driver driver works.
739198092Srdivacky  if (BoundArch) {
740226633Sdim    StringRef Name = BoundArch;
741243830Sdim    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
742243830Sdim    const Option MArch = Opts.getOption(options::OPT_march_EQ);
743198092Srdivacky
744198092Srdivacky    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
745198092Srdivacky    // which defines the list of which architectures we accept.
746198092Srdivacky    if (Name == "ppc")
747198092Srdivacky      ;
748198092Srdivacky    else if (Name == "ppc601")
749210299Sed      DAL->AddJoinedArg(0, MCpu, "601");
750198092Srdivacky    else if (Name == "ppc603")
751210299Sed      DAL->AddJoinedArg(0, MCpu, "603");
752198092Srdivacky    else if (Name == "ppc604")
753210299Sed      DAL->AddJoinedArg(0, MCpu, "604");
754198092Srdivacky    else if (Name == "ppc604e")
755210299Sed      DAL->AddJoinedArg(0, MCpu, "604e");
756198092Srdivacky    else if (Name == "ppc750")
757210299Sed      DAL->AddJoinedArg(0, MCpu, "750");
758198092Srdivacky    else if (Name == "ppc7400")
759210299Sed      DAL->AddJoinedArg(0, MCpu, "7400");
760198092Srdivacky    else if (Name == "ppc7450")
761210299Sed      DAL->AddJoinedArg(0, MCpu, "7450");
762198092Srdivacky    else if (Name == "ppc970")
763210299Sed      DAL->AddJoinedArg(0, MCpu, "970");
764198092Srdivacky
765198092Srdivacky    else if (Name == "ppc64")
766210299Sed      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
767193326Sed
768198092Srdivacky    else if (Name == "i386")
769198092Srdivacky      ;
770198092Srdivacky    else if (Name == "i486")
771210299Sed      DAL->AddJoinedArg(0, MArch, "i486");
772198092Srdivacky    else if (Name == "i586")
773210299Sed      DAL->AddJoinedArg(0, MArch, "i586");
774198092Srdivacky    else if (Name == "i686")
775210299Sed      DAL->AddJoinedArg(0, MArch, "i686");
776198092Srdivacky    else if (Name == "pentium")
777210299Sed      DAL->AddJoinedArg(0, MArch, "pentium");
778198092Srdivacky    else if (Name == "pentium2")
779210299Sed      DAL->AddJoinedArg(0, MArch, "pentium2");
780198092Srdivacky    else if (Name == "pentpro")
781210299Sed      DAL->AddJoinedArg(0, MArch, "pentiumpro");
782198092Srdivacky    else if (Name == "pentIIm3")
783210299Sed      DAL->AddJoinedArg(0, MArch, "pentium2");
784193326Sed
785198092Srdivacky    else if (Name == "x86_64")
786210299Sed      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
787198092Srdivacky
788198092Srdivacky    else if (Name == "arm")
789210299Sed      DAL->AddJoinedArg(0, MArch, "armv4t");
790198092Srdivacky    else if (Name == "armv4t")
791210299Sed      DAL->AddJoinedArg(0, MArch, "armv4t");
792198092Srdivacky    else if (Name == "armv5")
793210299Sed      DAL->AddJoinedArg(0, MArch, "armv5tej");
794198092Srdivacky    else if (Name == "xscale")
795210299Sed      DAL->AddJoinedArg(0, MArch, "xscale");
796198092Srdivacky    else if (Name == "armv6")
797210299Sed      DAL->AddJoinedArg(0, MArch, "armv6k");
798249423Sdim    else if (Name == "armv6m")
799249423Sdim      DAL->AddJoinedArg(0, MArch, "armv6m");
800198092Srdivacky    else if (Name == "armv7")
801210299Sed      DAL->AddJoinedArg(0, MArch, "armv7a");
802249423Sdim    else if (Name == "armv7em")
803249423Sdim      DAL->AddJoinedArg(0, MArch, "armv7em");
804243830Sdim    else if (Name == "armv7f")
805243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7f");
806243830Sdim    else if (Name == "armv7k")
807243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7k");
808249423Sdim    else if (Name == "armv7m")
809249423Sdim      DAL->AddJoinedArg(0, MArch, "armv7m");
810243830Sdim    else if (Name == "armv7s")
811243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7s");
812198092Srdivacky
813198092Srdivacky    else
814200583Srdivacky      llvm_unreachable("invalid Darwin arch");
815198092Srdivacky  }
816198092Srdivacky
817212904Sdim  // Add an explicit version min argument for the deployment target. We do this
818212904Sdim  // after argument translation because -Xarch_ arguments may add a version min
819212904Sdim  // argument.
820239462Sdim  if (BoundArch)
821239462Sdim    AddDeploymentTarget(*DAL);
822212904Sdim
823243830Sdim  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
824243830Sdim  // FIXME: It would be far better to avoid inserting those -static arguments,
825243830Sdim  // but we can't check the deployment target in the translation code until
826243830Sdim  // it is set here.
827243830Sdim  if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) {
828243830Sdim    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
829243830Sdim      Arg *A = *it;
830243830Sdim      ++it;
831243830Sdim      if (A->getOption().getID() != options::OPT_mkernel &&
832243830Sdim          A->getOption().getID() != options::OPT_fapple_kext)
833243830Sdim        continue;
834243830Sdim      assert(it != ie && "unexpected argument translation");
835243830Sdim      A = *it;
836243830Sdim      assert(A->getOption().getID() == options::OPT_static &&
837243830Sdim             "missing expected -static argument");
838243830Sdim      it = DAL->getArgs().erase(it);
839243830Sdim    }
840243830Sdim  }
841243830Sdim
842226633Sdim  // Validate the C++ standard library choice.
843226633Sdim  CXXStdlibType Type = GetCXXStdlibType(*DAL);
844226633Sdim  if (Type == ToolChain::CST_Libcxx) {
845239462Sdim    // Check whether the target provides libc++.
846239462Sdim    StringRef where;
847239462Sdim
848239462Sdim    // Complain about targetting iOS < 5.0 in any way.
849243830Sdim    if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))
850243830Sdim      where = "iOS 5.0";
851239462Sdim
852239462Sdim    if (where != StringRef()) {
853226633Sdim      getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
854239462Sdim        << where;
855226633Sdim    }
856226633Sdim  }
857226633Sdim
858193326Sed  return DAL;
859198092Srdivacky}
860193326Sed
861198092Srdivackybool Darwin::IsUnwindTablesDefault() const {
862243830Sdim  return getArch() == llvm::Triple::x86_64;
863193326Sed}
864193326Sed
865201361Srdivackybool Darwin::UseDwarfDebugFlags() const {
866201361Srdivacky  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
867201361Srdivacky    return S[0] != '\0';
868201361Srdivacky  return false;
869201361Srdivacky}
870201361Srdivacky
871203955Srdivackybool Darwin::UseSjLjExceptions() const {
872203955Srdivacky  // Darwin uses SjLj exceptions on ARM.
873203955Srdivacky  return (getTriple().getArch() == llvm::Triple::arm ||
874203955Srdivacky          getTriple().getArch() == llvm::Triple::thumb);
875203955Srdivacky}
876203955Srdivacky
877243830Sdimbool Darwin::isPICDefault() const {
878243830Sdim  return true;
879193326Sed}
880193326Sed
881251662Sdimbool Darwin::isPIEDefault() const {
882251662Sdim  return false;
883251662Sdim}
884251662Sdim
885243830Sdimbool Darwin::isPICDefaultForced() const {
886243830Sdim  return getArch() == llvm::Triple::x86_64;
887193326Sed}
888193326Sed
889221345Sdimbool Darwin::SupportsProfiling() const {
890221345Sdim  // Profiling instrumentation is only supported on x86.
891243830Sdim  return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
892221345Sdim}
893221345Sdim
894207619Srdivackybool Darwin::SupportsObjCGC() const {
895207619Srdivacky  // Garbage collection is supported everywhere except on iPhone OS.
896207619Srdivacky  return !isTargetIPhoneOS();
897207619Srdivacky}
898207619Srdivacky
899243830Sdimvoid Darwin::CheckObjCARC() const {
900243830Sdim  if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
901243830Sdim    return;
902243830Sdim  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
903234353Sdim}
904234353Sdim
905212904Sdimstd::string
906226633SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args,
907226633Sdim                                                types::ID InputType) const {
908226633Sdim  return ComputeLLVMTriple(Args, InputType);
909212904Sdim}
910212904Sdim
911193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform
912193326Sed/// all subcommands; this relies on gcc translating the majority of
913193326Sed/// command line options.
914193326Sed
915234353Sdim/// \brief Parse a GCCVersion object out of a string of text.
916234353Sdim///
917234353Sdim/// This is the primary means of forming GCCVersion objects.
918234353Sdim/*static*/
919234353SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
920234353Sdim  const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "" };
921234353Sdim  std::pair<StringRef, StringRef> First = VersionText.split('.');
922234353Sdim  std::pair<StringRef, StringRef> Second = First.second.split('.');
923234353Sdim
924234353Sdim  GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "" };
925234353Sdim  if (First.first.getAsInteger(10, GoodVersion.Major) ||
926234353Sdim      GoodVersion.Major < 0)
927234353Sdim    return BadVersion;
928234353Sdim  if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
929234353Sdim      GoodVersion.Minor < 0)
930234353Sdim    return BadVersion;
931234353Sdim
932234353Sdim  // First look for a number prefix and parse that if present. Otherwise just
933234353Sdim  // stash the entire patch string in the suffix, and leave the number
934234353Sdim  // unspecified. This covers versions strings such as:
935234353Sdim  //   4.4
936234353Sdim  //   4.4.0
937234353Sdim  //   4.4.x
938234353Sdim  //   4.4.2-rc4
939234353Sdim  //   4.4.x-patched
940234353Sdim  // And retains any patch number it finds.
941234353Sdim  StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
942234353Sdim  if (!PatchText.empty()) {
943249423Sdim    if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
944234353Sdim      // Try to parse the number and any suffix.
945234353Sdim      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
946234353Sdim          GoodVersion.Patch < 0)
947234353Sdim        return BadVersion;
948234353Sdim      GoodVersion.PatchSuffix = PatchText.substr(EndNumber).str();
949234353Sdim    }
950234353Sdim  }
951234353Sdim
952234353Sdim  return GoodVersion;
953234353Sdim}
954234353Sdim
955234353Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
956234353Sdimbool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const {
957249423Sdim  if (Major != RHS.Major)
958249423Sdim    return Major < RHS.Major;
959249423Sdim  if (Minor != RHS.Minor)
960249423Sdim    return Minor < RHS.Minor;
961249423Sdim  if (Patch != RHS.Patch) {
962249423Sdim    // Note that versions without a specified patch sort higher than those with
963249423Sdim    // a patch.
964249423Sdim    if (RHS.Patch == -1)
965249423Sdim      return true;
966249423Sdim    if (Patch == -1)
967249423Sdim      return false;
968234353Sdim
969249423Sdim    // Otherwise just sort on the patch itself.
970249423Sdim    return Patch < RHS.Patch;
971249423Sdim  }
972249423Sdim  if (PatchSuffix != RHS.PatchSuffix) {
973249423Sdim    // Sort empty suffixes higher.
974249423Sdim    if (RHS.PatchSuffix.empty())
975249423Sdim      return true;
976249423Sdim    if (PatchSuffix.empty())
977249423Sdim      return false;
978234353Sdim
979249423Sdim    // Provide a lexicographic sort to make this a total ordering.
980249423Sdim    return PatchSuffix < RHS.PatchSuffix;
981249423Sdim  }
982249423Sdim
983249423Sdim  // The versions are equal.
984234353Sdim  return false;
985234353Sdim}
986234353Sdim
987234353Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) {
988234353Sdim  const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
989234353Sdim  if (A)
990243830Sdim    return A->getValue();
991234353Sdim  return GCC_INSTALL_PREFIX;
992234353Sdim}
993234353Sdim
994234353Sdim/// \brief Construct a GCCInstallationDetector from the driver.
995234353Sdim///
996234353Sdim/// This performs all of the autodetection and sets up the various paths.
997234982Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable.
998234353Sdim///
999234353Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1000234353Sdim/// should instead pull the target out of the driver. This is currently
1001234353Sdim/// necessary because the driver doesn't store the final version of the target
1002234353Sdim/// triple.
1003234353SdimGeneric_GCC::GCCInstallationDetector::GCCInstallationDetector(
1004234353Sdim    const Driver &D,
1005234353Sdim    const llvm::Triple &TargetTriple,
1006234353Sdim    const ArgList &Args)
1007234353Sdim    : IsValid(false) {
1008234353Sdim  llvm::Triple MultiarchTriple
1009234353Sdim    = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
1010234353Sdim                                 : TargetTriple.get32BitArchVariant();
1011234353Sdim  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
1012234353Sdim  // The library directories which may contain GCC installations.
1013234353Sdim  SmallVector<StringRef, 4> CandidateLibDirs, CandidateMultiarchLibDirs;
1014234353Sdim  // The compatible GCC triples for this particular architecture.
1015234353Sdim  SmallVector<StringRef, 10> CandidateTripleAliases;
1016234353Sdim  SmallVector<StringRef, 10> CandidateMultiarchTripleAliases;
1017234353Sdim  CollectLibDirsAndTriples(TargetTriple, MultiarchTriple, CandidateLibDirs,
1018234353Sdim                           CandidateTripleAliases,
1019234353Sdim                           CandidateMultiarchLibDirs,
1020234353Sdim                           CandidateMultiarchTripleAliases);
1021234353Sdim
1022234353Sdim  // Compute the set of prefixes for our search.
1023234353Sdim  SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1024234353Sdim                                       D.PrefixDirs.end());
1025234353Sdim
1026234353Sdim  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1027234353Sdim  if (GCCToolchainDir != "") {
1028234353Sdim    if (GCCToolchainDir.back() == '/')
1029234353Sdim      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
1030234353Sdim
1031234353Sdim    Prefixes.push_back(GCCToolchainDir);
1032234353Sdim  } else {
1033234353Sdim    Prefixes.push_back(D.SysRoot);
1034234353Sdim    Prefixes.push_back(D.SysRoot + "/usr");
1035234353Sdim    Prefixes.push_back(D.InstalledDir + "/..");
1036234353Sdim  }
1037234353Sdim
1038234353Sdim  // Loop over the various components which exist and select the best GCC
1039234353Sdim  // installation available. GCC installs are ranked by version number.
1040234353Sdim  Version = GCCVersion::Parse("0.0.0");
1041234353Sdim  for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) {
1042234353Sdim    if (!llvm::sys::fs::exists(Prefixes[i]))
1043234353Sdim      continue;
1044234353Sdim    for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) {
1045234353Sdim      const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str();
1046234353Sdim      if (!llvm::sys::fs::exists(LibDir))
1047234353Sdim        continue;
1048234353Sdim      for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
1049243830Sdim        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
1050243830Sdim                               CandidateTripleAliases[k]);
1051234353Sdim    }
1052234353Sdim    for (unsigned j = 0, je = CandidateMultiarchLibDirs.size(); j < je; ++j) {
1053234353Sdim      const std::string LibDir
1054234353Sdim        = Prefixes[i] + CandidateMultiarchLibDirs[j].str();
1055234353Sdim      if (!llvm::sys::fs::exists(LibDir))
1056234353Sdim        continue;
1057234353Sdim      for (unsigned k = 0, ke = CandidateMultiarchTripleAliases.size(); k < ke;
1058234353Sdim           ++k)
1059243830Sdim        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
1060234353Sdim                               CandidateMultiarchTripleAliases[k],
1061234353Sdim                               /*NeedsMultiarchSuffix=*/true);
1062234353Sdim    }
1063234353Sdim  }
1064234353Sdim}
1065234353Sdim
1066234353Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
1067234353Sdim    const llvm::Triple &TargetTriple,
1068234353Sdim    const llvm::Triple &MultiarchTriple,
1069234353Sdim    SmallVectorImpl<StringRef> &LibDirs,
1070234353Sdim    SmallVectorImpl<StringRef> &TripleAliases,
1071234353Sdim    SmallVectorImpl<StringRef> &MultiarchLibDirs,
1072234353Sdim    SmallVectorImpl<StringRef> &MultiarchTripleAliases) {
1073234353Sdim  // Declare a bunch of static data sets that we'll select between below. These
1074234353Sdim  // are specifically designed to always refer to string literals to avoid any
1075234353Sdim  // lifetime or initialization issues.
1076249423Sdim  static const char *const AArch64LibDirs[] = { "/lib" };
1077249423Sdim  static const char *const AArch64Triples[] = {
1078249423Sdim    "aarch64-none-linux-gnu",
1079249423Sdim    "aarch64-linux-gnu"
1080249423Sdim  };
1081249423Sdim
1082234353Sdim  static const char *const ARMLibDirs[] = { "/lib" };
1083234353Sdim  static const char *const ARMTriples[] = {
1084234353Sdim    "arm-linux-gnueabi",
1085234353Sdim    "arm-linux-androideabi"
1086234353Sdim  };
1087239462Sdim  static const char *const ARMHFTriples[] = {
1088239462Sdim    "arm-linux-gnueabihf",
1089251662Sdim    "armv7hl-redhat-linux-gnueabi"
1090239462Sdim  };
1091234353Sdim
1092234353Sdim  static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
1093234353Sdim  static const char *const X86_64Triples[] = {
1094234353Sdim    "x86_64-linux-gnu",
1095234353Sdim    "x86_64-unknown-linux-gnu",
1096234353Sdim    "x86_64-pc-linux-gnu",
1097234353Sdim    "x86_64-redhat-linux6E",
1098234353Sdim    "x86_64-redhat-linux",
1099234353Sdim    "x86_64-suse-linux",
1100234353Sdim    "x86_64-manbo-linux-gnu",
1101234353Sdim    "x86_64-linux-gnu",
1102234353Sdim    "x86_64-slackware-linux"
1103234353Sdim  };
1104234353Sdim  static const char *const X86LibDirs[] = { "/lib32", "/lib" };
1105234353Sdim  static const char *const X86Triples[] = {
1106234353Sdim    "i686-linux-gnu",
1107234353Sdim    "i686-pc-linux-gnu",
1108234353Sdim    "i486-linux-gnu",
1109234353Sdim    "i386-linux-gnu",
1110249423Sdim    "i386-redhat-linux6E",
1111234353Sdim    "i686-redhat-linux",
1112234353Sdim    "i586-redhat-linux",
1113234353Sdim    "i386-redhat-linux",
1114234353Sdim    "i586-suse-linux",
1115239462Sdim    "i486-slackware-linux",
1116239462Sdim    "i686-montavista-linux"
1117234353Sdim  };
1118234353Sdim
1119234353Sdim  static const char *const MIPSLibDirs[] = { "/lib" };
1120234353Sdim  static const char *const MIPSTriples[] = { "mips-linux-gnu" };
1121234353Sdim  static const char *const MIPSELLibDirs[] = { "/lib" };
1122243830Sdim  static const char *const MIPSELTriples[] = {
1123243830Sdim    "mipsel-linux-gnu",
1124251662Sdim    "mipsel-linux-android",
1125251662Sdim    "mips-linux-gnu"
1126243830Sdim  };
1127234353Sdim
1128239462Sdim  static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
1129239462Sdim  static const char *const MIPS64Triples[] = { "mips64-linux-gnu" };
1130239462Sdim  static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
1131239462Sdim  static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu" };
1132239462Sdim
1133234353Sdim  static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
1134234353Sdim  static const char *const PPCTriples[] = {
1135234353Sdim    "powerpc-linux-gnu",
1136234353Sdim    "powerpc-unknown-linux-gnu",
1137249423Sdim    "powerpc-linux-gnuspe",
1138239462Sdim    "powerpc-suse-linux",
1139239462Sdim    "powerpc-montavista-linuxspe"
1140234353Sdim  };
1141234353Sdim  static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
1142234353Sdim  static const char *const PPC64Triples[] = {
1143234353Sdim    "powerpc64-linux-gnu",
1144234353Sdim    "powerpc64-unknown-linux-gnu",
1145234353Sdim    "powerpc64-suse-linux",
1146234353Sdim    "ppc64-redhat-linux"
1147234353Sdim  };
1148234353Sdim
1149251662Sdim  static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
1150251662Sdim  static const char *const SystemZTriples[] = {
1151251662Sdim    "s390x-linux-gnu",
1152251662Sdim    "s390x-unknown-linux-gnu",
1153251662Sdim    "s390x-ibm-linux-gnu",
1154251662Sdim    "s390x-suse-linux",
1155251662Sdim    "s390x-redhat-linux"
1156251662Sdim  };
1157251662Sdim
1158234353Sdim  switch (TargetTriple.getArch()) {
1159249423Sdim  case llvm::Triple::aarch64:
1160249423Sdim    LibDirs.append(AArch64LibDirs, AArch64LibDirs
1161249423Sdim                   + llvm::array_lengthof(AArch64LibDirs));
1162249423Sdim    TripleAliases.append(
1163249423Sdim      AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
1164249423Sdim    MultiarchLibDirs.append(
1165249423Sdim      AArch64LibDirs, AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
1166249423Sdim    MultiarchTripleAliases.append(
1167249423Sdim      AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
1168249423Sdim    break;
1169234353Sdim  case llvm::Triple::arm:
1170234353Sdim  case llvm::Triple::thumb:
1171234353Sdim    LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
1172239462Sdim    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1173239462Sdim      TripleAliases.append(
1174239462Sdim        ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
1175239462Sdim    } else {
1176239462Sdim      TripleAliases.append(
1177239462Sdim        ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
1178239462Sdim    }
1179234353Sdim    break;
1180234353Sdim  case llvm::Triple::x86_64:
1181234353Sdim    LibDirs.append(
1182234353Sdim      X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
1183234353Sdim    TripleAliases.append(
1184234353Sdim      X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
1185234353Sdim    MultiarchLibDirs.append(
1186234353Sdim      X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
1187234353Sdim    MultiarchTripleAliases.append(
1188234353Sdim      X86Triples, X86Triples + llvm::array_lengthof(X86Triples));
1189234353Sdim    break;
1190234353Sdim  case llvm::Triple::x86:
1191234353Sdim    LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
1192234353Sdim    TripleAliases.append(
1193234353Sdim      X86Triples, X86Triples + llvm::array_lengthof(X86Triples));
1194234353Sdim    MultiarchLibDirs.append(
1195234353Sdim      X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
1196234353Sdim    MultiarchTripleAliases.append(
1197234353Sdim      X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
1198234353Sdim    break;
1199234353Sdim  case llvm::Triple::mips:
1200234353Sdim    LibDirs.append(
1201234353Sdim      MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
1202234353Sdim    TripleAliases.append(
1203234353Sdim      MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
1204239462Sdim    MultiarchLibDirs.append(
1205239462Sdim      MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
1206239462Sdim    MultiarchTripleAliases.append(
1207239462Sdim      MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
1208234353Sdim    break;
1209234353Sdim  case llvm::Triple::mipsel:
1210234353Sdim    LibDirs.append(
1211234353Sdim      MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
1212234353Sdim    TripleAliases.append(
1213234353Sdim      MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
1214239462Sdim    MultiarchLibDirs.append(
1215239462Sdim      MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
1216239462Sdim    MultiarchTripleAliases.append(
1217239462Sdim      MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
1218234353Sdim    break;
1219239462Sdim  case llvm::Triple::mips64:
1220239462Sdim    LibDirs.append(
1221239462Sdim      MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
1222239462Sdim    TripleAliases.append(
1223239462Sdim      MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
1224239462Sdim    MultiarchLibDirs.append(
1225239462Sdim      MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
1226239462Sdim    MultiarchTripleAliases.append(
1227239462Sdim      MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
1228239462Sdim    break;
1229239462Sdim  case llvm::Triple::mips64el:
1230239462Sdim    LibDirs.append(
1231239462Sdim      MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
1232239462Sdim    TripleAliases.append(
1233239462Sdim      MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
1234239462Sdim    MultiarchLibDirs.append(
1235239462Sdim      MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
1236239462Sdim    MultiarchTripleAliases.append(
1237239462Sdim      MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
1238239462Sdim    break;
1239234353Sdim  case llvm::Triple::ppc:
1240234353Sdim    LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
1241234353Sdim    TripleAliases.append(
1242234353Sdim      PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
1243234353Sdim    MultiarchLibDirs.append(
1244234353Sdim      PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
1245234353Sdim    MultiarchTripleAliases.append(
1246234353Sdim      PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
1247234353Sdim    break;
1248234353Sdim  case llvm::Triple::ppc64:
1249234353Sdim    LibDirs.append(
1250234353Sdim      PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
1251234353Sdim    TripleAliases.append(
1252234353Sdim      PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
1253234353Sdim    MultiarchLibDirs.append(
1254234353Sdim      PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
1255234353Sdim    MultiarchTripleAliases.append(
1256234353Sdim      PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
1257234353Sdim    break;
1258251662Sdim  case llvm::Triple::systemz:
1259251662Sdim    LibDirs.append(
1260251662Sdim      SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
1261251662Sdim    TripleAliases.append(
1262251662Sdim      SystemZTriples, SystemZTriples + llvm::array_lengthof(SystemZTriples));
1263251662Sdim    break;
1264234353Sdim
1265234353Sdim  default:
1266234353Sdim    // By default, just rely on the standard lib directories and the original
1267234353Sdim    // triple.
1268234353Sdim    break;
1269234353Sdim  }
1270234353Sdim
1271234353Sdim  // Always append the drivers target triple to the end, in case it doesn't
1272234353Sdim  // match any of our aliases.
1273234353Sdim  TripleAliases.push_back(TargetTriple.str());
1274234353Sdim
1275234353Sdim  // Also include the multiarch variant if it's different.
1276234353Sdim  if (TargetTriple.str() != MultiarchTriple.str())
1277234353Sdim    MultiarchTripleAliases.push_back(MultiarchTriple.str());
1278234353Sdim}
1279234353Sdim
1280251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) {
1281251662Sdim  Arg *A = Args.getLastArg(options::OPT_msoft_float,
1282251662Sdim                           options::OPT_mhard_float,
1283251662Sdim                           options::OPT_mfloat_abi_EQ);
1284251662Sdim  if (!A) return false;
1285251662Sdim
1286251662Sdim  return A->getOption().matches(options::OPT_msoft_float) ||
1287251662Sdim         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
1288251662Sdim          A->getValue() == StringRef("soft"));
1289251662Sdim}
1290251662Sdim
1291251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) {
1292251662Sdim  return Arch == llvm::Triple::mips ||
1293251662Sdim         Arch == llvm::Triple::mipsel ||
1294251662Sdim         Arch == llvm::Triple::mips64 ||
1295251662Sdim         Arch == llvm::Triple::mips64el;
1296251662Sdim}
1297251662Sdim
1298251662Sdimstatic bool isMips16(const ArgList &Args) {
1299251662Sdim  Arg *A = Args.getLastArg(options::OPT_mips16,
1300251662Sdim                           options::OPT_mno_mips16);
1301251662Sdim  return A && A->getOption().matches(options::OPT_mips16);
1302251662Sdim}
1303251662Sdim
1304251662Sdimstatic bool isMicroMips(const ArgList &Args) {
1305251662Sdim  Arg *A = Args.getLastArg(options::OPT_mmicromips,
1306251662Sdim                           options::OPT_mno_micromips);
1307251662Sdim  return A && A->getOption().matches(options::OPT_mmicromips);
1308251662Sdim}
1309251662Sdim
1310243830Sdim// FIXME: There is the same routine in the Tools.cpp.
1311243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) {
1312243830Sdim  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
1313243830Sdim  return A && (A->getValue() == StringRef("n32"));
1314243830Sdim}
1315243830Sdim
1316251662Sdimstatic void appendMipsTargetSuffix(std::string &Path,
1317251662Sdim                                   llvm::Triple::ArchType TargetArch,
1318251662Sdim                                   const ArgList &Args) {
1319251662Sdim  if (isMips16(Args))
1320251662Sdim    Path += "/mips16";
1321251662Sdim  else if (isMicroMips(Args))
1322251662Sdim    Path += "/micromips";
1323243830Sdim
1324251662Sdim  if (isSoftFloatABI(Args))
1325251662Sdim    Path += "/soft-float";
1326251662Sdim
1327251662Sdim  if (TargetArch == llvm::Triple::mipsel ||
1328251662Sdim      TargetArch == llvm::Triple::mips64el)
1329251662Sdim    Path += "/el";
1330251662Sdim}
1331251662Sdim
1332251662Sdimstatic StringRef getMipsTargetABISuffix(llvm::Triple::ArchType TargetArch,
1333251662Sdim                                        const ArgList &Args) {
1334243830Sdim  if (TargetArch == llvm::Triple::mips64 ||
1335251662Sdim      TargetArch == llvm::Triple::mips64el)
1336251662Sdim    return hasMipsN32ABIArg(Args) ? "/n32" : "/64";
1337243830Sdim
1338243830Sdim  return "/32";
1339243830Sdim}
1340243830Sdim
1341251662Sdimstatic bool findTargetMultiarchSuffix(std::string &Suffix,
1342251662Sdim                                      StringRef Path,
1343251662Sdim                                      llvm::Triple::ArchType TargetArch,
1344251662Sdim                                      const ArgList &Args) {
1345251662Sdim  if (isMipsArch(TargetArch)) {
1346251662Sdim    StringRef ABISuffix = getMipsTargetABISuffix(TargetArch, Args);
1347251662Sdim
1348251662Sdim    // First build and check a complex path to crtbegin.o
1349251662Sdim    // depends on command line options (-mips16, -msoft-float, ...)
1350251662Sdim    // like mips-linux-gnu/4.7/mips16/soft-float/el/crtbegin.o
1351251662Sdim    appendMipsTargetSuffix(Suffix, TargetArch, Args);
1352251662Sdim
1353251662Sdim    if (TargetArch == llvm::Triple::mips64 ||
1354251662Sdim        TargetArch == llvm::Triple::mips64el)
1355251662Sdim      Suffix += ABISuffix;
1356251662Sdim
1357251662Sdim    if (llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o"))
1358251662Sdim      return true;
1359251662Sdim
1360251662Sdim    // Then fall back and probe a simple case like
1361251662Sdim    // mips-linux-gnu/4.7/32/crtbegin.o
1362251662Sdim    Suffix = ABISuffix;
1363251662Sdim    return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o");
1364251662Sdim  }
1365251662Sdim
1366251662Sdim  if (TargetArch == llvm::Triple::x86_64 ||
1367251662Sdim      TargetArch == llvm::Triple::ppc64 ||
1368251662Sdim      TargetArch == llvm::Triple::systemz)
1369251662Sdim    Suffix = "/64";
1370251662Sdim  else
1371251662Sdim    Suffix = "/32";
1372251662Sdim
1373251662Sdim  return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o");
1374251662Sdim}
1375251662Sdim
1376234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
1377243830Sdim    llvm::Triple::ArchType TargetArch, const ArgList &Args,
1378243830Sdim    const std::string &LibDir,
1379234353Sdim    StringRef CandidateTriple, bool NeedsMultiarchSuffix) {
1380234353Sdim  // There are various different suffixes involving the triple we
1381234353Sdim  // check for. We also record what is necessary to walk from each back
1382234353Sdim  // up to the lib directory.
1383234353Sdim  const std::string LibSuffixes[] = {
1384234353Sdim    "/gcc/" + CandidateTriple.str(),
1385234353Sdim    "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
1386234353Sdim
1387243830Sdim    // The Freescale PPC SDK has the gcc libraries in
1388243830Sdim    // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
1389243830Sdim    "/" + CandidateTriple.str(),
1390243830Sdim
1391234353Sdim    // Ubuntu has a strange mis-matched pair of triples that this happens to
1392234353Sdim    // match.
1393234353Sdim    // FIXME: It may be worthwhile to generalize this and look for a second
1394234353Sdim    // triple.
1395234353Sdim    "/i386-linux-gnu/gcc/" + CandidateTriple.str()
1396234353Sdim  };
1397234353Sdim  const std::string InstallSuffixes[] = {
1398234353Sdim    "/../../..",
1399234353Sdim    "/../../../..",
1400243830Sdim    "/../..",
1401234353Sdim    "/../../../.."
1402234353Sdim  };
1403234353Sdim  // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
1404234353Sdim  const unsigned NumLibSuffixes = (llvm::array_lengthof(LibSuffixes) -
1405234353Sdim                                   (TargetArch != llvm::Triple::x86));
1406234353Sdim  for (unsigned i = 0; i < NumLibSuffixes; ++i) {
1407234353Sdim    StringRef LibSuffix = LibSuffixes[i];
1408234353Sdim    llvm::error_code EC;
1409234353Sdim    for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
1410234353Sdim         !EC && LI != LE; LI = LI.increment(EC)) {
1411234353Sdim      StringRef VersionText = llvm::sys::path::filename(LI->path());
1412234353Sdim      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
1413234353Sdim      static const GCCVersion MinVersion = { "4.1.1", 4, 1, 1, "" };
1414234353Sdim      if (CandidateVersion < MinVersion)
1415234353Sdim        continue;
1416234353Sdim      if (CandidateVersion <= Version)
1417234353Sdim        continue;
1418234353Sdim
1419234353Sdim      // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
1420234353Sdim      // in what would normally be GCCInstallPath and put the 64-bit
1421234353Sdim      // libs in a subdirectory named 64. The simple logic we follow is that
1422234353Sdim      // *if* there is a subdirectory of the right name with crtbegin.o in it,
1423234353Sdim      // we use that. If not, and if not a multiarch triple, we look for
1424234353Sdim      // crtbegin.o without the subdirectory.
1425251662Sdim
1426251662Sdim      std::string MultiarchSuffix;
1427251662Sdim      if (findTargetMultiarchSuffix(MultiarchSuffix,
1428251662Sdim                                    LI->path(), TargetArch, Args)) {
1429251662Sdim        GCCMultiarchSuffix = MultiarchSuffix;
1430234353Sdim      } else {
1431234353Sdim        if (NeedsMultiarchSuffix ||
1432234353Sdim            !llvm::sys::fs::exists(LI->path() + "/crtbegin.o"))
1433234353Sdim          continue;
1434234353Sdim        GCCMultiarchSuffix.clear();
1435234353Sdim      }
1436234353Sdim
1437234353Sdim      Version = CandidateVersion;
1438234353Sdim      GCCTriple.setTriple(CandidateTriple);
1439234353Sdim      // FIXME: We hack together the directory name here instead of
1440234353Sdim      // using LI to ensure stable path separators across Windows and
1441234353Sdim      // Linux.
1442234353Sdim      GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
1443234353Sdim      GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
1444234353Sdim      IsValid = true;
1445234353Sdim    }
1446234353Sdim  }
1447234353Sdim}
1448234353Sdim
1449234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
1450234353Sdim                         const ArgList &Args)
1451249423Sdim  : ToolChain(D, Triple, Args), GCCInstallation(getDriver(), Triple, Args) {
1452212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
1453221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
1454212904Sdim    getProgramPaths().push_back(getDriver().Dir);
1455193326Sed}
1456193326Sed
1457193326SedGeneric_GCC::~Generic_GCC() {
1458193326Sed}
1459193326Sed
1460249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const {
1461249423Sdim  switch (AC) {
1462249423Sdim  case Action::PreprocessJobClass:
1463249423Sdim    if (!Preprocess)
1464249423Sdim      Preprocess.reset(new tools::gcc::Preprocess(*this));
1465249423Sdim    return Preprocess.get();
1466249423Sdim  case Action::PrecompileJobClass:
1467249423Sdim    if (!Precompile)
1468249423Sdim      Precompile.reset(new tools::gcc::Precompile(*this));
1469249423Sdim    return Precompile.get();
1470249423Sdim  case Action::CompileJobClass:
1471249423Sdim    if (!Compile)
1472249423Sdim      Compile.reset(new tools::gcc::Compile(*this));
1473249423Sdim    return Compile.get();
1474249423Sdim  default:
1475249423Sdim    return ToolChain::getTool(AC);
1476193326Sed  }
1477249423Sdim}
1478193326Sed
1479249423SdimTool *Generic_GCC::buildAssembler() const {
1480249423Sdim  return new tools::gcc::Assemble(*this);
1481193326Sed}
1482193326Sed
1483249423SdimTool *Generic_GCC::buildLinker() const {
1484249423Sdim  return new tools::gcc::Link(*this);
1485249423Sdim}
1486249423Sdim
1487193326Sedbool Generic_GCC::IsUnwindTablesDefault() const {
1488243830Sdim  return getArch() == llvm::Triple::x86_64;
1489193326Sed}
1490193326Sed
1491243830Sdimbool Generic_GCC::isPICDefault() const {
1492243830Sdim  return false;
1493193326Sed}
1494193326Sed
1495251662Sdimbool Generic_GCC::isPIEDefault() const {
1496251662Sdim  return false;
1497251662Sdim}
1498251662Sdim
1499243830Sdimbool Generic_GCC::isPICDefaultForced() const {
1500243830Sdim  return false;
1501193326Sed}
1502243830Sdim
1503234353Sdim/// Hexagon Toolchain
1504193326Sed
1505249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) {
1506249423Sdim
1507249423Sdim  // Locate the rest of the toolchain ...
1508249423Sdim  if (strlen(GCC_INSTALL_PREFIX))
1509249423Sdim    return std::string(GCC_INSTALL_PREFIX);
1510249423Sdim
1511249423Sdim  std::string InstallRelDir = InstalledDir + "/../../gnu";
1512249423Sdim  if (llvm::sys::fs::exists(InstallRelDir))
1513249423Sdim    return InstallRelDir;
1514249423Sdim
1515249423Sdim  std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
1516249423Sdim  if (llvm::sys::fs::exists(PrefixRelDir))
1517249423Sdim    return PrefixRelDir;
1518249423Sdim
1519249423Sdim  return InstallRelDir;
1520234353Sdim}
1521234353Sdim
1522249423Sdimstatic void GetHexagonLibraryPaths(
1523249423Sdim  const ArgList &Args,
1524249423Sdim  const std::string Ver,
1525249423Sdim  const std::string MarchString,
1526249423Sdim  const std::string &InstalledDir,
1527249423Sdim  ToolChain::path_list *LibPaths)
1528249423Sdim{
1529249423Sdim  bool buildingLib = Args.hasArg(options::OPT_shared);
1530249423Sdim
1531249423Sdim  //----------------------------------------------------------------------------
1532249423Sdim  // -L Args
1533249423Sdim  //----------------------------------------------------------------------------
1534249423Sdim  for (arg_iterator
1535249423Sdim         it = Args.filtered_begin(options::OPT_L),
1536249423Sdim         ie = Args.filtered_end();
1537249423Sdim       it != ie;
1538249423Sdim       ++it) {
1539249423Sdim    for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
1540249423Sdim      LibPaths->push_back((*it)->getValue(i));
1541249423Sdim  }
1542249423Sdim
1543249423Sdim  //----------------------------------------------------------------------------
1544249423Sdim  // Other standard paths
1545249423Sdim  //----------------------------------------------------------------------------
1546249423Sdim  const std::string MarchSuffix = "/" + MarchString;
1547249423Sdim  const std::string G0Suffix = "/G0";
1548249423Sdim  const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
1549249423Sdim  const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/";
1550249423Sdim
1551249423Sdim  // lib/gcc/hexagon/...
1552249423Sdim  std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
1553249423Sdim  if (buildingLib) {
1554249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
1555249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
1556249423Sdim  }
1557249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
1558249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver);
1559249423Sdim
1560249423Sdim  // lib/gcc/...
1561249423Sdim  LibPaths->push_back(RootDir + "lib/gcc");
1562249423Sdim
1563249423Sdim  // hexagon/lib/...
1564249423Sdim  std::string HexagonLibDir = RootDir + "hexagon/lib";
1565249423Sdim  if (buildingLib) {
1566249423Sdim    LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
1567249423Sdim    LibPaths->push_back(HexagonLibDir + G0Suffix);
1568249423Sdim  }
1569249423Sdim  LibPaths->push_back(HexagonLibDir + MarchSuffix);
1570249423Sdim  LibPaths->push_back(HexagonLibDir);
1571249423Sdim}
1572249423Sdim
1573249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
1574249423Sdim                       const ArgList &Args)
1575249423Sdim  : Linux(D, Triple, Args) {
1576249423Sdim  const std::string InstalledDir(getDriver().getInstalledDir());
1577249423Sdim  const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir);
1578249423Sdim
1579249423Sdim  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
1580249423Sdim  // program paths
1581249423Sdim  const std::string BinDir(GnuDir + "/bin");
1582249423Sdim  if (llvm::sys::fs::exists(BinDir))
1583249423Sdim    getProgramPaths().push_back(BinDir);
1584249423Sdim
1585249423Sdim  // Determine version of GCC libraries and headers to use.
1586249423Sdim  const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
1587249423Sdim  llvm::error_code ec;
1588249423Sdim  GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
1589249423Sdim  for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
1590249423Sdim       !ec && di != de; di = di.increment(ec)) {
1591249423Sdim    GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
1592249423Sdim    if (MaxVersion < cv)
1593249423Sdim      MaxVersion = cv;
1594249423Sdim  }
1595249423Sdim  GCCLibAndIncVersion = MaxVersion;
1596249423Sdim
1597249423Sdim  ToolChain::path_list *LibPaths= &getFilePaths();
1598249423Sdim
1599249423Sdim  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
1600249423Sdim  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
1601249423Sdim  // support 'linux' we'll need to fix this up
1602249423Sdim  LibPaths->clear();
1603249423Sdim
1604249423Sdim  GetHexagonLibraryPaths(
1605249423Sdim    Args,
1606249423Sdim    GetGCCLibAndIncVersion(),
1607249423Sdim    GetTargetCPU(Args),
1608249423Sdim    InstalledDir,
1609249423Sdim    LibPaths);
1610249423Sdim}
1611249423Sdim
1612234353SdimHexagon_TC::~Hexagon_TC() {
1613234353Sdim}
1614234353Sdim
1615249423SdimTool *Hexagon_TC::buildAssembler() const {
1616249423Sdim  return new tools::hexagon::Assemble(*this);
1617249423Sdim}
1618234353Sdim
1619249423SdimTool *Hexagon_TC::buildLinker() const {
1620249423Sdim  return new tools::hexagon::Link(*this);
1621249423Sdim}
1622234353Sdim
1623249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1624249423Sdim                                           ArgStringList &CC1Args) const {
1625249423Sdim  const Driver &D = getDriver();
1626249423Sdim
1627249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
1628249423Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
1629249423Sdim    return;
1630249423Sdim
1631249423Sdim  llvm::sys::Path InstallDir(D.InstalledDir);
1632249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1633249423Sdim  std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
1634249423Sdim  std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
1635249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
1636249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
1637249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
1638249423Sdim}
1639249423Sdim
1640249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1641249423Sdim                                              ArgStringList &CC1Args) const {
1642249423Sdim
1643249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1644249423Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1645249423Sdim    return;
1646249423Sdim
1647249423Sdim  const Driver &D = getDriver();
1648249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1649249423Sdim  llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
1650249423Sdim
1651249423Sdim  IncludeDir.appendComponent("hexagon/include/c++/");
1652249423Sdim  IncludeDir.appendComponent(Ver);
1653249423Sdim  addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
1654249423Sdim}
1655249423Sdim
1656249423SdimToolChain::CXXStdlibType
1657249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
1658249423Sdim  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1659249423Sdim  if (!A)
1660249423Sdim    return ToolChain::CST_Libstdcxx;
1661249423Sdim
1662249423Sdim  StringRef Value = A->getValue();
1663249423Sdim  if (Value != "libstdc++") {
1664249423Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1665249423Sdim      << A->getAsString(Args);
1666234353Sdim  }
1667234353Sdim
1668249423Sdim  return ToolChain::CST_Libstdcxx;
1669234353Sdim}
1670234353Sdim
1671249423Sdimstatic Arg *GetLastHexagonArchArg(const ArgList &Args)
1672249423Sdim{
1673249423Sdim  Arg *A = NULL;
1674249423Sdim
1675249423Sdim  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
1676249423Sdim       it != ie; ++it) {
1677249423Sdim    if ((*it)->getOption().matches(options::OPT_march_EQ) ||
1678249423Sdim        (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
1679249423Sdim      A = *it;
1680249423Sdim      A->claim();
1681249423Sdim    } else if ((*it)->getOption().matches(options::OPT_m_Joined)) {
1682249423Sdim      StringRef Value = (*it)->getValue(0);
1683249423Sdim      if (Value.startswith("v")) {
1684249423Sdim        A = *it;
1685249423Sdim        A->claim();
1686249423Sdim      }
1687249423Sdim    }
1688249423Sdim  }
1689249423Sdim  return A;
1690234353Sdim}
1691234353Sdim
1692249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
1693249423Sdim{
1694249423Sdim  // Select the default CPU (v4) if none was given or detection failed.
1695249423Sdim  Arg *A = GetLastHexagonArchArg (Args);
1696249423Sdim  if (A) {
1697249423Sdim    StringRef WhichHexagon = A->getValue();
1698249423Sdim    if (WhichHexagon.startswith("hexagon"))
1699249423Sdim      return WhichHexagon.substr(sizeof("hexagon") - 1);
1700249423Sdim    if (WhichHexagon != "")
1701249423Sdim      return WhichHexagon;
1702249423Sdim  }
1703249423Sdim
1704249423Sdim  return "v4";
1705234353Sdim}
1706249423Sdim// End Hexagon
1707234353Sdim
1708204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
1709204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
1710204793Srdivacky/// Currently does not support anything else but compilation.
1711204793Srdivacky
1712249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple,
1713249423Sdim                           const ArgList &Args)
1714249423Sdim  : ToolChain(D, Triple, Args) {
1715204793Srdivacky  // Path mangling to find libexec
1716204793Srdivacky  std::string Path(getDriver().Dir);
1717204793Srdivacky
1718204793Srdivacky  Path += "/../libexec";
1719204793Srdivacky  getProgramPaths().push_back(Path);
1720204793Srdivacky}
1721204793Srdivacky
1722204793SrdivackyTCEToolChain::~TCEToolChain() {
1723204793Srdivacky}
1724204793Srdivacky
1725223017Sdimbool TCEToolChain::IsMathErrnoDefault() const {
1726223017Sdim  return true;
1727204793Srdivacky}
1728204793Srdivacky
1729243830Sdimbool TCEToolChain::isPICDefault() const {
1730204793Srdivacky  return false;
1731204793Srdivacky}
1732204793Srdivacky
1733251662Sdimbool TCEToolChain::isPIEDefault() const {
1734251662Sdim  return false;
1735251662Sdim}
1736251662Sdim
1737243830Sdimbool TCEToolChain::isPICDefaultForced() const {
1738243830Sdim  return false;
1739204793Srdivacky}
1740204793Srdivacky
1741195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
1742195341Sed
1743234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1744234353Sdim  : Generic_ELF(D, Triple, Args) {
1745201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
1746195341Sed  getFilePaths().push_back("/usr/lib");
1747195341Sed}
1748195341Sed
1749249423SdimTool *OpenBSD::buildAssembler() const {
1750249423Sdim  return new tools::openbsd::Assemble(*this);
1751249423Sdim}
1752195341Sed
1753249423SdimTool *OpenBSD::buildLinker() const {
1754249423Sdim  return new tools::openbsd::Link(*this);
1755195341Sed}
1756195341Sed
1757239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
1758239462Sdim
1759239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1760239462Sdim  : Generic_ELF(D, Triple, Args) {
1761239462Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
1762239462Sdim  getFilePaths().push_back("/usr/lib");
1763239462Sdim}
1764239462Sdim
1765249423SdimTool *Bitrig::buildAssembler() const {
1766249423Sdim  return new tools::bitrig::Assemble(*this);
1767249423Sdim}
1768239462Sdim
1769249423SdimTool *Bitrig::buildLinker() const {
1770249423Sdim  return new tools::bitrig::Link(*this);
1771239462Sdim}
1772239462Sdim
1773239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1774239462Sdim                                          ArgStringList &CC1Args) const {
1775239462Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1776239462Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1777239462Sdim    return;
1778239462Sdim
1779243830Sdim  switch (GetCXXStdlibType(DriverArgs)) {
1780243830Sdim  case ToolChain::CST_Libcxx:
1781243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1782243830Sdim                     getDriver().SysRoot + "/usr/include/c++/");
1783243830Sdim    break;
1784243830Sdim  case ToolChain::CST_Libstdcxx:
1785243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1786243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++");
1787243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1788243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
1789239462Sdim
1790243830Sdim    StringRef Triple = getTriple().str();
1791243830Sdim    if (Triple.startswith("amd64"))
1792243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1793243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
1794243830Sdim                       Triple.substr(5));
1795243830Sdim    else
1796243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1797243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/" +
1798243830Sdim                       Triple);
1799243830Sdim    break;
1800243830Sdim  }
1801239462Sdim}
1802239462Sdim
1803239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
1804239462Sdim                                 ArgStringList &CmdArgs) const {
1805243830Sdim  switch (GetCXXStdlibType(Args)) {
1806243830Sdim  case ToolChain::CST_Libcxx:
1807243830Sdim    CmdArgs.push_back("-lc++");
1808243830Sdim    CmdArgs.push_back("-lcxxrt");
1809243830Sdim    // Include supc++ to provide Unwind until provided by libcxx.
1810243830Sdim    CmdArgs.push_back("-lgcc");
1811243830Sdim    break;
1812243830Sdim  case ToolChain::CST_Libstdcxx:
1813243830Sdim    CmdArgs.push_back("-lstdc++");
1814243830Sdim    break;
1815243830Sdim  }
1816239462Sdim}
1817239462Sdim
1818193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
1819193326Sed
1820234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1821234353Sdim  : Generic_ELF(D, Triple, Args) {
1822212904Sdim
1823234353Sdim  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
1824234353Sdim  // back to '/usr/lib' if it doesn't exist.
1825234353Sdim  if ((Triple.getArch() == llvm::Triple::x86 ||
1826234353Sdim       Triple.getArch() == llvm::Triple::ppc) &&
1827234982Sdim      llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
1828234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
1829234353Sdim  else
1830234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
1831193326Sed}
1832193326Sed
1833249423SdimTool *FreeBSD::buildAssembler() const {
1834249423Sdim  return new tools::freebsd::Assemble(*this);
1835249423Sdim}
1836193326Sed
1837249423SdimTool *FreeBSD::buildLinker() const {
1838249423Sdim  return new tools::freebsd::Link(*this);
1839193326Sed}
1840193326Sed
1841244640Sandrewbool FreeBSD::UseSjLjExceptions() const {
1842244640Sandrew  // FreeBSD uses SjLj exceptions on ARM oabi.
1843244640Sandrew  switch (getTriple().getEnvironment()) {
1844244640Sandrew  case llvm::Triple::GNUEABI:
1845244640Sandrew  case llvm::Triple::EABI:
1846244640Sandrew    return false;
1847244640Sandrew
1848244640Sandrew  default:
1849244640Sandrew    return (getTriple().getArch() == llvm::Triple::arm ||
1850244640Sandrew            getTriple().getArch() == llvm::Triple::thumb);
1851244640Sandrew  }
1852244640Sandrew}
1853244640Sandrew
1854255321StheravenToolChain::CXXStdlibType
1855255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const {
1856255321Stheraven  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
1857255321Stheraven    StringRef Value = A->getValue();
1858255321Stheraven    if (Value == "libc++")
1859255321Stheraven      return ToolChain::CST_Libcxx;
1860255321Stheraven    if (Value == "libstdc++")
1861255321Stheraven      return ToolChain::CST_Libstdcxx;
1862255321Stheraven    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1863255321Stheraven      << A->getAsString(Args);
1864255321Stheraven  }
1865255321Stheraven
1866255321Stheraven  return getTriple().getOSMajorVersion() >= 10 ? ToolChain::CST_Libcxx :
1867255321Stheraven         ToolChain::CST_Libstdcxx;
1868255321Stheraven}
1869255321Stheraven
1870255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1871255321Stheraven                                          ArgStringList &CC1Args) const {
1872255321Stheraven  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1873255321Stheraven      DriverArgs.hasArg(options::OPT_nostdincxx))
1874255321Stheraven    return;
1875255321Stheraven
1876255321Stheraven  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
1877255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
1878255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/v1");
1879255321Stheraven  else
1880255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
1881255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/4.2");
1882255321Stheraven  return;
1883255321Stheraven
1884255321Stheraven}
1885255321Stheraven
1886218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
1887218893Sdim
1888234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1889234353Sdim  : Generic_ELF(D, Triple, Args) {
1890218893Sdim
1891221345Sdim  if (getDriver().UseStdLib) {
1892234353Sdim    // When targeting a 32-bit platform, try the special directory used on
1893234353Sdim    // 64-bit hosts, and only fall back to the main library directory if that
1894234353Sdim    // doesn't work.
1895234353Sdim    // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
1896234353Sdim    // what all logic is needed to emulate the '=' prefix here.
1897234353Sdim    if (Triple.getArch() == llvm::Triple::x86)
1898221345Sdim      getFilePaths().push_back("=/usr/lib/i386");
1899234353Sdim
1900234353Sdim    getFilePaths().push_back("=/usr/lib");
1901218893Sdim  }
1902218893Sdim}
1903218893Sdim
1904249423SdimTool *NetBSD::buildAssembler() const {
1905249423Sdim  return new tools::netbsd::Assemble(*this);
1906249423Sdim}
1907218893Sdim
1908249423SdimTool *NetBSD::buildLinker() const {
1909249423Sdim  return new tools::netbsd::Link(*this);
1910218893Sdim}
1911218893Sdim
1912251662SdimToolChain::CXXStdlibType
1913251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const {
1914251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
1915251662Sdim    StringRef Value = A->getValue();
1916251662Sdim    if (Value == "libstdc++")
1917251662Sdim      return ToolChain::CST_Libstdcxx;
1918251662Sdim    if (Value == "libc++")
1919251662Sdim      return ToolChain::CST_Libcxx;
1920251662Sdim
1921251662Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1922251662Sdim      << A->getAsString(Args);
1923251662Sdim  }
1924251662Sdim
1925251662Sdim  return ToolChain::CST_Libstdcxx;
1926251662Sdim}
1927251662Sdim
1928251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1929251662Sdim                                          ArgStringList &CC1Args) const {
1930251662Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1931251662Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1932251662Sdim    return;
1933251662Sdim
1934251662Sdim  switch (GetCXXStdlibType(DriverArgs)) {
1935251662Sdim  case ToolChain::CST_Libcxx:
1936251662Sdim    addSystemInclude(DriverArgs, CC1Args,
1937251662Sdim                     getDriver().SysRoot + "/usr/include/c++/");
1938251662Sdim    break;
1939251662Sdim  case ToolChain::CST_Libstdcxx:
1940251662Sdim    addSystemInclude(DriverArgs, CC1Args,
1941251662Sdim                     getDriver().SysRoot + "/usr/include/g++");
1942251662Sdim    addSystemInclude(DriverArgs, CC1Args,
1943251662Sdim                     getDriver().SysRoot + "/usr/include/g++/backward");
1944251662Sdim    break;
1945251662Sdim  }
1946251662Sdim}
1947251662Sdim
1948210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
1949210299Sed
1950234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1951234353Sdim  : Generic_ELF(D, Triple, Args) {
1952210299Sed  getFilePaths().push_back(getDriver().Dir + "/../lib");
1953210299Sed  getFilePaths().push_back("/usr/lib");
1954210299Sed}
1955210299Sed
1956249423SdimTool *Minix::buildAssembler() const {
1957249423Sdim  return new tools::minix::Assemble(*this);
1958249423Sdim}
1959210299Sed
1960249423SdimTool *Minix::buildLinker() const {
1961249423Sdim  return new tools::minix::Link(*this);
1962210299Sed}
1963210299Sed
1964198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
1965198092Srdivacky
1966234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
1967234353Sdim                   const ArgList &Args)
1968234353Sdim  : Generic_GCC(D, Triple, Args) {
1969198092Srdivacky
1970212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
1971221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
1972212904Sdim    getProgramPaths().push_back(getDriver().Dir);
1973198092Srdivacky
1974201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
1975198092Srdivacky  getFilePaths().push_back("/usr/lib");
1976198092Srdivacky  getFilePaths().push_back("/usr/sfw/lib");
1977198092Srdivacky  getFilePaths().push_back("/opt/gcc4/lib");
1978198398Srdivacky  getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
1979198092Srdivacky
1980198092Srdivacky}
1981198092Srdivacky
1982249423SdimTool *AuroraUX::buildAssembler() const {
1983249423Sdim  return new tools::auroraux::Assemble(*this);
1984249423Sdim}
1985198092Srdivacky
1986249423SdimTool *AuroraUX::buildLinker() const {
1987249423Sdim  return new tools::auroraux::Link(*this);
1988198092Srdivacky}
1989198092Srdivacky
1990234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
1991198092Srdivacky
1992234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple,
1993234353Sdim                 const ArgList &Args)
1994234353Sdim  : Generic_GCC(D, Triple, Args) {
1995234353Sdim
1996234353Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
1997234353Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
1998234353Sdim    getProgramPaths().push_back(getDriver().Dir);
1999234353Sdim
2000234353Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
2001234353Sdim  getFilePaths().push_back("/usr/lib");
2002234353Sdim}
2003234353Sdim
2004249423SdimTool *Solaris::buildAssembler() const {
2005249423Sdim  return new tools::solaris::Assemble(*this);
2006249423Sdim}
2007234353Sdim
2008249423SdimTool *Solaris::buildLinker() const {
2009249423Sdim  return new tools::solaris::Link(*this);
2010234353Sdim}
2011234353Sdim
2012249423Sdim/// Distribution (very bare-bones at the moment).
2013193326Sed
2014249423Sdimenum Distro {
2015219077Sdim  ArchLinux,
2016218893Sdim  DebianLenny,
2017218893Sdim  DebianSqueeze,
2018223017Sdim  DebianWheezy,
2019249423Sdim  DebianJessie,
2020218893Sdim  Exherbo,
2021223017Sdim  RHEL4,
2022223017Sdim  RHEL5,
2023223017Sdim  RHEL6,
2024218893Sdim  Fedora13,
2025218893Sdim  Fedora14,
2026221345Sdim  Fedora15,
2027234353Sdim  Fedora16,
2028221345Sdim  FedoraRawhide,
2029218893Sdim  OpenSuse11_3,
2030223017Sdim  OpenSuse11_4,
2031223017Sdim  OpenSuse12_1,
2032235864Sdim  OpenSuse12_2,
2033221345Sdim  UbuntuHardy,
2034221345Sdim  UbuntuIntrepid,
2035218893Sdim  UbuntuJaunty,
2036218893Sdim  UbuntuKarmic,
2037218893Sdim  UbuntuLucid,
2038218893Sdim  UbuntuMaverick,
2039221345Sdim  UbuntuNatty,
2040223017Sdim  UbuntuOneiric,
2041234353Sdim  UbuntuPrecise,
2042244628Sdim  UbuntuQuantal,
2043244628Sdim  UbuntuRaring,
2044218893Sdim  UnknownDistro
2045218893Sdim};
2046198092Srdivacky
2047249423Sdimstatic bool IsRedhat(enum Distro Distro) {
2048234353Sdim  return (Distro >= Fedora13 && Distro <= FedoraRawhide) ||
2049234353Sdim         (Distro >= RHEL4    && Distro <= RHEL6);
2050218893Sdim}
2051198092Srdivacky
2052249423Sdimstatic bool IsOpenSuse(enum Distro Distro) {
2053235864Sdim  return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2;
2054193326Sed}
2055193326Sed
2056249423Sdimstatic bool IsDebian(enum Distro Distro) {
2057249423Sdim  return Distro >= DebianLenny && Distro <= DebianJessie;
2058218893Sdim}
2059218893Sdim
2060249423Sdimstatic bool IsUbuntu(enum Distro Distro) {
2061244628Sdim  return Distro >= UbuntuHardy && Distro <= UbuntuRaring;
2062218893Sdim}
2063218893Sdim
2064249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) {
2065234353Sdim  OwningPtr<llvm::MemoryBuffer> File;
2066218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
2067226633Sdim    StringRef Data = File.get()->getBuffer();
2068226633Sdim    SmallVector<StringRef, 8> Lines;
2069218893Sdim    Data.split(Lines, "\n");
2070249423Sdim    Distro Version = UnknownDistro;
2071234353Sdim    for (unsigned i = 0, s = Lines.size(); i != s; ++i)
2072234353Sdim      if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME="))
2073249423Sdim        Version = llvm::StringSwitch<Distro>(Lines[i].substr(17))
2074234353Sdim          .Case("hardy", UbuntuHardy)
2075234353Sdim          .Case("intrepid", UbuntuIntrepid)
2076234353Sdim          .Case("jaunty", UbuntuJaunty)
2077234353Sdim          .Case("karmic", UbuntuKarmic)
2078234353Sdim          .Case("lucid", UbuntuLucid)
2079234353Sdim          .Case("maverick", UbuntuMaverick)
2080234353Sdim          .Case("natty", UbuntuNatty)
2081234353Sdim          .Case("oneiric", UbuntuOneiric)
2082234353Sdim          .Case("precise", UbuntuPrecise)
2083244628Sdim          .Case("quantal", UbuntuQuantal)
2084244628Sdim          .Case("raring", UbuntuRaring)
2085234353Sdim          .Default(UnknownDistro);
2086234353Sdim    return Version;
2087218893Sdim  }
2088218893Sdim
2089218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
2090226633Sdim    StringRef Data = File.get()->getBuffer();
2091234353Sdim    if (Data.startswith("Fedora release 16"))
2092234353Sdim      return Fedora16;
2093234353Sdim    else if (Data.startswith("Fedora release 15"))
2094221345Sdim      return Fedora15;
2095221345Sdim    else if (Data.startswith("Fedora release 14"))
2096218893Sdim      return Fedora14;
2097221345Sdim    else if (Data.startswith("Fedora release 13"))
2098218893Sdim      return Fedora13;
2099221345Sdim    else if (Data.startswith("Fedora release") &&
2100226633Sdim             Data.find("Rawhide") != StringRef::npos)
2101221345Sdim      return FedoraRawhide;
2102223017Sdim    else if (Data.startswith("Red Hat Enterprise Linux") &&
2103226633Sdim             Data.find("release 6") != StringRef::npos)
2104223017Sdim      return RHEL6;
2105223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2106249423Sdim              Data.startswith("CentOS")) &&
2107226633Sdim             Data.find("release 5") != StringRef::npos)
2108223017Sdim      return RHEL5;
2109223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2110249423Sdim              Data.startswith("CentOS")) &&
2111226633Sdim             Data.find("release 4") != StringRef::npos)
2112223017Sdim      return RHEL4;
2113218893Sdim    return UnknownDistro;
2114218893Sdim  }
2115218893Sdim
2116218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
2117226633Sdim    StringRef Data = File.get()->getBuffer();
2118218893Sdim    if (Data[0] == '5')
2119218893Sdim      return DebianLenny;
2120234353Sdim    else if (Data.startswith("squeeze/sid") || Data[0] == '6')
2121218893Sdim      return DebianSqueeze;
2122234353Sdim    else if (Data.startswith("wheezy/sid")  || Data[0] == '7')
2123223017Sdim      return DebianWheezy;
2124249423Sdim    else if (Data.startswith("jessie/sid")  || Data[0] == '8')
2125249423Sdim      return DebianJessie;
2126218893Sdim    return UnknownDistro;
2127218893Sdim  }
2128218893Sdim
2129234353Sdim  if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File))
2130249423Sdim    return llvm::StringSwitch<Distro>(File.get()->getBuffer())
2131234353Sdim      .StartsWith("openSUSE 11.3", OpenSuse11_3)
2132234353Sdim      .StartsWith("openSUSE 11.4", OpenSuse11_4)
2133234353Sdim      .StartsWith("openSUSE 12.1", OpenSuse12_1)
2134235864Sdim      .StartsWith("openSUSE 12.2", OpenSuse12_2)
2135234353Sdim      .Default(UnknownDistro);
2136218893Sdim
2137218893Sdim  bool Exists;
2138218893Sdim  if (!llvm::sys::fs::exists("/etc/exherbo-release", Exists) && Exists)
2139218893Sdim    return Exherbo;
2140218893Sdim
2141219077Sdim  if (!llvm::sys::fs::exists("/etc/arch-release", Exists) && Exists)
2142219077Sdim    return ArchLinux;
2143219077Sdim
2144218893Sdim  return UnknownDistro;
2145218893Sdim}
2146218893Sdim
2147228379Sdim/// \brief Get our best guess at the multiarch triple for a target.
2148228379Sdim///
2149228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use
2150228379Sdim/// a target-triple directory in the library and header search paths.
2151228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple,
2152228379Sdim/// so we provide a rough mapping here.
2153228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple,
2154228379Sdim                                      StringRef SysRoot) {
2155228379Sdim  // For most architectures, just use whatever we have rather than trying to be
2156228379Sdim  // clever.
2157228379Sdim  switch (TargetTriple.getArch()) {
2158228379Sdim  default:
2159228379Sdim    return TargetTriple.str();
2160226633Sdim
2161228379Sdim    // We use the existence of '/lib/<triple>' as a directory to detect some
2162228379Sdim    // common linux triples that don't quite match the Clang triple for both
2163234353Sdim    // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
2164234353Sdim    // regardless of what the actual target triple is.
2165239462Sdim  case llvm::Triple::arm:
2166239462Sdim  case llvm::Triple::thumb:
2167239462Sdim    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
2168239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
2169239462Sdim        return "arm-linux-gnueabihf";
2170239462Sdim    } else {
2171239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
2172239462Sdim        return "arm-linux-gnueabi";
2173239462Sdim    }
2174239462Sdim    return TargetTriple.str();
2175228379Sdim  case llvm::Triple::x86:
2176228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
2177228379Sdim      return "i386-linux-gnu";
2178228379Sdim    return TargetTriple.str();
2179228379Sdim  case llvm::Triple::x86_64:
2180228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
2181228379Sdim      return "x86_64-linux-gnu";
2182228379Sdim    return TargetTriple.str();
2183249423Sdim  case llvm::Triple::aarch64:
2184249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
2185249423Sdim      return "aarch64-linux-gnu";
2186234353Sdim  case llvm::Triple::mips:
2187234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
2188234353Sdim      return "mips-linux-gnu";
2189234353Sdim    return TargetTriple.str();
2190234353Sdim  case llvm::Triple::mipsel:
2191234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
2192234353Sdim      return "mipsel-linux-gnu";
2193234353Sdim    return TargetTriple.str();
2194234353Sdim  case llvm::Triple::ppc:
2195249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
2196249423Sdim      return "powerpc-linux-gnuspe";
2197234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))
2198234353Sdim      return "powerpc-linux-gnu";
2199234353Sdim    return TargetTriple.str();
2200234353Sdim  case llvm::Triple::ppc64:
2201234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))
2202234353Sdim      return "powerpc64-linux-gnu";
2203234353Sdim    return TargetTriple.str();
2204226633Sdim  }
2205226633Sdim}
2206226633Sdim
2207234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
2208234353Sdim  if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
2209234353Sdim}
2210234353Sdim
2211243830Sdimstatic bool isMipsR2Arch(llvm::Triple::ArchType Arch,
2212243830Sdim                         const ArgList &Args) {
2213243830Sdim  if (Arch != llvm::Triple::mips &&
2214243830Sdim      Arch != llvm::Triple::mipsel)
2215243830Sdim    return false;
2216243830Sdim
2217243830Sdim  Arg *A = Args.getLastArg(options::OPT_march_EQ,
2218243830Sdim                           options::OPT_mcpu_EQ,
2219243830Sdim                           options::OPT_mips_CPUs_Group);
2220243830Sdim
2221243830Sdim  if (!A)
2222243830Sdim    return false;
2223243830Sdim
2224243830Sdim  if (A->getOption().matches(options::OPT_mips_CPUs_Group))
2225243830Sdim    return A->getOption().matches(options::OPT_mips32r2);
2226243830Sdim
2227243830Sdim  return A->getValue() == StringRef("mips32r2");
2228243830Sdim}
2229243830Sdim
2230243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple,
2231243830Sdim                                const ArgList &Args) {
2232243830Sdim  if (!isMipsArch(Triple.getArch()))
2233243830Sdim    return Triple.isArch32Bit() ? "lib32" : "lib64";
2234243830Sdim
2235243830Sdim  // lib32 directory has a special meaning on MIPS targets.
2236243830Sdim  // It contains N32 ABI binaries. Use this folder if produce
2237243830Sdim  // code for N32 ABI only.
2238243830Sdim  if (hasMipsN32ABIArg(Args))
2239243830Sdim    return "lib32";
2240243830Sdim
2241243830Sdim  return Triple.isArch32Bit() ? "lib" : "lib64";
2242243830Sdim}
2243243830Sdim
2244234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
2245234353Sdim  : Generic_ELF(D, Triple, Args) {
2246234353Sdim  llvm::Triple::ArchType Arch = Triple.getArch();
2247251662Sdim  std::string SysRoot = computeSysRoot(Args);
2248226633Sdim
2249226633Sdim  // OpenSuse stores the linker with the compiler, add that to the search
2250226633Sdim  // path.
2251226633Sdim  ToolChain::path_list &PPaths = getProgramPaths();
2252228379Sdim  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
2253234353Sdim                         GCCInstallation.getTriple().str() + "/bin").str());
2254226633Sdim
2255226633Sdim  Linker = GetProgramPath("ld");
2256226633Sdim
2257249423Sdim  Distro Distro = DetectDistro(Arch);
2258218893Sdim
2259223017Sdim  if (IsOpenSuse(Distro) || IsUbuntu(Distro)) {
2260218893Sdim    ExtraOpts.push_back("-z");
2261218893Sdim    ExtraOpts.push_back("relro");
2262218893Sdim  }
2263218893Sdim
2264221345Sdim  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
2265218893Sdim    ExtraOpts.push_back("-X");
2266218893Sdim
2267243830Sdim  const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android;
2268251662Sdim  const bool IsMips = isMipsArch(Arch);
2269218893Sdim
2270251662Sdim  if (IsMips && !SysRoot.empty())
2271251662Sdim    ExtraOpts.push_back("--sysroot=" + SysRoot);
2272251662Sdim
2273234353Sdim  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
2274234353Sdim  // and the MIPS ABI require .dynsym to be sorted in different ways.
2275234353Sdim  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
2276234353Sdim  // ABI requires a mapping between the GOT and the symbol table.
2277234353Sdim  // Android loader does not support .gnu.hash.
2278251662Sdim  if (!IsMips && !IsAndroid) {
2279234353Sdim    if (IsRedhat(Distro) || IsOpenSuse(Distro) ||
2280234353Sdim        (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
2281234353Sdim      ExtraOpts.push_back("--hash-style=gnu");
2282234353Sdim
2283234353Sdim    if (IsDebian(Distro) || IsOpenSuse(Distro) || Distro == UbuntuLucid ||
2284234353Sdim        Distro == UbuntuJaunty || Distro == UbuntuKarmic)
2285234353Sdim      ExtraOpts.push_back("--hash-style=both");
2286234353Sdim  }
2287234353Sdim
2288223017Sdim  if (IsRedhat(Distro))
2289218893Sdim    ExtraOpts.push_back("--no-add-needed");
2290218893Sdim
2291223017Sdim  if (Distro == DebianSqueeze || Distro == DebianWheezy ||
2292249423Sdim      Distro == DebianJessie || IsOpenSuse(Distro) ||
2293223017Sdim      (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
2294234353Sdim      (IsUbuntu(Distro) && Distro >= UbuntuKarmic))
2295218893Sdim    ExtraOpts.push_back("--build-id");
2296218893Sdim
2297223017Sdim  if (IsOpenSuse(Distro))
2298223017Sdim    ExtraOpts.push_back("--enable-new-dtags");
2299223017Sdim
2300226633Sdim  // The selection of paths to try here is designed to match the patterns which
2301226633Sdim  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
2302226633Sdim  // This was determined by running GCC in a fake filesystem, creating all
2303226633Sdim  // possible permutations of these directories, and seeing which ones it added
2304226633Sdim  // to the link paths.
2305226633Sdim  path_list &Paths = getFilePaths();
2306219077Sdim
2307243830Sdim  const std::string Multilib = getMultilibDir(Triple, Args);
2308228379Sdim  const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
2309226633Sdim
2310228379Sdim  // Add the multilib suffixed paths where they are available.
2311228379Sdim  if (GCCInstallation.isValid()) {
2312234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2313228379Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2314234353Sdim
2315243830Sdim    if (IsAndroid && isMipsR2Arch(Triple.getArch(), Args))
2316243830Sdim      addPathIfExists(GCCInstallation.getInstallPath() +
2317243830Sdim                      GCCInstallation.getMultiarchSuffix() +
2318243830Sdim                      "/mips-r2",
2319243830Sdim                      Paths);
2320243830Sdim    else
2321243830Sdim      addPathIfExists((GCCInstallation.getInstallPath() +
2322243830Sdim                       GCCInstallation.getMultiarchSuffix()),
2323243830Sdim                      Paths);
2324243830Sdim
2325234353Sdim    // If the GCC installation we found is inside of the sysroot, we want to
2326234353Sdim    // prefer libraries installed in the parent prefix of the GCC installation.
2327234353Sdim    // It is important to *not* use these paths when the GCC installation is
2328234982Sdim    // outside of the system root as that can pick up unintended libraries.
2329234353Sdim    // This usually happens when there is an external cross compiler on the
2330234353Sdim    // host system, and a more minimal sysroot available that is the target of
2331234353Sdim    // the cross.
2332234353Sdim    if (StringRef(LibPath).startswith(SysRoot)) {
2333234353Sdim      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib,
2334234353Sdim                      Paths);
2335234353Sdim      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
2336234353Sdim      addPathIfExists(LibPath + "/../" + Multilib, Paths);
2337234353Sdim    }
2338243830Sdim    // On Android, libraries in the parent prefix of the GCC installation are
2339243830Sdim    // preferred to the ones under sysroot.
2340243830Sdim    if (IsAndroid) {
2341243830Sdim      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
2342243830Sdim    }
2343251662Sdim    // Sourcery CodeBench MIPS toolchain holds some libraries under
2344251662Sdim    // the parent prefix of the GCC installation.
2345251662Sdim    if (IsMips) {
2346251662Sdim      std::string Suffix;
2347251662Sdim      appendMipsTargetSuffix(Suffix, Arch, Args);
2348251662Sdim      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" +
2349251662Sdim                      Multilib + Suffix,
2350251662Sdim                      Paths);
2351251662Sdim    }
2352228379Sdim  }
2353228379Sdim  addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
2354228379Sdim  addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
2355228379Sdim  addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
2356228379Sdim  addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
2357226633Sdim
2358228379Sdim  // Try walking via the GCC triple path in case of multiarch GCC
2359228379Sdim  // installations with strange symlinks.
2360228379Sdim  if (GCCInstallation.isValid())
2361234353Sdim    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
2362228379Sdim                    "/../../" + Multilib, Paths);
2363226633Sdim
2364226633Sdim  // Add the non-multilib suffixed paths (if potentially different).
2365226633Sdim  if (GCCInstallation.isValid()) {
2366226633Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2367234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2368234353Sdim    if (!GCCInstallation.getMultiarchSuffix().empty())
2369226633Sdim      addPathIfExists(GCCInstallation.getInstallPath(), Paths);
2370234353Sdim
2371234353Sdim    if (StringRef(LibPath).startswith(SysRoot)) {
2372234353Sdim      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
2373234353Sdim      addPathIfExists(LibPath, Paths);
2374234353Sdim    }
2375226633Sdim  }
2376226633Sdim  addPathIfExists(SysRoot + "/lib", Paths);
2377226633Sdim  addPathIfExists(SysRoot + "/usr/lib", Paths);
2378251662Sdim
2379251662Sdim  IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow();
2380218893Sdim}
2381218893Sdim
2382218893Sdimbool Linux::HasNativeLLVMSupport() const {
2383218893Sdim  return true;
2384218893Sdim}
2385218893Sdim
2386249423SdimTool *Linux::buildLinker() const {
2387249423Sdim  return new tools::gnutools::Link(*this);
2388249423Sdim}
2389212904Sdim
2390249423SdimTool *Linux::buildAssembler() const {
2391249423Sdim  return new tools::gnutools::Assemble(*this);
2392212904Sdim}
2393212904Sdim
2394249423Sdimvoid Linux::addClangTargetOptions(const ArgList &DriverArgs,
2395249423Sdim                                  ArgStringList &CC1Args) const {
2396239462Sdim  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
2397249423Sdim  bool UseInitArrayDefault
2398249423Sdim    = V >= Generic_GCC::GCCVersion::Parse("4.7.0") ||
2399249423Sdim      getTriple().getArch() == llvm::Triple::aarch64 ||
2400249423Sdim      getTriple().getEnvironment() == llvm::Triple::Android;
2401249423Sdim  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
2402249423Sdim                         options::OPT_fno_use_init_array,
2403249423Sdim                         UseInitArrayDefault))
2404239462Sdim    CC1Args.push_back("-fuse-init-array");
2405239462Sdim}
2406239462Sdim
2407251662Sdimstd::string Linux::computeSysRoot(const ArgList &Args) const {
2408251662Sdim  if (!getDriver().SysRoot.empty())
2409251662Sdim    return getDriver().SysRoot;
2410251662Sdim
2411251662Sdim  if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
2412251662Sdim    return std::string();
2413251662Sdim
2414251662Sdim  std::string Path =
2415251662Sdim    (GCCInstallation.getInstallPath() +
2416251662Sdim     "/../../../../" + GCCInstallation.getTriple().str() + "/libc").str();
2417251662Sdim  appendMipsTargetSuffix(Path, getTriple().getArch(), Args);
2418251662Sdim
2419251662Sdim  return llvm::sys::fs::exists(Path) ? Path : "";
2420251662Sdim}
2421251662Sdim
2422228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2423228379Sdim                                      ArgStringList &CC1Args) const {
2424228379Sdim  const Driver &D = getDriver();
2425251662Sdim  std::string SysRoot = computeSysRoot(DriverArgs);
2426228379Sdim
2427228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc))
2428228379Sdim    return;
2429228379Sdim
2430228379Sdim  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
2431251662Sdim    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
2432228379Sdim
2433228379Sdim  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2434228379Sdim    llvm::sys::Path P(D.ResourceDir);
2435228379Sdim    P.appendComponent("include");
2436228379Sdim    addSystemInclude(DriverArgs, CC1Args, P.str());
2437228379Sdim  }
2438228379Sdim
2439228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2440228379Sdim    return;
2441228379Sdim
2442228379Sdim  // Check for configure-time C include directories.
2443228379Sdim  StringRef CIncludeDirs(C_INCLUDE_DIRS);
2444228379Sdim  if (CIncludeDirs != "") {
2445228379Sdim    SmallVector<StringRef, 5> dirs;
2446228379Sdim    CIncludeDirs.split(dirs, ":");
2447228379Sdim    for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end();
2448228379Sdim         I != E; ++I) {
2449251662Sdim      StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : "";
2450228379Sdim      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I);
2451228379Sdim    }
2452228379Sdim    return;
2453228379Sdim  }
2454228379Sdim
2455228379Sdim  // Lacking those, try to detect the correct set of system includes for the
2456228379Sdim  // target triple.
2457228379Sdim
2458251662Sdim  // Sourcery CodeBench and modern FSF Mips toolchains put extern C
2459251662Sdim  // system includes under three additional directories.
2460251662Sdim  if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) {
2461251662Sdim    addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
2462251662Sdim                                    GCCInstallation.getInstallPath() +
2463251662Sdim                                    "/include");
2464251662Sdim
2465251662Sdim    addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
2466251662Sdim                                    GCCInstallation.getInstallPath() +
2467251662Sdim                                    "/../../../../" +
2468251662Sdim                                    GCCInstallation.getTriple().str() +
2469251662Sdim                                    "/libc/usr/include");
2470251662Sdim  }
2471251662Sdim
2472228379Sdim  // Implement generic Debian multiarch support.
2473228379Sdim  const StringRef X86_64MultiarchIncludeDirs[] = {
2474228379Sdim    "/usr/include/x86_64-linux-gnu",
2475228379Sdim
2476228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2477228379Sdim    // in use in any released version of Debian, so we should consider
2478228379Sdim    // removing them.
2479228379Sdim    "/usr/include/i686-linux-gnu/64",
2480228379Sdim    "/usr/include/i486-linux-gnu/64"
2481228379Sdim  };
2482228379Sdim  const StringRef X86MultiarchIncludeDirs[] = {
2483228379Sdim    "/usr/include/i386-linux-gnu",
2484228379Sdim
2485228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2486228379Sdim    // in use in any released version of Debian, so we should consider
2487228379Sdim    // removing them.
2488228379Sdim    "/usr/include/x86_64-linux-gnu/32",
2489228379Sdim    "/usr/include/i686-linux-gnu",
2490228379Sdim    "/usr/include/i486-linux-gnu"
2491228379Sdim  };
2492249423Sdim  const StringRef AArch64MultiarchIncludeDirs[] = {
2493249423Sdim    "/usr/include/aarch64-linux-gnu"
2494249423Sdim  };
2495228379Sdim  const StringRef ARMMultiarchIncludeDirs[] = {
2496228379Sdim    "/usr/include/arm-linux-gnueabi"
2497228379Sdim  };
2498239462Sdim  const StringRef ARMHFMultiarchIncludeDirs[] = {
2499239462Sdim    "/usr/include/arm-linux-gnueabihf"
2500239462Sdim  };
2501234353Sdim  const StringRef MIPSMultiarchIncludeDirs[] = {
2502234353Sdim    "/usr/include/mips-linux-gnu"
2503234353Sdim  };
2504234353Sdim  const StringRef MIPSELMultiarchIncludeDirs[] = {
2505234353Sdim    "/usr/include/mipsel-linux-gnu"
2506234353Sdim  };
2507234353Sdim  const StringRef PPCMultiarchIncludeDirs[] = {
2508234353Sdim    "/usr/include/powerpc-linux-gnu"
2509234353Sdim  };
2510234353Sdim  const StringRef PPC64MultiarchIncludeDirs[] = {
2511234353Sdim    "/usr/include/powerpc64-linux-gnu"
2512234353Sdim  };
2513228379Sdim  ArrayRef<StringRef> MultiarchIncludeDirs;
2514228379Sdim  if (getTriple().getArch() == llvm::Triple::x86_64) {
2515228379Sdim    MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
2516228379Sdim  } else if (getTriple().getArch() == llvm::Triple::x86) {
2517228379Sdim    MultiarchIncludeDirs = X86MultiarchIncludeDirs;
2518249423Sdim  } else if (getTriple().getArch() == llvm::Triple::aarch64) {
2519249423Sdim    MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
2520228379Sdim  } else if (getTriple().getArch() == llvm::Triple::arm) {
2521239462Sdim    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
2522239462Sdim      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
2523239462Sdim    else
2524239462Sdim      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
2525234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mips) {
2526234353Sdim    MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
2527234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mipsel) {
2528234353Sdim    MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
2529234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc) {
2530234353Sdim    MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
2531234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc64) {
2532234353Sdim    MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
2533228379Sdim  }
2534228379Sdim  for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(),
2535228379Sdim                                     E = MultiarchIncludeDirs.end();
2536228379Sdim       I != E; ++I) {
2537251662Sdim    if (llvm::sys::fs::exists(SysRoot + *I)) {
2538251662Sdim      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I);
2539228379Sdim      break;
2540228379Sdim    }
2541228379Sdim  }
2542228379Sdim
2543228379Sdim  if (getTriple().getOS() == llvm::Triple::RTEMS)
2544228379Sdim    return;
2545228379Sdim
2546234353Sdim  // Add an include of '/include' directly. This isn't provided by default by
2547234353Sdim  // system GCCs, but is often used with cross-compiling GCCs, and harmless to
2548234353Sdim  // add even when Clang is acting as-if it were a system compiler.
2549251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
2550234353Sdim
2551251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
2552228379Sdim}
2553228379Sdim
2554249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation.
2555234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
2556234353Sdim                                                const ArgList &DriverArgs,
2557234353Sdim                                                ArgStringList &CC1Args) {
2558228379Sdim  if (!llvm::sys::fs::exists(Base))
2559228379Sdim    return false;
2560228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base);
2561228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir);
2562228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/backward");
2563228379Sdim  return true;
2564228379Sdim}
2565228379Sdim
2566249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
2567249423Sdim/// libstdc++ installation.
2568249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
2569249423Sdim                                                Twine TargetArchDir,
2570249423Sdim                                                Twine MultiLibSuffix,
2571249423Sdim                                                const ArgList &DriverArgs,
2572249423Sdim                                                ArgStringList &CC1Args) {
2573249423Sdim  if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix,
2574249423Sdim                                DriverArgs, CC1Args))
2575249423Sdim    return false;
2576249423Sdim
2577249423Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
2578249423Sdim                   + MultiLibSuffix);
2579249423Sdim  return true;
2580249423Sdim}
2581249423Sdim
2582228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2583228379Sdim                                         ArgStringList &CC1Args) const {
2584228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2585228379Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
2586228379Sdim    return;
2587228379Sdim
2588228379Sdim  // Check if libc++ has been enabled and provide its include paths if so.
2589228379Sdim  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
2590228379Sdim    // libc++ is always installed at a fixed path on Linux currently.
2591228379Sdim    addSystemInclude(DriverArgs, CC1Args,
2592228379Sdim                     getDriver().SysRoot + "/usr/include/c++/v1");
2593228379Sdim    return;
2594228379Sdim  }
2595228379Sdim
2596234353Sdim  // We need a detected GCC installation on Linux to provide libstdc++'s
2597234353Sdim  // headers. We handled the libc++ case above.
2598234353Sdim  if (!GCCInstallation.isValid())
2599228379Sdim    return;
2600228379Sdim
2601228379Sdim  // By default, look for the C++ headers in an include directory adjacent to
2602228379Sdim  // the lib directory of the GCC installation. Note that this is expect to be
2603228379Sdim  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
2604228379Sdim  StringRef LibDir = GCCInstallation.getParentLibPath();
2605228379Sdim  StringRef InstallDir = GCCInstallation.getInstallPath();
2606239462Sdim  StringRef Version = GCCInstallation.getVersion().Text;
2607243830Sdim  StringRef TripleStr = GCCInstallation.getTriple().str();
2608243830Sdim
2609249423Sdim  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
2610249423Sdim                               "/c++/" + Version.str(),
2611249423Sdim                               TripleStr,
2612249423Sdim                               GCCInstallation.getMultiarchSuffix(),
2613249423Sdim                               DriverArgs, CC1Args))
2614249423Sdim    return;
2615249423Sdim
2616243830Sdim  const std::string IncludePathCandidates[] = {
2617228379Sdim    // Gentoo is weird and places its headers inside the GCC install, so if the
2618228379Sdim    // first attempt to find the headers fails, try this pattern.
2619243830Sdim    InstallDir.str() + "/include/g++-v4",
2620243830Sdim    // Android standalone toolchain has C++ headers in yet another place.
2621243830Sdim    LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.str(),
2622243830Sdim    // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
2623243830Sdim    // without a subdirectory corresponding to the gcc version.
2624243830Sdim    LibDir.str() + "/../include/c++",
2625243830Sdim  };
2626243830Sdim
2627243830Sdim  for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
2628243830Sdim    if (addLibStdCXXIncludePaths(IncludePathCandidates[i], (TripleStr +
2629243830Sdim                GCCInstallation.getMultiarchSuffix()),
2630243830Sdim            DriverArgs, CC1Args))
2631243830Sdim      break;
2632228379Sdim  }
2633228379Sdim}
2634228379Sdim
2635251662Sdimbool Linux::isPIEDefault() const {
2636251662Sdim  return IsPIEDefault;
2637251662Sdim}
2638251662Sdim
2639193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
2640193326Sed
2641234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2642234353Sdim  : Generic_ELF(D, Triple, Args) {
2643193326Sed
2644193326Sed  // Path mangling to find libexec
2645212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2646221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2647212904Sdim    getProgramPaths().push_back(getDriver().Dir);
2648193326Sed
2649201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
2650193326Sed  getFilePaths().push_back("/usr/lib");
2651251662Sdim  if (llvm::sys::fs::exists("/usr/lib/gcc47"))
2652251662Sdim    getFilePaths().push_back("/usr/lib/gcc47");
2653251662Sdim  else
2654251662Sdim    getFilePaths().push_back("/usr/lib/gcc44");
2655193326Sed}
2656193326Sed
2657249423SdimTool *DragonFly::buildAssembler() const {
2658249423Sdim  return new tools::dragonfly::Assemble(*this);
2659249423Sdim}
2660193326Sed
2661249423SdimTool *DragonFly::buildLinker() const {
2662249423Sdim  return new tools::dragonfly::Link(*this);
2663193326Sed}
2664