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 "clang/Basic/ObjCRuntime.h"
12249423Sdim#include "clang/Basic/Version.h"
13208600Srdivacky#include "clang/Driver/Compilation.h"
14193326Sed#include "clang/Driver/Driver.h"
15193326Sed#include "clang/Driver/DriverDiagnostic.h"
16199512Srdivacky#include "clang/Driver/Options.h"
17263508Sdim#include "clang/Driver/SanitizerArgs.h"
18249423Sdim#include "llvm/ADT/STLExtras.h"
19212904Sdim#include "llvm/ADT/SmallString.h"
20193326Sed#include "llvm/ADT/StringExtras.h"
21226633Sdim#include "llvm/ADT/StringSwitch.h"
22263508Sdim#include "llvm/Option/Arg.h"
23263508Sdim#include "llvm/Option/ArgList.h"
24263508Sdim#include "llvm/Option/OptTable.h"
25263508Sdim#include "llvm/Option/Option.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"
32263508Sdim#include "llvm/Support/Program.h"
33193326Sed
34249423Sdim// FIXME: This needs to be listed last until we fix the broken include guards
35249423Sdim// in these files and the LLVM config.h files.
36249423Sdim#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
37243830Sdim
38193326Sed#include <cstdlib> // ::getenv
39193326Sed
40193326Sedusing namespace clang::driver;
41193326Sedusing namespace clang::driver::toolchains;
42226633Sdimusing namespace clang;
43263508Sdimusing namespace llvm::opt;
44193326Sed
45198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64.
46193326Sed
47249423SdimDarwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
48249423Sdim  : ToolChain(D, Triple, Args), TargetInitialized(false)
49198092Srdivacky{
50234353Sdim  // Compute the initial Darwin version from the triple
51234353Sdim  unsigned Major, Minor, Micro;
52234353Sdim  if (!Triple.getMacOSXVersion(Major, Minor, Micro))
53234353Sdim    getDriver().Diag(diag::err_drv_invalid_darwin_version) <<
54234353Sdim      Triple.getOSName();
55234353Sdim  llvm::raw_string_ostream(MacosxVersionMin)
56234353Sdim    << Major << '.' << Minor << '.' << Micro;
57212904Sdim
58234353Sdim  // FIXME: DarwinVersion is only used to find GCC's libexec directory.
59234353Sdim  // It should be removed when we stop supporting that.
60234353Sdim  DarwinVersion[0] = Minor + 4;
61234353Sdim  DarwinVersion[1] = Micro;
62234353Sdim  DarwinVersion[2] = 0;
63239462Sdim
64239462Sdim  // Compute the initial iOS version from the triple
65239462Sdim  Triple.getiOSVersion(Major, Minor, Micro);
66239462Sdim  llvm::raw_string_ostream(iOSVersionMin)
67239462Sdim    << Major << '.' << Minor << '.' << Micro;
68198092Srdivacky}
69198092Srdivacky
70212904Sdimtypes::ID Darwin::LookupTypeForExtension(const char *Ext) const {
71212904Sdim  types::ID Ty = types::lookupTypeForExtension(Ext);
72212904Sdim
73212904Sdim  // Darwin always preprocesses assembly files (unless -x is used explicitly).
74212904Sdim  if (Ty == types::TY_PP_Asm)
75212904Sdim    return types::TY_Asm;
76212904Sdim
77212904Sdim  return Ty;
78212904Sdim}
79212904Sdim
80218893Sdimbool Darwin::HasNativeLLVMSupport() const {
81218893Sdim  return true;
82218893Sdim}
83218893Sdim
84239462Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
85239462SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
86243830Sdim  if (isTargetIPhoneOS())
87239462Sdim    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
88243830Sdim  if (isNonFragile)
89243830Sdim    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
90243830Sdim  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
91224145Sdim}
92224145Sdim
93226633Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
94226633Sdimbool Darwin::hasBlocksRuntime() const {
95226633Sdim  if (isTargetIPhoneOS())
96226633Sdim    return !isIPhoneOSVersionLT(3, 2);
97226633Sdim  else
98226633Sdim    return !isMacosxVersionLT(10, 6);
99226633Sdim}
100202879Srdivacky
101226633Sdimstatic const char *GetArmArchForMArch(StringRef Value) {
102226633Sdim  return llvm::StringSwitch<const char*>(Value)
103226633Sdim    .Case("armv6k", "armv6")
104249423Sdim    .Case("armv6m", "armv6m")
105226633Sdim    .Case("armv5tej", "armv5")
106226633Sdim    .Case("xscale", "xscale")
107226633Sdim    .Case("armv4t", "armv4t")
108226633Sdim    .Case("armv7", "armv7")
109226633Sdim    .Cases("armv7a", "armv7-a", "armv7")
110226633Sdim    .Cases("armv7r", "armv7-r", "armv7")
111249423Sdim    .Cases("armv7em", "armv7e-m", "armv7em")
112243830Sdim    .Cases("armv7f", "armv7-f", "armv7f")
113243830Sdim    .Cases("armv7k", "armv7-k", "armv7k")
114249423Sdim    .Cases("armv7m", "armv7-m", "armv7m")
115243830Sdim    .Cases("armv7s", "armv7-s", "armv7s")
116226633Sdim    .Default(0);
117202879Srdivacky}
118202879Srdivacky
119226633Sdimstatic const char *GetArmArchForMCpu(StringRef Value) {
120226633Sdim  return llvm::StringSwitch<const char *>(Value)
121226633Sdim    .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
122226633Sdim    .Cases("arm10e", "arm10tdmi", "armv5")
123226633Sdim    .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
124226633Sdim    .Case("xscale", "xscale")
125249423Sdim    .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
126249423Sdim    .Case("cortex-m0", "armv6m")
127263508Sdim    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7")
128263508Sdim    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7")
129263508Sdim    .Cases("cortex-r4", "cortex-r5", "armv7r")
130243830Sdim    .Case("cortex-a9-mp", "armv7f")
131249423Sdim    .Case("cortex-m3", "armv7m")
132249423Sdim    .Case("cortex-m4", "armv7em")
133243830Sdim    .Case("swift", "armv7s")
134226633Sdim    .Default(0);
135202879Srdivacky}
136202879Srdivacky
137226633SdimStringRef Darwin::getDarwinArchName(const ArgList &Args) const {
138202879Srdivacky  switch (getTriple().getArch()) {
139202879Srdivacky  default:
140202879Srdivacky    return getArchName();
141223017Sdim
142221345Sdim  case llvm::Triple::thumb:
143202879Srdivacky  case llvm::Triple::arm: {
144202879Srdivacky    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
145243830Sdim      if (const char *Arch = GetArmArchForMArch(A->getValue()))
146202879Srdivacky        return Arch;
147202879Srdivacky
148202879Srdivacky    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
149243830Sdim      if (const char *Arch = GetArmArchForMCpu(A->getValue()))
150202879Srdivacky        return Arch;
151202879Srdivacky
152202879Srdivacky    return "arm";
153202879Srdivacky  }
154202879Srdivacky  }
155202879Srdivacky}
156202879Srdivacky
157198092SrdivackyDarwin::~Darwin() {
158193326Sed}
159193326Sed
160226633Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
161226633Sdim                                                types::ID InputType) const {
162226633Sdim  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
163212904Sdim
164212904Sdim  // If the target isn't initialized (e.g., an unknown Darwin platform, return
165212904Sdim  // the default triple).
166212904Sdim  if (!isTargetInitialized())
167212904Sdim    return Triple.getTriple();
168223017Sdim
169263508Sdim  if (Triple.getArchName() == "thumbv6m" ||
170263508Sdim      Triple.getArchName() == "thumbv7m" ||
171263508Sdim      Triple.getArchName() == "thumbv7em") {
172263508Sdim    // OS is ios or macosx unless it's the v6m or v7m.
173263508Sdim    Triple.setOS(llvm::Triple::Darwin);
174263508Sdim    Triple.setEnvironment(llvm::Triple::EABI);
175263508Sdim  } else {
176263508Sdim    SmallString<16> Str;
177263508Sdim    Str += isTargetIPhoneOS() ? "ios" : "macosx";
178263508Sdim    Str += getTargetVersion().getAsString();
179263508Sdim    Triple.setOSName(Str);
180263508Sdim  }
181223017Sdim
182212904Sdim  return Triple.getTriple();
183212904Sdim}
184212904Sdim
185234353Sdimvoid Generic_ELF::anchor() {}
186234353Sdim
187249423SdimTool *Darwin::getTool(Action::ActionClass AC) const {
188249423Sdim  switch (AC) {
189249423Sdim  case Action::LipoJobClass:
190249423Sdim    if (!Lipo)
191249423Sdim      Lipo.reset(new tools::darwin::Lipo(*this));
192249423Sdim    return Lipo.get();
193249423Sdim  case Action::DsymutilJobClass:
194249423Sdim    if (!Dsymutil)
195249423Sdim      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
196249423Sdim    return Dsymutil.get();
197249423Sdim  case Action::VerifyJobClass:
198249423Sdim    if (!VerifyDebug)
199249423Sdim      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
200249423Sdim    return VerifyDebug.get();
201249423Sdim  default:
202249423Sdim    return ToolChain::getTool(AC);
203239462Sdim  }
204249423Sdim}
205193326Sed
206249423SdimTool *Darwin::buildLinker() const {
207249423Sdim  return new tools::darwin::Link(*this);
208249423Sdim}
209208600Srdivacky
210249423SdimTool *Darwin::buildAssembler() const {
211249423Sdim  return new tools::darwin::Assemble(*this);
212193326Sed}
213193326Sed
214249423SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
215249423Sdim                         const ArgList &Args)
216249423Sdim  : Darwin(D, Triple, Args)
217198092Srdivacky{
218218893Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
219218893Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
220218893Sdim    getProgramPaths().push_back(getDriver().Dir);
221218893Sdim
222198092Srdivacky  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
223212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
224212904Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
225212904Sdim    getProgramPaths().push_back(getDriver().Dir);
226226633Sdim}
227226633Sdim
228224145Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args,
229224145Sdim                                 ArgStringList &CmdArgs) const {
230226633Sdim
231226633Sdim  CmdArgs.push_back("-force_load");
232263508Sdim  SmallString<128> P(getDriver().ClangExecutable);
233263508Sdim  llvm::sys::path::remove_filename(P); // 'clang'
234263508Sdim  llvm::sys::path::remove_filename(P); // 'bin'
235263508Sdim  llvm::sys::path::append(P, "lib", "arc", "libarclite_");
236224145Sdim  // Mash in the platform.
237234353Sdim  if (isTargetIOSSimulator())
238263508Sdim    P += "iphonesimulator";
239234353Sdim  else if (isTargetIPhoneOS())
240263508Sdim    P += "iphoneos";
241224145Sdim  else
242263508Sdim    P += "macosx";
243263508Sdim  P += ".a";
244224145Sdim
245263508Sdim  CmdArgs.push_back(Args.MakeArgString(P));
246224145Sdim}
247224145Sdim
248224145Sdimvoid DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
249226633Sdim                                    ArgStringList &CmdArgs,
250249423Sdim                                    const char *DarwinStaticLib,
251249423Sdim                                    bool AlwaysLink) const {
252263508Sdim  SmallString<128> P(getDriver().ResourceDir);
253263508Sdim  llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib);
254226633Sdim
255224145Sdim  // For now, allow missing resource libraries to support developers who may
256249423Sdim  // not have compiler-rt checked out or integrated into their build (unless
257249423Sdim  // we explicitly force linking with this library).
258263508Sdim  if (AlwaysLink || llvm::sys::fs::exists(P.str()))
259224145Sdim    CmdArgs.push_back(Args.MakeArgString(P.str()));
260224145Sdim}
261224145Sdim
262198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
263198092Srdivacky                                        ArgStringList &CmdArgs) const {
264234353Sdim  // Darwin only supports the compiler-rt based runtime libraries.
265234353Sdim  switch (GetRuntimeLibType(Args)) {
266234353Sdim  case ToolChain::RLT_CompilerRT:
267234353Sdim    break;
268234353Sdim  default:
269234353Sdim    getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
270243830Sdim      << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
271234353Sdim    return;
272234353Sdim  }
273234353Sdim
274202879Srdivacky  // Darwin doesn't support real static executables, don't link any runtime
275202879Srdivacky  // libraries with -static.
276243830Sdim  if (Args.hasArg(options::OPT_static) ||
277243830Sdim      Args.hasArg(options::OPT_fapple_kext) ||
278243830Sdim      Args.hasArg(options::OPT_mkernel))
279198092Srdivacky    return;
280198092Srdivacky
281198092Srdivacky  // Reject -static-libgcc for now, we can deal with this when and if someone
282198092Srdivacky  // cares. This is useful in situations where someone wants to statically link
283198092Srdivacky  // something like libstdc++, and needs its runtime support routines.
284198092Srdivacky  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
285226633Sdim    getDriver().Diag(diag::err_drv_unsupported_opt)
286198092Srdivacky      << A->getAsString(Args);
287198092Srdivacky    return;
288198092Srdivacky  }
289198092Srdivacky
290234353Sdim  // If we are building profile support, link that library in.
291234353Sdim  if (Args.hasArg(options::OPT_fprofile_arcs) ||
292234353Sdim      Args.hasArg(options::OPT_fprofile_generate) ||
293234353Sdim      Args.hasArg(options::OPT_fcreate_profile) ||
294234353Sdim      Args.hasArg(options::OPT_coverage)) {
295234353Sdim    // Select the appropriate runtime library for the target.
296234353Sdim    if (isTargetIPhoneOS()) {
297234353Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a");
298234353Sdim    } else {
299234353Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a");
300234353Sdim    }
301234353Sdim  }
302234353Sdim
303263508Sdim  const SanitizerArgs &Sanitize = getSanitizerArgs();
304243830Sdim
305249423Sdim  // Add Ubsan runtime library, if required.
306249423Sdim  if (Sanitize.needsUbsanRt()) {
307263508Sdim    // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
308249423Sdim    if (isTargetIPhoneOS()) {
309249423Sdim      getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
310249423Sdim        << "-fsanitize=undefined";
311249423Sdim    } else {
312249423Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
313249423Sdim
314249423Sdim      // The Ubsan runtime library requires C++.
315249423Sdim      AddCXXStdlibLibArgs(Args, CmdArgs);
316249423Sdim    }
317249423Sdim  }
318249423Sdim
319234353Sdim  // Add ASAN runtime library, if required. Dynamic libraries and bundles
320234353Sdim  // should not be linked with the runtime library.
321243830Sdim  if (Sanitize.needsAsanRt()) {
322263508Sdim    // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
323249423Sdim    if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
324234353Sdim      getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
325243830Sdim        << "-fsanitize=address";
326234353Sdim    } else {
327263508Sdim      if (!Args.hasArg(options::OPT_dynamiclib) &&
328263508Sdim          !Args.hasArg(options::OPT_bundle)) {
329249423Sdim        // The ASAN runtime library requires C++.
330249423Sdim        AddCXXStdlibLibArgs(Args, CmdArgs);
331249423Sdim      }
332263508Sdim      if (isTargetMacOS()) {
333263508Sdim        AddLinkRuntimeLib(Args, CmdArgs,
334263508Sdim                          "libclang_rt.asan_osx_dynamic.dylib",
335263508Sdim                          true);
336263508Sdim      } else {
337263508Sdim        if (isTargetIOSSimulator()) {
338263508Sdim          AddLinkRuntimeLib(Args, CmdArgs,
339263508Sdim                            "libclang_rt.asan_iossim_dynamic.dylib",
340263508Sdim                            true);
341263508Sdim        }
342263508Sdim      }
343234353Sdim    }
344234353Sdim  }
345234353Sdim
346202879Srdivacky  // Otherwise link libSystem, then the dynamic runtime library, and finally any
347202879Srdivacky  // target specific static runtime library.
348198092Srdivacky  CmdArgs.push_back("-lSystem");
349202879Srdivacky
350202879Srdivacky  // Select the dynamic runtime library and the target specific static library.
351203955Srdivacky  if (isTargetIPhoneOS()) {
352221345Sdim    // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
353221345Sdim    // it never went into the SDK.
354226633Sdim    // Linking against libgcc_s.1 isn't needed for iOS 5.0+
355226633Sdim    if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator())
356226633Sdim      CmdArgs.push_back("-lgcc_s.1");
357202879Srdivacky
358221345Sdim    // We currently always need a static runtime library for iOS.
359224145Sdim    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
360202879Srdivacky  } else {
361202879Srdivacky    // The dynamic runtime library was merged with libSystem for 10.6 and
362202879Srdivacky    // beyond; only 10.4 and 10.5 need an additional runtime library.
363203955Srdivacky    if (isMacosxVersionLT(10, 5))
364202879Srdivacky      CmdArgs.push_back("-lgcc_s.10.4");
365203955Srdivacky    else if (isMacosxVersionLT(10, 6))
366202879Srdivacky      CmdArgs.push_back("-lgcc_s.10.5");
367202879Srdivacky
368218893Sdim    // For OS X, we thought we would only need a static runtime library when
369221345Sdim    // targeting 10.4, to provide versions of the static functions which were
370218893Sdim    // omitted from 10.4.dylib.
371218893Sdim    //
372218893Sdim    // Unfortunately, that turned out to not be true, because Darwin system
373218893Sdim    // headers can still use eprintf on i386, and it is not exported from
374218893Sdim    // libSystem. Therefore, we still must provide a runtime library just for
375218893Sdim    // the tiny tiny handful of projects that *might* use that symbol.
376218893Sdim    if (isMacosxVersionLT(10, 5)) {
377224145Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
378218893Sdim    } else {
379218893Sdim      if (getTriple().getArch() == llvm::Triple::x86)
380224145Sdim        AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
381224145Sdim      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
382218893Sdim    }
383202879Srdivacky  }
384224145Sdim}
385202879Srdivacky
386212904Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
387201361Srdivacky  const OptTable &Opts = getDriver().getOpts();
388193326Sed
389243830Sdim  // Support allowing the SDKROOT environment variable used by xcrun and other
390243830Sdim  // Xcode tools to define the default sysroot, by making it the default for
391243830Sdim  // isysroot.
392249423Sdim  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
393249423Sdim    // Warn if the path does not exist.
394263508Sdim    if (!llvm::sys::fs::exists(A->getValue()))
395249423Sdim      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
396249423Sdim  } else {
397243830Sdim    if (char *env = ::getenv("SDKROOT")) {
398249423Sdim      // We only use this value as the default if it is an absolute path,
399249423Sdim      // exists, and it is not the root path.
400249423Sdim      if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&
401249423Sdim          StringRef(env) != "/") {
402243830Sdim        Args.append(Args.MakeSeparateArg(
403243830Sdim                      0, Opts.getOption(options::OPT_isysroot), env));
404243830Sdim      }
405243830Sdim    }
406243830Sdim  }
407243830Sdim
408203955Srdivacky  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
409221345Sdim  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
410221345Sdim  Arg *iOSSimVersion = Args.getLastArg(
411221345Sdim    options::OPT_mios_simulator_version_min_EQ);
412224145Sdim
413221345Sdim  if (OSXVersion && (iOSVersion || iOSSimVersion)) {
414226633Sdim    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
415193326Sed          << OSXVersion->getAsString(Args)
416221345Sdim          << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args);
417221345Sdim    iOSVersion = iOSSimVersion = 0;
418221345Sdim  } else if (iOSVersion && iOSSimVersion) {
419226633Sdim    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
420221345Sdim          << iOSVersion->getAsString(Args)
421221345Sdim          << iOSSimVersion->getAsString(Args);
422221345Sdim    iOSSimVersion = 0;
423221345Sdim  } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) {
424226633Sdim    // If no deployment target was specified on the command line, check for
425203955Srdivacky    // environment defines.
426226633Sdim    StringRef OSXTarget;
427226633Sdim    StringRef iOSTarget;
428226633Sdim    StringRef iOSSimTarget;
429226633Sdim    if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
430226633Sdim      OSXTarget = env;
431226633Sdim    if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
432226633Sdim      iOSTarget = env;
433226633Sdim    if (char *env = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET"))
434226633Sdim      iOSSimTarget = env;
435203955Srdivacky
436226633Sdim    // If no '-miphoneos-version-min' specified on the command line and
437226633Sdim    // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default
438234982Sdim    // based on -isysroot.
439226633Sdim    if (iOSTarget.empty()) {
440226633Sdim      if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
441226633Sdim        StringRef first, second;
442243830Sdim        StringRef isysroot = A->getValue();
443226633Sdim        llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
444226633Sdim        if (second != "")
445226633Sdim          iOSTarget = second.substr(0,3);
446226633Sdim      }
447226633Sdim    }
448203955Srdivacky
449226633Sdim    // If no OSX or iOS target has been specified and we're compiling for armv7,
450226633Sdim    // go ahead as assume we're targeting iOS.
451239462Sdim    if (OSXTarget.empty() && iOSTarget.empty() &&
452243830Sdim        (getDarwinArchName(Args) == "armv7" ||
453243830Sdim         getDarwinArchName(Args) == "armv7s"))
454239462Sdim        iOSTarget = iOSVersionMin;
455226633Sdim
456221345Sdim    // Handle conflicting deployment targets
457193326Sed    //
458203955Srdivacky    // FIXME: Don't hardcode default here.
459221345Sdim
460221345Sdim    // Do not allow conflicts with the iOS simulator target.
461226633Sdim    if (!iOSSimTarget.empty() && (!OSXTarget.empty() || !iOSTarget.empty())) {
462226633Sdim      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
463221345Sdim        << "IOS_SIMULATOR_DEPLOYMENT_TARGET"
464226633Sdim        << (!OSXTarget.empty() ? "MACOSX_DEPLOYMENT_TARGET" :
465221345Sdim            "IPHONEOS_DEPLOYMENT_TARGET");
466221345Sdim    }
467221345Sdim
468221345Sdim    // Allow conflicts among OSX and iOS for historical reasons, but choose the
469221345Sdim    // default platform.
470226633Sdim    if (!OSXTarget.empty() && !iOSTarget.empty()) {
471203955Srdivacky      if (getTriple().getArch() == llvm::Triple::arm ||
472203955Srdivacky          getTriple().getArch() == llvm::Triple::thumb)
473226633Sdim        OSXTarget = "";
474203955Srdivacky      else
475226633Sdim        iOSTarget = "";
476203955Srdivacky    }
477193326Sed
478226633Sdim    if (!OSXTarget.empty()) {
479243830Sdim      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
480212904Sdim      OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
481212904Sdim      Args.append(OSXVersion);
482226633Sdim    } else if (!iOSTarget.empty()) {
483243830Sdim      const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
484221345Sdim      iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget);
485221345Sdim      Args.append(iOSVersion);
486226633Sdim    } else if (!iOSSimTarget.empty()) {
487243830Sdim      const Option O = Opts.getOption(
488221345Sdim        options::OPT_mios_simulator_version_min_EQ);
489221345Sdim      iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
490221345Sdim      Args.append(iOSSimVersion);
491198092Srdivacky    } else {
492210299Sed      // Otherwise, assume we are targeting OS X.
493243830Sdim      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
494212904Sdim      OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
495212904Sdim      Args.append(OSXVersion);
496198092Srdivacky    }
497193326Sed  }
498198092Srdivacky
499221345Sdim  // Reject invalid architecture combinations.
500221345Sdim  if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 &&
501221345Sdim                        getTriple().getArch() != llvm::Triple::x86_64)) {
502226633Sdim    getDriver().Diag(diag::err_drv_invalid_arch_for_deployment_target)
503221345Sdim      << getTriple().getArchName() << iOSSimVersion->getAsString(Args);
504221345Sdim  }
505221345Sdim
506203955Srdivacky  // Set the tool chain target information.
507203955Srdivacky  unsigned Major, Minor, Micro;
508203955Srdivacky  bool HadExtra;
509203955Srdivacky  if (OSXVersion) {
510221345Sdim    assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!");
511243830Sdim    if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor,
512203955Srdivacky                                   Micro, HadExtra) || HadExtra ||
513221345Sdim        Major != 10 || Minor >= 100 || Micro >= 100)
514226633Sdim      getDriver().Diag(diag::err_drv_invalid_version_number)
515203955Srdivacky        << OSXVersion->getAsString(Args);
516203955Srdivacky  } else {
517221345Sdim    const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
518221345Sdim    assert(Version && "Unknown target platform!");
519243830Sdim    if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor,
520203955Srdivacky                                   Micro, HadExtra) || HadExtra ||
521203955Srdivacky        Major >= 10 || Minor >= 100 || Micro >= 100)
522226633Sdim      getDriver().Diag(diag::err_drv_invalid_version_number)
523221345Sdim        << Version->getAsString(Args);
524203955Srdivacky  }
525221345Sdim
526221345Sdim  bool IsIOSSim = bool(iOSSimVersion);
527221345Sdim
528221345Sdim  // In GCC, the simulator historically was treated as being OS X in some
529221345Sdim  // contexts, like determining the link logic, despite generally being called
530221345Sdim  // with an iOS deployment target. For compatibility, we detect the
531221345Sdim  // simulator as iOS + x86, and treat it differently in a few contexts.
532221345Sdim  if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
533221345Sdim                     getTriple().getArch() == llvm::Triple::x86_64))
534221345Sdim    IsIOSSim = true;
535221345Sdim
536221345Sdim  setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim);
537212904Sdim}
538203955Srdivacky
539218893Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
540218893Sdim                                      ArgStringList &CmdArgs) const {
541218893Sdim  CXXStdlibType Type = GetCXXStdlibType(Args);
542218893Sdim
543218893Sdim  switch (Type) {
544218893Sdim  case ToolChain::CST_Libcxx:
545218893Sdim    CmdArgs.push_back("-lc++");
546218893Sdim    break;
547218893Sdim
548218893Sdim  case ToolChain::CST_Libstdcxx: {
549218893Sdim    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
550218893Sdim    // it was previously found in the gcc lib dir. However, for all the Darwin
551218893Sdim    // platforms we care about it was -lstdc++.6, so we search for that
552218893Sdim    // explicitly if we can't see an obvious -lstdc++ candidate.
553218893Sdim
554218893Sdim    // Check in the sysroot first.
555218893Sdim    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
556263508Sdim      SmallString<128> P(A->getValue());
557263508Sdim      llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
558218893Sdim
559263508Sdim      if (!llvm::sys::fs::exists(P.str())) {
560263508Sdim        llvm::sys::path::remove_filename(P);
561263508Sdim        llvm::sys::path::append(P, "libstdc++.6.dylib");
562263508Sdim        if (llvm::sys::fs::exists(P.str())) {
563218893Sdim          CmdArgs.push_back(Args.MakeArgString(P.str()));
564218893Sdim          return;
565218893Sdim        }
566218893Sdim      }
567218893Sdim    }
568218893Sdim
569218893Sdim    // Otherwise, look in the root.
570234353Sdim    // FIXME: This should be removed someday when we don't have to care about
571234353Sdim    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
572263508Sdim    if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") &&
573263508Sdim        llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) {
574218893Sdim      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
575218893Sdim      return;
576218893Sdim    }
577218893Sdim
578218893Sdim    // Otherwise, let the linker search.
579218893Sdim    CmdArgs.push_back("-lstdc++");
580218893Sdim    break;
581218893Sdim  }
582218893Sdim  }
583218893Sdim}
584218893Sdim
585218893Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args,
586218893Sdim                                   ArgStringList &CmdArgs) const {
587218893Sdim
588218893Sdim  // For Darwin platforms, use the compiler-rt-based support library
589218893Sdim  // instead of the gcc-provided one (which is also incidentally
590218893Sdim  // only present in the gcc lib dir, which makes it hard to find).
591218893Sdim
592263508Sdim  SmallString<128> P(getDriver().ResourceDir);
593263508Sdim  llvm::sys::path::append(P, "lib", "darwin");
594223017Sdim
595243830Sdim  // Use the newer cc_kext for iOS ARM after 6.0.
596243830Sdim  if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
597243830Sdim      !isIPhoneOSVersionLT(6, 0)) {
598263508Sdim    llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
599243830Sdim  } else {
600263508Sdim    llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a");
601243830Sdim  }
602243830Sdim
603218893Sdim  // For now, allow missing resource libraries to support developers who may
604218893Sdim  // not have compiler-rt checked out or integrated into their build.
605263508Sdim  if (llvm::sys::fs::exists(P.str()))
606218893Sdim    CmdArgs.push_back(Args.MakeArgString(P.str()));
607218893Sdim}
608218893Sdim
609212904SdimDerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
610212904Sdim                                      const char *BoundArch) const {
611212904Sdim  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
612212904Sdim  const OptTable &Opts = getDriver().getOpts();
613212904Sdim
614212904Sdim  // FIXME: We really want to get out of the tool chain level argument
615212904Sdim  // translation business, as it makes the driver functionality much
616212904Sdim  // more opaque. For now, we follow gcc closely solely for the
617212904Sdim  // purpose of easily achieving feature parity & testability. Once we
618212904Sdim  // have something that works, we should reevaluate each translation
619212904Sdim  // and try to push it down into tool specific logic.
620212904Sdim
621210299Sed  for (ArgList::const_iterator it = Args.begin(),
622210299Sed         ie = Args.end(); it != ie; ++it) {
623193326Sed    Arg *A = *it;
624193326Sed
625193326Sed    if (A->getOption().matches(options::OPT_Xarch__)) {
626224145Sdim      // Skip this argument unless the architecture matches either the toolchain
627224145Sdim      // triple arch, or the arch being bound.
628243830Sdim      llvm::Triple::ArchType XarchArch =
629243830Sdim        tools::darwin::getArchTypeForDarwinArchName(A->getValue(0));
630243830Sdim      if (!(XarchArch == getArch()  ||
631243830Sdim            (BoundArch && XarchArch ==
632243830Sdim             tools::darwin::getArchTypeForDarwinArchName(BoundArch))))
633193326Sed        continue;
634193326Sed
635218893Sdim      Arg *OriginalArg = A;
636243830Sdim      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
637210299Sed      unsigned Prev = Index;
638193326Sed      Arg *XarchArg = Opts.ParseOneArg(Args, Index);
639198092Srdivacky
640193326Sed      // If the argument parsing failed or more than one argument was
641193326Sed      // consumed, the -Xarch_ argument's parameter tried to consume
642193326Sed      // extra arguments. Emit an error and ignore.
643193326Sed      //
644193326Sed      // We also want to disallow any options which would alter the
645193326Sed      // driver behavior; that isn't going to work in our model. We
646193326Sed      // use isDriverOption() as an approximation, although things
647193326Sed      // like -O4 are going to slip through.
648221345Sdim      if (!XarchArg || Index > Prev + 1) {
649226633Sdim        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
650193326Sed          << A->getAsString(Args);
651193326Sed        continue;
652243830Sdim      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
653226633Sdim        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
654221345Sdim          << A->getAsString(Args);
655221345Sdim        continue;
656193326Sed      }
657193326Sed
658193326Sed      XarchArg->setBaseArg(A);
659193326Sed      A = XarchArg;
660210299Sed
661210299Sed      DAL->AddSynthesizedArg(A);
662218893Sdim
663218893Sdim      // Linker input arguments require custom handling. The problem is that we
664218893Sdim      // have already constructed the phase actions, so we can not treat them as
665218893Sdim      // "input arguments".
666243830Sdim      if (A->getOption().hasFlag(options::LinkerInput)) {
667218893Sdim        // Convert the argument into individual Zlinker_input_args.
668218893Sdim        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
669218893Sdim          DAL->AddSeparateArg(OriginalArg,
670218893Sdim                              Opts.getOption(options::OPT_Zlinker_input),
671243830Sdim                              A->getValue(i));
672223017Sdim
673218893Sdim        }
674218893Sdim        continue;
675218893Sdim      }
676198092Srdivacky    }
677193326Sed
678193326Sed    // Sob. These is strictly gcc compatible for the time being. Apple
679193326Sed    // gcc translates options twice, which means that self-expanding
680193326Sed    // options add duplicates.
681199512Srdivacky    switch ((options::ID) A->getOption().getID()) {
682193326Sed    default:
683193326Sed      DAL->append(A);
684193326Sed      break;
685193326Sed
686193326Sed    case options::OPT_mkernel:
687193326Sed    case options::OPT_fapple_kext:
688193326Sed      DAL->append(A);
689210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
690193326Sed      break;
691198092Srdivacky
692193326Sed    case options::OPT_dependency_file:
693210299Sed      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
694243830Sdim                          A->getValue());
695193326Sed      break;
696193326Sed
697193326Sed    case options::OPT_gfull:
698210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
699210299Sed      DAL->AddFlagArg(A,
700210299Sed               Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
701193326Sed      break;
702193326Sed
703193326Sed    case options::OPT_gused:
704210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
705210299Sed      DAL->AddFlagArg(A,
706210299Sed             Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
707193326Sed      break;
708193326Sed
709193326Sed    case options::OPT_shared:
710210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
711193326Sed      break;
712193326Sed
713193326Sed    case options::OPT_fconstant_cfstrings:
714210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
715193326Sed      break;
716193326Sed
717193326Sed    case options::OPT_fno_constant_cfstrings:
718210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
719193326Sed      break;
720193326Sed
721193326Sed    case options::OPT_Wnonportable_cfstrings:
722210299Sed      DAL->AddFlagArg(A,
723210299Sed                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
724193326Sed      break;
725193326Sed
726193326Sed    case options::OPT_Wno_nonportable_cfstrings:
727210299Sed      DAL->AddFlagArg(A,
728210299Sed                   Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
729193326Sed      break;
730193326Sed
731193326Sed    case options::OPT_fpascal_strings:
732210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
733193326Sed      break;
734193326Sed
735193326Sed    case options::OPT_fno_pascal_strings:
736210299Sed      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
737193326Sed      break;
738193326Sed    }
739193326Sed  }
740193326Sed
741198092Srdivacky  if (getTriple().getArch() == llvm::Triple::x86 ||
742198092Srdivacky      getTriple().getArch() == llvm::Triple::x86_64)
743199512Srdivacky    if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
744210299Sed      DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2");
745198092Srdivacky
746198092Srdivacky  // Add the arch options based on the particular spelling of -arch, to match
747198092Srdivacky  // how the driver driver works.
748198092Srdivacky  if (BoundArch) {
749226633Sdim    StringRef Name = BoundArch;
750243830Sdim    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
751243830Sdim    const Option MArch = Opts.getOption(options::OPT_march_EQ);
752198092Srdivacky
753198092Srdivacky    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
754198092Srdivacky    // which defines the list of which architectures we accept.
755198092Srdivacky    if (Name == "ppc")
756198092Srdivacky      ;
757198092Srdivacky    else if (Name == "ppc601")
758210299Sed      DAL->AddJoinedArg(0, MCpu, "601");
759198092Srdivacky    else if (Name == "ppc603")
760210299Sed      DAL->AddJoinedArg(0, MCpu, "603");
761198092Srdivacky    else if (Name == "ppc604")
762210299Sed      DAL->AddJoinedArg(0, MCpu, "604");
763198092Srdivacky    else if (Name == "ppc604e")
764210299Sed      DAL->AddJoinedArg(0, MCpu, "604e");
765198092Srdivacky    else if (Name == "ppc750")
766210299Sed      DAL->AddJoinedArg(0, MCpu, "750");
767198092Srdivacky    else if (Name == "ppc7400")
768210299Sed      DAL->AddJoinedArg(0, MCpu, "7400");
769198092Srdivacky    else if (Name == "ppc7450")
770210299Sed      DAL->AddJoinedArg(0, MCpu, "7450");
771198092Srdivacky    else if (Name == "ppc970")
772210299Sed      DAL->AddJoinedArg(0, MCpu, "970");
773198092Srdivacky
774263508Sdim    else if (Name == "ppc64" || Name == "ppc64le")
775210299Sed      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
776193326Sed
777198092Srdivacky    else if (Name == "i386")
778198092Srdivacky      ;
779198092Srdivacky    else if (Name == "i486")
780210299Sed      DAL->AddJoinedArg(0, MArch, "i486");
781198092Srdivacky    else if (Name == "i586")
782210299Sed      DAL->AddJoinedArg(0, MArch, "i586");
783198092Srdivacky    else if (Name == "i686")
784210299Sed      DAL->AddJoinedArg(0, MArch, "i686");
785198092Srdivacky    else if (Name == "pentium")
786210299Sed      DAL->AddJoinedArg(0, MArch, "pentium");
787198092Srdivacky    else if (Name == "pentium2")
788210299Sed      DAL->AddJoinedArg(0, MArch, "pentium2");
789198092Srdivacky    else if (Name == "pentpro")
790210299Sed      DAL->AddJoinedArg(0, MArch, "pentiumpro");
791198092Srdivacky    else if (Name == "pentIIm3")
792210299Sed      DAL->AddJoinedArg(0, MArch, "pentium2");
793193326Sed
794198092Srdivacky    else if (Name == "x86_64")
795210299Sed      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
796263508Sdim    else if (Name == "x86_64h") {
797263508Sdim      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
798263508Sdim      DAL->AddJoinedArg(0, MArch, "x86_64h");
799263508Sdim    }
800198092Srdivacky
801198092Srdivacky    else if (Name == "arm")
802210299Sed      DAL->AddJoinedArg(0, MArch, "armv4t");
803198092Srdivacky    else if (Name == "armv4t")
804210299Sed      DAL->AddJoinedArg(0, MArch, "armv4t");
805198092Srdivacky    else if (Name == "armv5")
806210299Sed      DAL->AddJoinedArg(0, MArch, "armv5tej");
807198092Srdivacky    else if (Name == "xscale")
808210299Sed      DAL->AddJoinedArg(0, MArch, "xscale");
809198092Srdivacky    else if (Name == "armv6")
810210299Sed      DAL->AddJoinedArg(0, MArch, "armv6k");
811249423Sdim    else if (Name == "armv6m")
812249423Sdim      DAL->AddJoinedArg(0, MArch, "armv6m");
813198092Srdivacky    else if (Name == "armv7")
814210299Sed      DAL->AddJoinedArg(0, MArch, "armv7a");
815249423Sdim    else if (Name == "armv7em")
816249423Sdim      DAL->AddJoinedArg(0, MArch, "armv7em");
817243830Sdim    else if (Name == "armv7f")
818243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7f");
819243830Sdim    else if (Name == "armv7k")
820243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7k");
821249423Sdim    else if (Name == "armv7m")
822249423Sdim      DAL->AddJoinedArg(0, MArch, "armv7m");
823243830Sdim    else if (Name == "armv7s")
824243830Sdim      DAL->AddJoinedArg(0, MArch, "armv7s");
825198092Srdivacky
826198092Srdivacky    else
827200583Srdivacky      llvm_unreachable("invalid Darwin arch");
828198092Srdivacky  }
829198092Srdivacky
830212904Sdim  // Add an explicit version min argument for the deployment target. We do this
831212904Sdim  // after argument translation because -Xarch_ arguments may add a version min
832212904Sdim  // argument.
833239462Sdim  if (BoundArch)
834239462Sdim    AddDeploymentTarget(*DAL);
835212904Sdim
836243830Sdim  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
837243830Sdim  // FIXME: It would be far better to avoid inserting those -static arguments,
838243830Sdim  // but we can't check the deployment target in the translation code until
839243830Sdim  // it is set here.
840243830Sdim  if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) {
841243830Sdim    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
842243830Sdim      Arg *A = *it;
843243830Sdim      ++it;
844243830Sdim      if (A->getOption().getID() != options::OPT_mkernel &&
845243830Sdim          A->getOption().getID() != options::OPT_fapple_kext)
846243830Sdim        continue;
847243830Sdim      assert(it != ie && "unexpected argument translation");
848243830Sdim      A = *it;
849243830Sdim      assert(A->getOption().getID() == options::OPT_static &&
850243830Sdim             "missing expected -static argument");
851243830Sdim      it = DAL->getArgs().erase(it);
852243830Sdim    }
853243830Sdim  }
854243830Sdim
855263508Sdim  // Default to use libc++ on OS X 10.9+ and iOS 7+.
856263508Sdim  if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
857263508Sdim       (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) &&
858263508Sdim      !Args.getLastArg(options::OPT_stdlib_EQ))
859263508Sdim    DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++");
860263508Sdim
861226633Sdim  // Validate the C++ standard library choice.
862226633Sdim  CXXStdlibType Type = GetCXXStdlibType(*DAL);
863226633Sdim  if (Type == ToolChain::CST_Libcxx) {
864239462Sdim    // Check whether the target provides libc++.
865239462Sdim    StringRef where;
866239462Sdim
867239462Sdim    // Complain about targetting iOS < 5.0 in any way.
868243830Sdim    if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))
869243830Sdim      where = "iOS 5.0";
870239462Sdim
871239462Sdim    if (where != StringRef()) {
872226633Sdim      getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
873239462Sdim        << where;
874226633Sdim    }
875226633Sdim  }
876226633Sdim
877193326Sed  return DAL;
878198092Srdivacky}
879193326Sed
880198092Srdivackybool Darwin::IsUnwindTablesDefault() const {
881243830Sdim  return getArch() == llvm::Triple::x86_64;
882193326Sed}
883193326Sed
884201361Srdivackybool Darwin::UseDwarfDebugFlags() const {
885201361Srdivacky  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
886201361Srdivacky    return S[0] != '\0';
887201361Srdivacky  return false;
888201361Srdivacky}
889201361Srdivacky
890203955Srdivackybool Darwin::UseSjLjExceptions() const {
891203955Srdivacky  // Darwin uses SjLj exceptions on ARM.
892203955Srdivacky  return (getTriple().getArch() == llvm::Triple::arm ||
893203955Srdivacky          getTriple().getArch() == llvm::Triple::thumb);
894203955Srdivacky}
895203955Srdivacky
896243830Sdimbool Darwin::isPICDefault() const {
897243830Sdim  return true;
898193326Sed}
899193326Sed
900251662Sdimbool Darwin::isPIEDefault() const {
901251662Sdim  return false;
902251662Sdim}
903251662Sdim
904243830Sdimbool Darwin::isPICDefaultForced() const {
905243830Sdim  return getArch() == llvm::Triple::x86_64;
906193326Sed}
907193326Sed
908221345Sdimbool Darwin::SupportsProfiling() const {
909221345Sdim  // Profiling instrumentation is only supported on x86.
910243830Sdim  return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
911221345Sdim}
912221345Sdim
913207619Srdivackybool Darwin::SupportsObjCGC() const {
914207619Srdivacky  // Garbage collection is supported everywhere except on iPhone OS.
915207619Srdivacky  return !isTargetIPhoneOS();
916207619Srdivacky}
917207619Srdivacky
918243830Sdimvoid Darwin::CheckObjCARC() const {
919243830Sdim  if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
920243830Sdim    return;
921243830Sdim  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
922234353Sdim}
923234353Sdim
924212904Sdimstd::string
925226633SdimDarwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args,
926226633Sdim                                                types::ID InputType) const {
927226633Sdim  return ComputeLLVMTriple(Args, InputType);
928212904Sdim}
929212904Sdim
930193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform
931193326Sed/// all subcommands; this relies on gcc translating the majority of
932193326Sed/// command line options.
933193326Sed
934234353Sdim/// \brief Parse a GCCVersion object out of a string of text.
935234353Sdim///
936234353Sdim/// This is the primary means of forming GCCVersion objects.
937234353Sdim/*static*/
938234353SdimGeneric_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
939263508Sdim  const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
940234353Sdim  std::pair<StringRef, StringRef> First = VersionText.split('.');
941234353Sdim  std::pair<StringRef, StringRef> Second = First.second.split('.');
942234353Sdim
943263508Sdim  GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
944234353Sdim  if (First.first.getAsInteger(10, GoodVersion.Major) ||
945234353Sdim      GoodVersion.Major < 0)
946234353Sdim    return BadVersion;
947263508Sdim  GoodVersion.MajorStr = First.first.str();
948234353Sdim  if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
949234353Sdim      GoodVersion.Minor < 0)
950234353Sdim    return BadVersion;
951263508Sdim  GoodVersion.MinorStr = Second.first.str();
952234353Sdim
953234353Sdim  // First look for a number prefix and parse that if present. Otherwise just
954234353Sdim  // stash the entire patch string in the suffix, and leave the number
955234353Sdim  // unspecified. This covers versions strings such as:
956234353Sdim  //   4.4
957234353Sdim  //   4.4.0
958234353Sdim  //   4.4.x
959234353Sdim  //   4.4.2-rc4
960234353Sdim  //   4.4.x-patched
961234353Sdim  // And retains any patch number it finds.
962234353Sdim  StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
963234353Sdim  if (!PatchText.empty()) {
964249423Sdim    if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
965234353Sdim      // Try to parse the number and any suffix.
966234353Sdim      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
967234353Sdim          GoodVersion.Patch < 0)
968234353Sdim        return BadVersion;
969263508Sdim      GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
970234353Sdim    }
971234353Sdim  }
972234353Sdim
973234353Sdim  return GoodVersion;
974234353Sdim}
975234353Sdim
976234353Sdim/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
977263508Sdimbool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
978263508Sdim                                          int RHSPatch,
979263508Sdim                                          StringRef RHSPatchSuffix) const {
980263508Sdim  if (Major != RHSMajor)
981263508Sdim    return Major < RHSMajor;
982263508Sdim  if (Minor != RHSMinor)
983263508Sdim    return Minor < RHSMinor;
984263508Sdim  if (Patch != RHSPatch) {
985249423Sdim    // Note that versions without a specified patch sort higher than those with
986249423Sdim    // a patch.
987263508Sdim    if (RHSPatch == -1)
988249423Sdim      return true;
989249423Sdim    if (Patch == -1)
990249423Sdim      return false;
991234353Sdim
992249423Sdim    // Otherwise just sort on the patch itself.
993263508Sdim    return Patch < RHSPatch;
994249423Sdim  }
995263508Sdim  if (PatchSuffix != RHSPatchSuffix) {
996249423Sdim    // Sort empty suffixes higher.
997263508Sdim    if (RHSPatchSuffix.empty())
998249423Sdim      return true;
999249423Sdim    if (PatchSuffix.empty())
1000249423Sdim      return false;
1001234353Sdim
1002249423Sdim    // Provide a lexicographic sort to make this a total ordering.
1003263508Sdim    return PatchSuffix < RHSPatchSuffix;
1004249423Sdim  }
1005249423Sdim
1006249423Sdim  // The versions are equal.
1007234353Sdim  return false;
1008234353Sdim}
1009234353Sdim
1010234353Sdimstatic StringRef getGCCToolchainDir(const ArgList &Args) {
1011234353Sdim  const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
1012234353Sdim  if (A)
1013243830Sdim    return A->getValue();
1014234353Sdim  return GCC_INSTALL_PREFIX;
1015234353Sdim}
1016234353Sdim
1017259157Sdim/// \brief Initialize a GCCInstallationDetector from the driver.
1018234353Sdim///
1019234353Sdim/// This performs all of the autodetection and sets up the various paths.
1020234982Sdim/// Once constructed, a GCCInstallationDetector is essentially immutable.
1021234353Sdim///
1022234353Sdim/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1023234353Sdim/// should instead pull the target out of the driver. This is currently
1024234353Sdim/// necessary because the driver doesn't store the final version of the target
1025234353Sdim/// triple.
1026259157Sdimvoid
1027259157SdimGeneric_GCC::GCCInstallationDetector::init(
1028263508Sdim    const llvm::Triple &TargetTriple, const ArgList &Args) {
1029263508Sdim  llvm::Triple BiarchVariantTriple =
1030263508Sdim      TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
1031234353Sdim                                 : TargetTriple.get32BitArchVariant();
1032234353Sdim  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
1033234353Sdim  // The library directories which may contain GCC installations.
1034263508Sdim  SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
1035234353Sdim  // The compatible GCC triples for this particular architecture.
1036234353Sdim  SmallVector<StringRef, 10> CandidateTripleAliases;
1037263508Sdim  SmallVector<StringRef, 10> CandidateBiarchTripleAliases;
1038263508Sdim  CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
1039263508Sdim                           CandidateTripleAliases, CandidateBiarchLibDirs,
1040263508Sdim                           CandidateBiarchTripleAliases);
1041234353Sdim
1042234353Sdim  // Compute the set of prefixes for our search.
1043234353Sdim  SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1044234353Sdim                                       D.PrefixDirs.end());
1045234353Sdim
1046234353Sdim  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1047234353Sdim  if (GCCToolchainDir != "") {
1048234353Sdim    if (GCCToolchainDir.back() == '/')
1049234353Sdim      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
1050234353Sdim
1051234353Sdim    Prefixes.push_back(GCCToolchainDir);
1052234353Sdim  } else {
1053263508Sdim    // If we have a SysRoot, try that first.
1054263508Sdim    if (!D.SysRoot.empty()) {
1055263508Sdim      Prefixes.push_back(D.SysRoot);
1056263508Sdim      Prefixes.push_back(D.SysRoot + "/usr");
1057263508Sdim    }
1058263508Sdim
1059263508Sdim    // Then look for gcc installed alongside clang.
1060234353Sdim    Prefixes.push_back(D.InstalledDir + "/..");
1061263508Sdim
1062263508Sdim    // And finally in /usr.
1063263508Sdim    if (D.SysRoot.empty())
1064263508Sdim      Prefixes.push_back("/usr");
1065234353Sdim  }
1066234353Sdim
1067234353Sdim  // Loop over the various components which exist and select the best GCC
1068234353Sdim  // installation available. GCC installs are ranked by version number.
1069234353Sdim  Version = GCCVersion::Parse("0.0.0");
1070234353Sdim  for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) {
1071234353Sdim    if (!llvm::sys::fs::exists(Prefixes[i]))
1072234353Sdim      continue;
1073234353Sdim    for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) {
1074234353Sdim      const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str();
1075234353Sdim      if (!llvm::sys::fs::exists(LibDir))
1076234353Sdim        continue;
1077234353Sdim      for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
1078243830Sdim        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
1079243830Sdim                               CandidateTripleAliases[k]);
1080234353Sdim    }
1081263508Sdim    for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) {
1082263508Sdim      const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str();
1083234353Sdim      if (!llvm::sys::fs::exists(LibDir))
1084234353Sdim        continue;
1085263508Sdim      for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke;
1086234353Sdim           ++k)
1087243830Sdim        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
1088263508Sdim                               CandidateBiarchTripleAliases[k],
1089263508Sdim                               /*NeedsBiarchSuffix=*/ true);
1090234353Sdim    }
1091234353Sdim  }
1092234353Sdim}
1093234353Sdim
1094263508Sdimvoid Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
1095263508Sdim  for (std::set<std::string>::const_iterator
1096263508Sdim           I = CandidateGCCInstallPaths.begin(),
1097263508Sdim           E = CandidateGCCInstallPaths.end();
1098263508Sdim       I != E; ++I)
1099263508Sdim    OS << "Found candidate GCC installation: " << *I << "\n";
1100263508Sdim
1101263508Sdim  OS << "Selected GCC installation: " << GCCInstallPath << "\n";
1102263508Sdim}
1103263508Sdim
1104234353Sdim/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
1105263508Sdim    const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
1106234353Sdim    SmallVectorImpl<StringRef> &LibDirs,
1107234353Sdim    SmallVectorImpl<StringRef> &TripleAliases,
1108263508Sdim    SmallVectorImpl<StringRef> &BiarchLibDirs,
1109263508Sdim    SmallVectorImpl<StringRef> &BiarchTripleAliases) {
1110234353Sdim  // Declare a bunch of static data sets that we'll select between below. These
1111234353Sdim  // are specifically designed to always refer to string literals to avoid any
1112234353Sdim  // lifetime or initialization issues.
1113249423Sdim  static const char *const AArch64LibDirs[] = { "/lib" };
1114263508Sdim  static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu",
1115263508Sdim                                                "aarch64-linux-gnu" };
1116249423Sdim
1117234353Sdim  static const char *const ARMLibDirs[] = { "/lib" };
1118263508Sdim  static const char *const ARMTriples[] = { "arm-linux-gnueabi",
1119263508Sdim                                            "arm-linux-androideabi" };
1120263508Sdim  static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf",
1121263508Sdim                                              "armv7hl-redhat-linux-gnueabi" };
1122234353Sdim
1123234353Sdim  static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
1124234353Sdim  static const char *const X86_64Triples[] = {
1125263508Sdim    "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
1126263508Sdim    "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
1127263508Sdim    "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux"
1128234353Sdim  };
1129234353Sdim  static const char *const X86LibDirs[] = { "/lib32", "/lib" };
1130234353Sdim  static const char *const X86Triples[] = {
1131263508Sdim    "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
1132263508Sdim    "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux",
1133263508Sdim    "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux",
1134239462Sdim    "i686-montavista-linux"
1135234353Sdim  };
1136234353Sdim
1137234353Sdim  static const char *const MIPSLibDirs[] = { "/lib" };
1138263508Sdim  static const char *const MIPSTriples[] = { "mips-linux-gnu",
1139263508Sdim                                             "mips-mti-linux-gnu" };
1140234353Sdim  static const char *const MIPSELLibDirs[] = { "/lib" };
1141263508Sdim  static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
1142263508Sdim                                               "mipsel-linux-android" };
1143234353Sdim
1144239462Sdim  static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
1145263508Sdim  static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
1146263508Sdim                                               "mips-mti-linux-gnu" };
1147239462Sdim  static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
1148263508Sdim  static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
1149263508Sdim                                                 "mips-mti-linux-gnu" };
1150239462Sdim
1151234353Sdim  static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
1152234353Sdim  static const char *const PPCTriples[] = {
1153263508Sdim    "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
1154263508Sdim    "powerpc-suse-linux", "powerpc-montavista-linuxspe"
1155234353Sdim  };
1156234353Sdim  static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
1157263508Sdim  static const char *const PPC64Triples[] = { "powerpc64-linux-gnu",
1158263508Sdim                                              "powerpc64-unknown-linux-gnu",
1159263508Sdim                                              "powerpc64-suse-linux",
1160263508Sdim                                              "ppc64-redhat-linux" };
1161263508Sdim  static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" };
1162263508Sdim  static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu",
1163263508Sdim                                                "powerpc64le-unknown-linux-gnu",
1164263508Sdim                                                "powerpc64le-suse-linux",
1165263508Sdim                                                "ppc64le-redhat-linux" };
1166234353Sdim
1167263763Sdim  static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" };
1168263763Sdim  static const char *const SPARCv8Triples[] = { "sparc-linux-gnu",
1169263763Sdim                                                "sparcv8-linux-gnu" };
1170263763Sdim  static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" };
1171263763Sdim  static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu",
1172263763Sdim                                                "sparcv9-linux-gnu" };
1173263763Sdim
1174251662Sdim  static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
1175251662Sdim  static const char *const SystemZTriples[] = {
1176263508Sdim    "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
1177263508Sdim    "s390x-suse-linux", "s390x-redhat-linux"
1178251662Sdim  };
1179251662Sdim
1180234353Sdim  switch (TargetTriple.getArch()) {
1181249423Sdim  case llvm::Triple::aarch64:
1182263508Sdim    LibDirs.append(AArch64LibDirs,
1183263508Sdim                   AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
1184263508Sdim    TripleAliases.append(AArch64Triples,
1185263508Sdim                         AArch64Triples + llvm::array_lengthof(AArch64Triples));
1186263508Sdim    BiarchLibDirs.append(AArch64LibDirs,
1187263508Sdim                         AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
1188263508Sdim    BiarchTripleAliases.append(
1189263508Sdim        AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
1190249423Sdim    break;
1191234353Sdim  case llvm::Triple::arm:
1192234353Sdim  case llvm::Triple::thumb:
1193234353Sdim    LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
1194239462Sdim    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
1195263508Sdim      TripleAliases.append(ARMHFTriples,
1196263508Sdim                           ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
1197239462Sdim    } else {
1198263508Sdim      TripleAliases.append(ARMTriples,
1199263508Sdim                           ARMTriples + llvm::array_lengthof(ARMTriples));
1200239462Sdim    }
1201234353Sdim    break;
1202234353Sdim  case llvm::Triple::x86_64:
1203263508Sdim    LibDirs.append(X86_64LibDirs,
1204263508Sdim                   X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
1205263508Sdim    TripleAliases.append(X86_64Triples,
1206263508Sdim                         X86_64Triples + llvm::array_lengthof(X86_64Triples));
1207263508Sdim    BiarchLibDirs.append(X86LibDirs,
1208263508Sdim                         X86LibDirs + llvm::array_lengthof(X86LibDirs));
1209263508Sdim    BiarchTripleAliases.append(X86Triples,
1210263508Sdim                               X86Triples + llvm::array_lengthof(X86Triples));
1211234353Sdim    break;
1212234353Sdim  case llvm::Triple::x86:
1213234353Sdim    LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
1214263508Sdim    TripleAliases.append(X86Triples,
1215263508Sdim                         X86Triples + llvm::array_lengthof(X86Triples));
1216263508Sdim    BiarchLibDirs.append(X86_64LibDirs,
1217263508Sdim                         X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
1218263508Sdim    BiarchTripleAliases.append(
1219263508Sdim        X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
1220234353Sdim    break;
1221234353Sdim  case llvm::Triple::mips:
1222263508Sdim    LibDirs.append(MIPSLibDirs,
1223263508Sdim                   MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
1224263508Sdim    TripleAliases.append(MIPSTriples,
1225263508Sdim                         MIPSTriples + llvm::array_lengthof(MIPSTriples));
1226263508Sdim    BiarchLibDirs.append(MIPS64LibDirs,
1227263508Sdim                         MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
1228263508Sdim    BiarchTripleAliases.append(
1229263508Sdim        MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
1230234353Sdim    break;
1231234353Sdim  case llvm::Triple::mipsel:
1232263508Sdim    LibDirs.append(MIPSELLibDirs,
1233263508Sdim                   MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
1234263508Sdim    TripleAliases.append(MIPSELTriples,
1235263508Sdim                         MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
1236263508Sdim    TripleAliases.append(MIPSTriples,
1237263508Sdim                         MIPSTriples + llvm::array_lengthof(MIPSTriples));
1238263508Sdim    BiarchLibDirs.append(
1239263508Sdim        MIPS64ELLibDirs,
1240263508Sdim        MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
1241263508Sdim    BiarchTripleAliases.append(
1242263508Sdim        MIPS64ELTriples,
1243263508Sdim        MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
1244234353Sdim    break;
1245239462Sdim  case llvm::Triple::mips64:
1246263508Sdim    LibDirs.append(MIPS64LibDirs,
1247263508Sdim                   MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
1248263508Sdim    TripleAliases.append(MIPS64Triples,
1249263508Sdim                         MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
1250263508Sdim    BiarchLibDirs.append(MIPSLibDirs,
1251263508Sdim                         MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
1252263508Sdim    BiarchTripleAliases.append(MIPSTriples,
1253263508Sdim                               MIPSTriples + llvm::array_lengthof(MIPSTriples));
1254239462Sdim    break;
1255239462Sdim  case llvm::Triple::mips64el:
1256263508Sdim    LibDirs.append(MIPS64ELLibDirs,
1257263508Sdim                   MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
1258239462Sdim    TripleAliases.append(
1259263508Sdim        MIPS64ELTriples,
1260263508Sdim        MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
1261263508Sdim    BiarchLibDirs.append(MIPSELLibDirs,
1262263508Sdim                         MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
1263263508Sdim    BiarchTripleAliases.append(
1264263508Sdim        MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
1265263508Sdim    BiarchTripleAliases.append(
1266263508Sdim        MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
1267239462Sdim    break;
1268234353Sdim  case llvm::Triple::ppc:
1269234353Sdim    LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
1270263508Sdim    TripleAliases.append(PPCTriples,
1271263508Sdim                         PPCTriples + llvm::array_lengthof(PPCTriples));
1272263508Sdim    BiarchLibDirs.append(PPC64LibDirs,
1273263508Sdim                         PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
1274263508Sdim    BiarchTripleAliases.append(
1275263508Sdim        PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
1276234353Sdim    break;
1277234353Sdim  case llvm::Triple::ppc64:
1278263508Sdim    LibDirs.append(PPC64LibDirs,
1279263508Sdim                   PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
1280263508Sdim    TripleAliases.append(PPC64Triples,
1281263508Sdim                         PPC64Triples + llvm::array_lengthof(PPC64Triples));
1282263508Sdim    BiarchLibDirs.append(PPCLibDirs,
1283263508Sdim                         PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
1284263508Sdim    BiarchTripleAliases.append(PPCTriples,
1285263508Sdim                               PPCTriples + llvm::array_lengthof(PPCTriples));
1286234353Sdim    break;
1287263508Sdim  case llvm::Triple::ppc64le:
1288263508Sdim    LibDirs.append(PPC64LELibDirs,
1289263508Sdim                   PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs));
1290263508Sdim    TripleAliases.append(PPC64LETriples,
1291263508Sdim                         PPC64LETriples + llvm::array_lengthof(PPC64LETriples));
1292263508Sdim    break;
1293263763Sdim  case llvm::Triple::sparc:
1294263763Sdim    LibDirs.append(SPARCv8LibDirs,
1295263763Sdim                   SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
1296263763Sdim    TripleAliases.append(SPARCv8Triples,
1297263763Sdim                         SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
1298263763Sdim    BiarchLibDirs.append(SPARCv9LibDirs,
1299263763Sdim                         SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
1300263763Sdim    BiarchTripleAliases.append(
1301263763Sdim        SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
1302263763Sdim    break;
1303263763Sdim  case llvm::Triple::sparcv9:
1304263763Sdim    LibDirs.append(SPARCv9LibDirs,
1305263763Sdim                   SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
1306263763Sdim    TripleAliases.append(SPARCv9Triples,
1307263763Sdim                         SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
1308263763Sdim    BiarchLibDirs.append(SPARCv8LibDirs,
1309263763Sdim                         SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
1310263763Sdim    BiarchTripleAliases.append(
1311263763Sdim        SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
1312263763Sdim    break;
1313251662Sdim  case llvm::Triple::systemz:
1314263508Sdim    LibDirs.append(SystemZLibDirs,
1315263508Sdim                   SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
1316263508Sdim    TripleAliases.append(SystemZTriples,
1317263508Sdim                         SystemZTriples + llvm::array_lengthof(SystemZTriples));
1318251662Sdim    break;
1319234353Sdim
1320234353Sdim  default:
1321234353Sdim    // By default, just rely on the standard lib directories and the original
1322234353Sdim    // triple.
1323234353Sdim    break;
1324234353Sdim  }
1325234353Sdim
1326234353Sdim  // Always append the drivers target triple to the end, in case it doesn't
1327234353Sdim  // match any of our aliases.
1328234353Sdim  TripleAliases.push_back(TargetTriple.str());
1329234353Sdim
1330234353Sdim  // Also include the multiarch variant if it's different.
1331263508Sdim  if (TargetTriple.str() != BiarchTriple.str())
1332263508Sdim    BiarchTripleAliases.push_back(BiarchTriple.str());
1333234353Sdim}
1334234353Sdim
1335251662Sdimstatic bool isSoftFloatABI(const ArgList &Args) {
1336251662Sdim  Arg *A = Args.getLastArg(options::OPT_msoft_float,
1337251662Sdim                           options::OPT_mhard_float,
1338251662Sdim                           options::OPT_mfloat_abi_EQ);
1339251662Sdim  if (!A) return false;
1340251662Sdim
1341251662Sdim  return A->getOption().matches(options::OPT_msoft_float) ||
1342251662Sdim         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
1343251662Sdim          A->getValue() == StringRef("soft"));
1344251662Sdim}
1345251662Sdim
1346251662Sdimstatic bool isMipsArch(llvm::Triple::ArchType Arch) {
1347251662Sdim  return Arch == llvm::Triple::mips ||
1348251662Sdim         Arch == llvm::Triple::mipsel ||
1349251662Sdim         Arch == llvm::Triple::mips64 ||
1350251662Sdim         Arch == llvm::Triple::mips64el;
1351251662Sdim}
1352251662Sdim
1353251662Sdimstatic bool isMips16(const ArgList &Args) {
1354251662Sdim  Arg *A = Args.getLastArg(options::OPT_mips16,
1355251662Sdim                           options::OPT_mno_mips16);
1356251662Sdim  return A && A->getOption().matches(options::OPT_mips16);
1357251662Sdim}
1358251662Sdim
1359263508Sdimstatic bool isMips32r2(const ArgList &Args) {
1360263508Sdim  Arg *A = Args.getLastArg(options::OPT_march_EQ,
1361263508Sdim                           options::OPT_mcpu_EQ);
1362263508Sdim
1363263508Sdim  return A && A->getValue() == StringRef("mips32r2");
1364263508Sdim}
1365263508Sdim
1366263508Sdimstatic bool isMips64r2(const ArgList &Args) {
1367263508Sdim  Arg *A = Args.getLastArg(options::OPT_march_EQ,
1368263508Sdim                           options::OPT_mcpu_EQ);
1369263508Sdim
1370263508Sdim  return A && A->getValue() == StringRef("mips64r2");
1371263508Sdim}
1372263508Sdim
1373251662Sdimstatic bool isMicroMips(const ArgList &Args) {
1374251662Sdim  Arg *A = Args.getLastArg(options::OPT_mmicromips,
1375251662Sdim                           options::OPT_mno_micromips);
1376251662Sdim  return A && A->getOption().matches(options::OPT_mmicromips);
1377251662Sdim}
1378251662Sdim
1379263508Sdimstatic bool isMipsFP64(const ArgList &Args) {
1380263508Sdim  Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32);
1381263508Sdim  return A && A->getOption().matches(options::OPT_mfp64);
1382263508Sdim}
1383263508Sdim
1384263508Sdimstatic bool isMipsNan2008(const ArgList &Args) {
1385263508Sdim  Arg *A = Args.getLastArg(options::OPT_mnan_EQ);
1386263508Sdim  return A && A->getValue() == StringRef("2008");
1387263508Sdim}
1388263508Sdim
1389243830Sdim// FIXME: There is the same routine in the Tools.cpp.
1390243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) {
1391243830Sdim  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
1392243830Sdim  return A && (A->getValue() == StringRef("n32"));
1393243830Sdim}
1394243830Sdim
1395263508Sdimstatic bool hasCrtBeginObj(Twine Path) {
1396263508Sdim  return llvm::sys::fs::exists(Path + "/crtbegin.o");
1397263508Sdim}
1398263508Sdim
1399263508Sdimstatic bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path,
1400251662Sdim                                   llvm::Triple::ArchType TargetArch,
1401251662Sdim                                   const ArgList &Args) {
1402263508Sdim  // FIXME: This routine was only intended to model bi-arch toolchains which
1403263508Sdim  // use -m32 and -m64 to swap between variants of a target. It shouldn't be
1404263508Sdim  // doing ABI-based builtin location for MIPS.
1405263508Sdim  if (hasMipsN32ABIArg(Args))
1406263508Sdim    Suffix = "/n32";
1407263508Sdim  else if (TargetArch == llvm::Triple::x86_64 ||
1408263508Sdim           TargetArch == llvm::Triple::ppc64 ||
1409263763Sdim           TargetArch == llvm::Triple::sparcv9 ||
1410263508Sdim           TargetArch == llvm::Triple::systemz ||
1411263508Sdim           TargetArch == llvm::Triple::mips64 ||
1412263508Sdim           TargetArch == llvm::Triple::mips64el)
1413263508Sdim    Suffix = "/64";
1414263508Sdim  else
1415263508Sdim    Suffix = "/32";
1416243830Sdim
1417263508Sdim  return hasCrtBeginObj(Path + Suffix);
1418251662Sdim}
1419251662Sdim
1420263508Sdimvoid Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix(
1421263508Sdim    std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path,
1422263508Sdim    const llvm::opt::ArgList &Args) {
1423263508Sdim  if (!isMipsArch(TargetArch))
1424263508Sdim    return;
1425243830Sdim
1426263508Sdim  // Some MIPS toolchains put libraries and object files compiled
1427263508Sdim  // using different options in to the sub-directoris which names
1428263508Sdim  // reflects the flags used for compilation. For example sysroot
1429263508Sdim  // directory might looks like the following examples:
1430263508Sdim  //
1431263508Sdim  // /usr
1432263508Sdim  //   /lib      <= crt*.o files compiled with '-mips32'
1433263508Sdim  // /mips16
1434263508Sdim  //   /usr
1435263508Sdim  //     /lib    <= crt*.o files compiled with '-mips16'
1436263508Sdim  //   /el
1437263508Sdim  //     /usr
1438263508Sdim  //       /lib  <= crt*.o files compiled with '-mips16 -EL'
1439263508Sdim  //
1440263508Sdim  // or
1441263508Sdim  //
1442263508Sdim  // /usr
1443263508Sdim  //   /lib      <= crt*.o files compiled with '-mips32r2'
1444263508Sdim  // /mips16
1445263508Sdim  //   /usr
1446263508Sdim  //     /lib    <= crt*.o files compiled with '-mips32r2 -mips16'
1447263508Sdim  // /mips32
1448263508Sdim  //     /usr
1449263508Sdim  //       /lib  <= crt*.o files compiled with '-mips32'
1450263508Sdim  //
1451263508Sdim  // Unfortunately different toolchains use different and partially
1452263508Sdim  // overlapped naming schemes. So we have to make a trick for detection
1453263508Sdim  // of using toolchain. We lookup a path which unique for each toolchains.
1454243830Sdim
1455263508Sdim  bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float");
1456263508Sdim  bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof");
1457251662Sdim
1458263508Sdim  if (IsMentorToolChain && IsFSFToolChain)
1459263508Sdim    D.Diag(diag::err_drv_unknown_toolchain);
1460251662Sdim
1461263508Sdim  if (IsMentorToolChain) {
1462263508Sdim    if (isMips16(Args))
1463263508Sdim      Suffix += "/mips16";
1464263508Sdim    else if (isMicroMips(Args))
1465263508Sdim      Suffix += "/micromips";
1466263508Sdim
1467263508Sdim    if (isSoftFloatABI(Args))
1468263508Sdim      Suffix += "/soft-float";
1469263508Sdim
1470263508Sdim    if (TargetArch == llvm::Triple::mipsel ||
1471251662Sdim        TargetArch == llvm::Triple::mips64el)
1472263508Sdim      Suffix += "/el";
1473263508Sdim  } else if (IsFSFToolChain) {
1474263508Sdim    if (TargetArch == llvm::Triple::mips ||
1475263508Sdim        TargetArch == llvm::Triple::mipsel) {
1476263508Sdim      if (isMicroMips(Args))
1477263508Sdim        Suffix += "/micromips";
1478263508Sdim      else if (isMips32r2(Args))
1479263508Sdim        Suffix += "";
1480263508Sdim      else
1481263508Sdim        Suffix += "/mips32";
1482251662Sdim
1483263508Sdim      if (isMips16(Args))
1484263508Sdim        Suffix += "/mips16";
1485263508Sdim    } else {
1486263508Sdim      if (isMips64r2(Args))
1487263508Sdim        Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64";
1488263508Sdim      else
1489263508Sdim        Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64";
1490263508Sdim    }
1491251662Sdim
1492263508Sdim    if (TargetArch == llvm::Triple::mipsel ||
1493263508Sdim        TargetArch == llvm::Triple::mips64el)
1494263508Sdim      Suffix += "/el";
1495263508Sdim
1496263508Sdim    if (isSoftFloatABI(Args))
1497263508Sdim      Suffix += "/sof";
1498263508Sdim    else {
1499263508Sdim      if (isMipsFP64(Args))
1500263508Sdim        Suffix += "/fp64";
1501263508Sdim
1502263508Sdim      if (isMipsNan2008(Args))
1503263508Sdim        Suffix += "/nan2008";
1504263508Sdim    }
1505251662Sdim  }
1506251662Sdim
1507263508Sdim  if (!hasCrtBeginObj(Path + Suffix))
1508263508Sdim    Suffix.clear();
1509251662Sdim}
1510251662Sdim
1511234353Sdimvoid Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
1512243830Sdim    llvm::Triple::ArchType TargetArch, const ArgList &Args,
1513263508Sdim    const std::string &LibDir, StringRef CandidateTriple,
1514263508Sdim    bool NeedsBiarchSuffix) {
1515234353Sdim  // There are various different suffixes involving the triple we
1516234353Sdim  // check for. We also record what is necessary to walk from each back
1517234353Sdim  // up to the lib directory.
1518234353Sdim  const std::string LibSuffixes[] = {
1519234353Sdim    "/gcc/" + CandidateTriple.str(),
1520263508Sdim    // Debian puts cross-compilers in gcc-cross
1521263508Sdim    "/gcc-cross/" + CandidateTriple.str(),
1522234353Sdim    "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
1523234353Sdim
1524243830Sdim    // The Freescale PPC SDK has the gcc libraries in
1525243830Sdim    // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
1526243830Sdim    "/" + CandidateTriple.str(),
1527243830Sdim
1528234353Sdim    // Ubuntu has a strange mis-matched pair of triples that this happens to
1529234353Sdim    // match.
1530234353Sdim    // FIXME: It may be worthwhile to generalize this and look for a second
1531234353Sdim    // triple.
1532234353Sdim    "/i386-linux-gnu/gcc/" + CandidateTriple.str()
1533234353Sdim  };
1534234353Sdim  const std::string InstallSuffixes[] = {
1535263508Sdim    "/../../..",    // gcc/
1536263508Sdim    "/../../..",    // gcc-cross/
1537263508Sdim    "/../../../..", // <triple>/gcc/
1538263508Sdim    "/../..",       // <triple>/
1539263508Sdim    "/../../../.."  // i386-linux-gnu/gcc/<triple>/
1540234353Sdim  };
1541234353Sdim  // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
1542263508Sdim  const unsigned NumLibSuffixes =
1543263508Sdim      (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
1544234353Sdim  for (unsigned i = 0; i < NumLibSuffixes; ++i) {
1545234353Sdim    StringRef LibSuffix = LibSuffixes[i];
1546234353Sdim    llvm::error_code EC;
1547234353Sdim    for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
1548234353Sdim         !EC && LI != LE; LI = LI.increment(EC)) {
1549234353Sdim      StringRef VersionText = llvm::sys::path::filename(LI->path());
1550234353Sdim      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
1551263508Sdim      if (CandidateVersion.Major != -1) // Filter obviously bad entries.
1552263508Sdim        if (!CandidateGCCInstallPaths.insert(LI->path()).second)
1553263508Sdim          continue; // Saw this path before; no need to look at it again.
1554263508Sdim      if (CandidateVersion.isOlderThan(4, 1, 1))
1555234353Sdim        continue;
1556234353Sdim      if (CandidateVersion <= Version)
1557234353Sdim        continue;
1558234353Sdim
1559263508Sdim      std::string MIPSABIDirSuffix;
1560263508Sdim      findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args);
1561263508Sdim
1562234353Sdim      // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
1563234353Sdim      // in what would normally be GCCInstallPath and put the 64-bit
1564234353Sdim      // libs in a subdirectory named 64. The simple logic we follow is that
1565234353Sdim      // *if* there is a subdirectory of the right name with crtbegin.o in it,
1566263508Sdim      // we use that. If not, and if not a biarch triple alias, we look for
1567234353Sdim      // crtbegin.o without the subdirectory.
1568251662Sdim
1569263508Sdim      std::string BiarchSuffix;
1570263508Sdim      if (findTargetBiarchSuffix(BiarchSuffix,
1571263508Sdim                                 LI->path() + MIPSABIDirSuffix,
1572263508Sdim                                 TargetArch, Args)) {
1573263508Sdim        GCCBiarchSuffix = BiarchSuffix;
1574263508Sdim      } else if (NeedsBiarchSuffix ||
1575263508Sdim                 !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) {
1576263508Sdim        continue;
1577234353Sdim      } else {
1578263508Sdim        GCCBiarchSuffix.clear();
1579234353Sdim      }
1580234353Sdim
1581234353Sdim      Version = CandidateVersion;
1582234353Sdim      GCCTriple.setTriple(CandidateTriple);
1583234353Sdim      // FIXME: We hack together the directory name here instead of
1584234353Sdim      // using LI to ensure stable path separators across Windows and
1585234353Sdim      // Linux.
1586234353Sdim      GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
1587234353Sdim      GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
1588263508Sdim      GCCMIPSABIDirSuffix = MIPSABIDirSuffix;
1589234353Sdim      IsValid = true;
1590234353Sdim    }
1591234353Sdim  }
1592234353Sdim}
1593234353Sdim
1594234353SdimGeneric_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
1595234353Sdim                         const ArgList &Args)
1596263508Sdim  : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) {
1597212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
1598221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
1599212904Sdim    getProgramPaths().push_back(getDriver().Dir);
1600193326Sed}
1601193326Sed
1602193326SedGeneric_GCC::~Generic_GCC() {
1603193326Sed}
1604193326Sed
1605249423SdimTool *Generic_GCC::getTool(Action::ActionClass AC) const {
1606249423Sdim  switch (AC) {
1607249423Sdim  case Action::PreprocessJobClass:
1608249423Sdim    if (!Preprocess)
1609249423Sdim      Preprocess.reset(new tools::gcc::Preprocess(*this));
1610249423Sdim    return Preprocess.get();
1611249423Sdim  case Action::PrecompileJobClass:
1612249423Sdim    if (!Precompile)
1613249423Sdim      Precompile.reset(new tools::gcc::Precompile(*this));
1614249423Sdim    return Precompile.get();
1615249423Sdim  case Action::CompileJobClass:
1616249423Sdim    if (!Compile)
1617249423Sdim      Compile.reset(new tools::gcc::Compile(*this));
1618249423Sdim    return Compile.get();
1619249423Sdim  default:
1620249423Sdim    return ToolChain::getTool(AC);
1621193326Sed  }
1622249423Sdim}
1623193326Sed
1624249423SdimTool *Generic_GCC::buildAssembler() const {
1625249423Sdim  return new tools::gcc::Assemble(*this);
1626193326Sed}
1627193326Sed
1628249423SdimTool *Generic_GCC::buildLinker() const {
1629249423Sdim  return new tools::gcc::Link(*this);
1630249423Sdim}
1631249423Sdim
1632263508Sdimvoid Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
1633263508Sdim  // Print the information about how we detected the GCC installation.
1634263508Sdim  GCCInstallation.print(OS);
1635263508Sdim}
1636263508Sdim
1637193326Sedbool Generic_GCC::IsUnwindTablesDefault() const {
1638243830Sdim  return getArch() == llvm::Triple::x86_64;
1639193326Sed}
1640193326Sed
1641243830Sdimbool Generic_GCC::isPICDefault() const {
1642243830Sdim  return false;
1643193326Sed}
1644193326Sed
1645251662Sdimbool Generic_GCC::isPIEDefault() const {
1646251662Sdim  return false;
1647251662Sdim}
1648251662Sdim
1649243830Sdimbool Generic_GCC::isPICDefaultForced() const {
1650243830Sdim  return false;
1651193326Sed}
1652243830Sdim
1653266715Sdimvoid Generic_GCC::addClangTargetOptions(const ArgList &DriverArgs,
1654266715Sdim                                        ArgStringList &CC1Args) const {
1655266715Sdim  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
1656266715Sdim  bool UseInitArrayDefault =
1657266715Sdim      getTriple().getArch() == llvm::Triple::aarch64 ||
1658266715Sdim      (getTriple().getOS() == llvm::Triple::Linux && (
1659266715Sdim         !V.isOlderThan(4, 7, 0) ||
1660266715Sdim         getTriple().getEnvironment() == llvm::Triple::Android));
1661266715Sdim
1662266715Sdim  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
1663266715Sdim                         options::OPT_fno_use_init_array,
1664266715Sdim                         UseInitArrayDefault))
1665266715Sdim    CC1Args.push_back("-fuse-init-array");
1666266715Sdim}
1667266715Sdim
1668234353Sdim/// Hexagon Toolchain
1669193326Sed
1670249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) {
1671249423Sdim
1672249423Sdim  // Locate the rest of the toolchain ...
1673249423Sdim  if (strlen(GCC_INSTALL_PREFIX))
1674249423Sdim    return std::string(GCC_INSTALL_PREFIX);
1675249423Sdim
1676249423Sdim  std::string InstallRelDir = InstalledDir + "/../../gnu";
1677249423Sdim  if (llvm::sys::fs::exists(InstallRelDir))
1678249423Sdim    return InstallRelDir;
1679249423Sdim
1680249423Sdim  std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
1681249423Sdim  if (llvm::sys::fs::exists(PrefixRelDir))
1682249423Sdim    return PrefixRelDir;
1683249423Sdim
1684249423Sdim  return InstallRelDir;
1685234353Sdim}
1686234353Sdim
1687249423Sdimstatic void GetHexagonLibraryPaths(
1688249423Sdim  const ArgList &Args,
1689249423Sdim  const std::string Ver,
1690249423Sdim  const std::string MarchString,
1691249423Sdim  const std::string &InstalledDir,
1692249423Sdim  ToolChain::path_list *LibPaths)
1693249423Sdim{
1694249423Sdim  bool buildingLib = Args.hasArg(options::OPT_shared);
1695249423Sdim
1696249423Sdim  //----------------------------------------------------------------------------
1697249423Sdim  // -L Args
1698249423Sdim  //----------------------------------------------------------------------------
1699249423Sdim  for (arg_iterator
1700249423Sdim         it = Args.filtered_begin(options::OPT_L),
1701249423Sdim         ie = Args.filtered_end();
1702249423Sdim       it != ie;
1703249423Sdim       ++it) {
1704249423Sdim    for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
1705249423Sdim      LibPaths->push_back((*it)->getValue(i));
1706249423Sdim  }
1707249423Sdim
1708249423Sdim  //----------------------------------------------------------------------------
1709249423Sdim  // Other standard paths
1710249423Sdim  //----------------------------------------------------------------------------
1711249423Sdim  const std::string MarchSuffix = "/" + MarchString;
1712249423Sdim  const std::string G0Suffix = "/G0";
1713249423Sdim  const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
1714249423Sdim  const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/";
1715249423Sdim
1716249423Sdim  // lib/gcc/hexagon/...
1717249423Sdim  std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
1718249423Sdim  if (buildingLib) {
1719249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
1720249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
1721249423Sdim  }
1722249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
1723249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver);
1724249423Sdim
1725249423Sdim  // lib/gcc/...
1726249423Sdim  LibPaths->push_back(RootDir + "lib/gcc");
1727249423Sdim
1728249423Sdim  // hexagon/lib/...
1729249423Sdim  std::string HexagonLibDir = RootDir + "hexagon/lib";
1730249423Sdim  if (buildingLib) {
1731249423Sdim    LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
1732249423Sdim    LibPaths->push_back(HexagonLibDir + G0Suffix);
1733249423Sdim  }
1734249423Sdim  LibPaths->push_back(HexagonLibDir + MarchSuffix);
1735249423Sdim  LibPaths->push_back(HexagonLibDir);
1736249423Sdim}
1737249423Sdim
1738249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
1739249423Sdim                       const ArgList &Args)
1740249423Sdim  : Linux(D, Triple, Args) {
1741249423Sdim  const std::string InstalledDir(getDriver().getInstalledDir());
1742249423Sdim  const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir);
1743249423Sdim
1744249423Sdim  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
1745249423Sdim  // program paths
1746249423Sdim  const std::string BinDir(GnuDir + "/bin");
1747249423Sdim  if (llvm::sys::fs::exists(BinDir))
1748249423Sdim    getProgramPaths().push_back(BinDir);
1749249423Sdim
1750249423Sdim  // Determine version of GCC libraries and headers to use.
1751249423Sdim  const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
1752249423Sdim  llvm::error_code ec;
1753249423Sdim  GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
1754249423Sdim  for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
1755249423Sdim       !ec && di != de; di = di.increment(ec)) {
1756249423Sdim    GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
1757249423Sdim    if (MaxVersion < cv)
1758249423Sdim      MaxVersion = cv;
1759249423Sdim  }
1760249423Sdim  GCCLibAndIncVersion = MaxVersion;
1761249423Sdim
1762249423Sdim  ToolChain::path_list *LibPaths= &getFilePaths();
1763249423Sdim
1764249423Sdim  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
1765249423Sdim  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
1766249423Sdim  // support 'linux' we'll need to fix this up
1767249423Sdim  LibPaths->clear();
1768249423Sdim
1769249423Sdim  GetHexagonLibraryPaths(
1770249423Sdim    Args,
1771249423Sdim    GetGCCLibAndIncVersion(),
1772249423Sdim    GetTargetCPU(Args),
1773249423Sdim    InstalledDir,
1774249423Sdim    LibPaths);
1775249423Sdim}
1776249423Sdim
1777234353SdimHexagon_TC::~Hexagon_TC() {
1778234353Sdim}
1779234353Sdim
1780249423SdimTool *Hexagon_TC::buildAssembler() const {
1781249423Sdim  return new tools::hexagon::Assemble(*this);
1782249423Sdim}
1783234353Sdim
1784249423SdimTool *Hexagon_TC::buildLinker() const {
1785249423Sdim  return new tools::hexagon::Link(*this);
1786249423Sdim}
1787234353Sdim
1788249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1789249423Sdim                                           ArgStringList &CC1Args) const {
1790249423Sdim  const Driver &D = getDriver();
1791249423Sdim
1792249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
1793249423Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
1794249423Sdim    return;
1795249423Sdim
1796249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1797249423Sdim  std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
1798249423Sdim  std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
1799249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
1800249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
1801249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
1802249423Sdim}
1803249423Sdim
1804249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1805249423Sdim                                              ArgStringList &CC1Args) const {
1806249423Sdim
1807249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1808249423Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1809249423Sdim    return;
1810249423Sdim
1811249423Sdim  const Driver &D = getDriver();
1812249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1813263508Sdim  SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
1814249423Sdim
1815263508Sdim  llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");
1816263508Sdim  llvm::sys::path::append(IncludeDir, Ver);
1817249423Sdim  addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
1818249423Sdim}
1819249423Sdim
1820249423SdimToolChain::CXXStdlibType
1821249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
1822249423Sdim  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1823249423Sdim  if (!A)
1824249423Sdim    return ToolChain::CST_Libstdcxx;
1825249423Sdim
1826249423Sdim  StringRef Value = A->getValue();
1827249423Sdim  if (Value != "libstdc++") {
1828249423Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1829249423Sdim      << A->getAsString(Args);
1830234353Sdim  }
1831234353Sdim
1832249423Sdim  return ToolChain::CST_Libstdcxx;
1833234353Sdim}
1834234353Sdim
1835263508Sdimstatic int getHexagonVersion(const ArgList &Args) {
1836263508Sdim  Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ);
1837263508Sdim  // Select the default CPU (v4) if none was given.
1838263508Sdim  if (!A)
1839263508Sdim    return 4;
1840249423Sdim
1841263508Sdim  // FIXME: produce errors if we cannot parse the version.
1842263508Sdim  StringRef WhichHexagon = A->getValue();
1843263508Sdim  if (WhichHexagon.startswith("hexagonv")) {
1844263508Sdim    int Val;
1845263508Sdim    if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val))
1846263508Sdim      return Val;
1847249423Sdim  }
1848263508Sdim  if (WhichHexagon.startswith("v")) {
1849263508Sdim    int Val;
1850263508Sdim    if (!WhichHexagon.substr(1).getAsInteger(10, Val))
1851263508Sdim      return Val;
1852263508Sdim  }
1853263508Sdim
1854263508Sdim  // FIXME: should probably be an error.
1855263508Sdim  return 4;
1856234353Sdim}
1857234353Sdim
1858249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
1859249423Sdim{
1860263508Sdim  int V = getHexagonVersion(Args);
1861263508Sdim  // FIXME: We don't support versions < 4. We should error on them.
1862263508Sdim  switch (V) {
1863263508Sdim  default:
1864263508Sdim    llvm_unreachable("Unexpected version");
1865263508Sdim  case 5:
1866263508Sdim    return "v5";
1867263508Sdim  case 4:
1868263508Sdim    return "v4";
1869263508Sdim  case 3:
1870263508Sdim    return "v3";
1871263508Sdim  case 2:
1872263508Sdim    return "v2";
1873263508Sdim  case 1:
1874263508Sdim    return "v1";
1875249423Sdim  }
1876234353Sdim}
1877249423Sdim// End Hexagon
1878234353Sdim
1879204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
1880204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
1881204793Srdivacky/// Currently does not support anything else but compilation.
1882204793Srdivacky
1883249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple,
1884249423Sdim                           const ArgList &Args)
1885249423Sdim  : ToolChain(D, Triple, Args) {
1886204793Srdivacky  // Path mangling to find libexec
1887204793Srdivacky  std::string Path(getDriver().Dir);
1888204793Srdivacky
1889204793Srdivacky  Path += "/../libexec";
1890204793Srdivacky  getProgramPaths().push_back(Path);
1891204793Srdivacky}
1892204793Srdivacky
1893204793SrdivackyTCEToolChain::~TCEToolChain() {
1894204793Srdivacky}
1895204793Srdivacky
1896223017Sdimbool TCEToolChain::IsMathErrnoDefault() const {
1897223017Sdim  return true;
1898204793Srdivacky}
1899204793Srdivacky
1900243830Sdimbool TCEToolChain::isPICDefault() const {
1901204793Srdivacky  return false;
1902204793Srdivacky}
1903204793Srdivacky
1904251662Sdimbool TCEToolChain::isPIEDefault() const {
1905251662Sdim  return false;
1906251662Sdim}
1907251662Sdim
1908243830Sdimbool TCEToolChain::isPICDefaultForced() const {
1909243830Sdim  return false;
1910204793Srdivacky}
1911204793Srdivacky
1912195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
1913195341Sed
1914234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1915234353Sdim  : Generic_ELF(D, Triple, Args) {
1916201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
1917195341Sed  getFilePaths().push_back("/usr/lib");
1918195341Sed}
1919195341Sed
1920249423SdimTool *OpenBSD::buildAssembler() const {
1921249423Sdim  return new tools::openbsd::Assemble(*this);
1922249423Sdim}
1923195341Sed
1924249423SdimTool *OpenBSD::buildLinker() const {
1925249423Sdim  return new tools::openbsd::Link(*this);
1926195341Sed}
1927195341Sed
1928239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
1929239462Sdim
1930239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1931239462Sdim  : Generic_ELF(D, Triple, Args) {
1932239462Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
1933239462Sdim  getFilePaths().push_back("/usr/lib");
1934239462Sdim}
1935239462Sdim
1936249423SdimTool *Bitrig::buildAssembler() const {
1937249423Sdim  return new tools::bitrig::Assemble(*this);
1938249423Sdim}
1939239462Sdim
1940249423SdimTool *Bitrig::buildLinker() const {
1941249423Sdim  return new tools::bitrig::Link(*this);
1942239462Sdim}
1943239462Sdim
1944239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1945239462Sdim                                          ArgStringList &CC1Args) const {
1946239462Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1947239462Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1948239462Sdim    return;
1949239462Sdim
1950243830Sdim  switch (GetCXXStdlibType(DriverArgs)) {
1951243830Sdim  case ToolChain::CST_Libcxx:
1952243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1953243830Sdim                     getDriver().SysRoot + "/usr/include/c++/");
1954243830Sdim    break;
1955243830Sdim  case ToolChain::CST_Libstdcxx:
1956243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1957243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++");
1958243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1959243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
1960239462Sdim
1961243830Sdim    StringRef Triple = getTriple().str();
1962243830Sdim    if (Triple.startswith("amd64"))
1963243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1964243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
1965243830Sdim                       Triple.substr(5));
1966243830Sdim    else
1967243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1968243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/" +
1969243830Sdim                       Triple);
1970243830Sdim    break;
1971243830Sdim  }
1972239462Sdim}
1973239462Sdim
1974239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
1975239462Sdim                                 ArgStringList &CmdArgs) const {
1976243830Sdim  switch (GetCXXStdlibType(Args)) {
1977243830Sdim  case ToolChain::CST_Libcxx:
1978243830Sdim    CmdArgs.push_back("-lc++");
1979243830Sdim    CmdArgs.push_back("-lcxxrt");
1980243830Sdim    // Include supc++ to provide Unwind until provided by libcxx.
1981243830Sdim    CmdArgs.push_back("-lgcc");
1982243830Sdim    break;
1983243830Sdim  case ToolChain::CST_Libstdcxx:
1984243830Sdim    CmdArgs.push_back("-lstdc++");
1985243830Sdim    break;
1986243830Sdim  }
1987239462Sdim}
1988239462Sdim
1989193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
1990193326Sed
1991234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1992234353Sdim  : Generic_ELF(D, Triple, Args) {
1993212904Sdim
1994234353Sdim  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
1995234353Sdim  // back to '/usr/lib' if it doesn't exist.
1996234353Sdim  if ((Triple.getArch() == llvm::Triple::x86 ||
1997234353Sdim       Triple.getArch() == llvm::Triple::ppc) &&
1998234982Sdim      llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
1999234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
2000234353Sdim  else
2001234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
2002193326Sed}
2003193326Sed
2004255321StheravenToolChain::CXXStdlibType
2005255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const {
2006255321Stheraven  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2007255321Stheraven    StringRef Value = A->getValue();
2008263508Sdim    if (Value == "libstdc++")
2009263508Sdim      return ToolChain::CST_Libstdcxx;
2010255321Stheraven    if (Value == "libc++")
2011255321Stheraven      return ToolChain::CST_Libcxx;
2012263508Sdim
2013255321Stheraven    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2014255321Stheraven      << A->getAsString(Args);
2015255321Stheraven  }
2016263508Sdim  if (getTriple().getOSMajorVersion() >= 10)
2017263508Sdim    return ToolChain::CST_Libcxx;
2018263508Sdim  return ToolChain::CST_Libstdcxx;
2019255321Stheraven}
2020255321Stheraven
2021255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2022263508Sdim                                           ArgStringList &CC1Args) const {
2023255321Stheraven  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2024255321Stheraven      DriverArgs.hasArg(options::OPT_nostdincxx))
2025255321Stheraven    return;
2026255321Stheraven
2027263508Sdim  switch (GetCXXStdlibType(DriverArgs)) {
2028263508Sdim  case ToolChain::CST_Libcxx:
2029255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
2030255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/v1");
2031263508Sdim    break;
2032263508Sdim  case ToolChain::CST_Libstdcxx:
2033255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
2034255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/4.2");
2035263508Sdim    addSystemInclude(DriverArgs, CC1Args,
2036263508Sdim                     getDriver().SysRoot + "/usr/include/c++/4.2/backward");
2037263508Sdim    break;
2038263508Sdim  }
2039263508Sdim}
2040255321Stheraven
2041263508SdimTool *FreeBSD::buildAssembler() const {
2042263508Sdim  return new tools::freebsd::Assemble(*this);
2043255321Stheraven}
2044255321Stheraven
2045263508SdimTool *FreeBSD::buildLinker() const {
2046263508Sdim  return new tools::freebsd::Link(*this);
2047263508Sdim}
2048263508Sdim
2049263508Sdimbool FreeBSD::UseSjLjExceptions() const {
2050263508Sdim  // FreeBSD uses SjLj exceptions on ARM oabi.
2051263508Sdim  switch (getTriple().getEnvironment()) {
2052263508Sdim  case llvm::Triple::GNUEABI:
2053263508Sdim  case llvm::Triple::EABI:
2054263508Sdim    return false;
2055263508Sdim
2056263508Sdim  default:
2057263508Sdim    return (getTriple().getArch() == llvm::Triple::arm ||
2058263508Sdim            getTriple().getArch() == llvm::Triple::thumb);
2059263508Sdim  }
2060263508Sdim}
2061263508Sdim
2062218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
2063218893Sdim
2064234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2065234353Sdim  : Generic_ELF(D, Triple, Args) {
2066218893Sdim
2067221345Sdim  if (getDriver().UseStdLib) {
2068234353Sdim    // When targeting a 32-bit platform, try the special directory used on
2069234353Sdim    // 64-bit hosts, and only fall back to the main library directory if that
2070234353Sdim    // doesn't work.
2071234353Sdim    // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
2072234353Sdim    // what all logic is needed to emulate the '=' prefix here.
2073234353Sdim    if (Triple.getArch() == llvm::Triple::x86)
2074221345Sdim      getFilePaths().push_back("=/usr/lib/i386");
2075234353Sdim
2076234353Sdim    getFilePaths().push_back("=/usr/lib");
2077218893Sdim  }
2078218893Sdim}
2079218893Sdim
2080249423SdimTool *NetBSD::buildAssembler() const {
2081249423Sdim  return new tools::netbsd::Assemble(*this);
2082249423Sdim}
2083218893Sdim
2084249423SdimTool *NetBSD::buildLinker() const {
2085249423Sdim  return new tools::netbsd::Link(*this);
2086218893Sdim}
2087218893Sdim
2088251662SdimToolChain::CXXStdlibType
2089251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const {
2090251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2091251662Sdim    StringRef Value = A->getValue();
2092251662Sdim    if (Value == "libstdc++")
2093251662Sdim      return ToolChain::CST_Libstdcxx;
2094251662Sdim    if (Value == "libc++")
2095251662Sdim      return ToolChain::CST_Libcxx;
2096251662Sdim
2097251662Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2098251662Sdim      << A->getAsString(Args);
2099251662Sdim  }
2100251662Sdim
2101263508Sdim  unsigned Major, Minor, Micro;
2102263508Sdim  getTriple().getOSVersion(Major, Minor, Micro);
2103263508Sdim  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
2104263508Sdim    if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64)
2105263508Sdim      return ToolChain::CST_Libcxx;
2106263508Sdim  }
2107251662Sdim  return ToolChain::CST_Libstdcxx;
2108251662Sdim}
2109251662Sdim
2110251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2111251662Sdim                                          ArgStringList &CC1Args) const {
2112251662Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2113251662Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
2114251662Sdim    return;
2115251662Sdim
2116251662Sdim  switch (GetCXXStdlibType(DriverArgs)) {
2117251662Sdim  case ToolChain::CST_Libcxx:
2118251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2119251662Sdim                     getDriver().SysRoot + "/usr/include/c++/");
2120251662Sdim    break;
2121251662Sdim  case ToolChain::CST_Libstdcxx:
2122251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2123251662Sdim                     getDriver().SysRoot + "/usr/include/g++");
2124251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2125251662Sdim                     getDriver().SysRoot + "/usr/include/g++/backward");
2126251662Sdim    break;
2127251662Sdim  }
2128251662Sdim}
2129251662Sdim
2130210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
2131210299Sed
2132234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2133234353Sdim  : Generic_ELF(D, Triple, Args) {
2134210299Sed  getFilePaths().push_back(getDriver().Dir + "/../lib");
2135210299Sed  getFilePaths().push_back("/usr/lib");
2136210299Sed}
2137210299Sed
2138249423SdimTool *Minix::buildAssembler() const {
2139249423Sdim  return new tools::minix::Assemble(*this);
2140249423Sdim}
2141210299Sed
2142249423SdimTool *Minix::buildLinker() const {
2143249423Sdim  return new tools::minix::Link(*this);
2144210299Sed}
2145210299Sed
2146198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
2147198092Srdivacky
2148234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
2149234353Sdim                   const ArgList &Args)
2150234353Sdim  : Generic_GCC(D, Triple, Args) {
2151198092Srdivacky
2152212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2153221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2154212904Sdim    getProgramPaths().push_back(getDriver().Dir);
2155198092Srdivacky
2156201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
2157198092Srdivacky  getFilePaths().push_back("/usr/lib");
2158198092Srdivacky  getFilePaths().push_back("/usr/sfw/lib");
2159198092Srdivacky  getFilePaths().push_back("/opt/gcc4/lib");
2160198398Srdivacky  getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
2161198092Srdivacky
2162198092Srdivacky}
2163198092Srdivacky
2164249423SdimTool *AuroraUX::buildAssembler() const {
2165249423Sdim  return new tools::auroraux::Assemble(*this);
2166249423Sdim}
2167198092Srdivacky
2168249423SdimTool *AuroraUX::buildLinker() const {
2169249423Sdim  return new tools::auroraux::Link(*this);
2170198092Srdivacky}
2171198092Srdivacky
2172234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
2173198092Srdivacky
2174234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple,
2175234353Sdim                 const ArgList &Args)
2176234353Sdim  : Generic_GCC(D, Triple, Args) {
2177234353Sdim
2178234353Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2179234353Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2180234353Sdim    getProgramPaths().push_back(getDriver().Dir);
2181234353Sdim
2182234353Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
2183234353Sdim  getFilePaths().push_back("/usr/lib");
2184234353Sdim}
2185234353Sdim
2186249423SdimTool *Solaris::buildAssembler() const {
2187249423Sdim  return new tools::solaris::Assemble(*this);
2188249423Sdim}
2189234353Sdim
2190249423SdimTool *Solaris::buildLinker() const {
2191249423Sdim  return new tools::solaris::Link(*this);
2192234353Sdim}
2193234353Sdim
2194249423Sdim/// Distribution (very bare-bones at the moment).
2195193326Sed
2196249423Sdimenum Distro {
2197219077Sdim  ArchLinux,
2198218893Sdim  DebianLenny,
2199218893Sdim  DebianSqueeze,
2200223017Sdim  DebianWheezy,
2201249423Sdim  DebianJessie,
2202218893Sdim  Exherbo,
2203223017Sdim  RHEL4,
2204223017Sdim  RHEL5,
2205223017Sdim  RHEL6,
2206263508Sdim  Fedora,
2207263508Sdim  OpenSUSE,
2208221345Sdim  UbuntuHardy,
2209221345Sdim  UbuntuIntrepid,
2210218893Sdim  UbuntuJaunty,
2211218893Sdim  UbuntuKarmic,
2212218893Sdim  UbuntuLucid,
2213218893Sdim  UbuntuMaverick,
2214221345Sdim  UbuntuNatty,
2215223017Sdim  UbuntuOneiric,
2216234353Sdim  UbuntuPrecise,
2217244628Sdim  UbuntuQuantal,
2218244628Sdim  UbuntuRaring,
2219263508Sdim  UbuntuSaucy,
2220263508Sdim  UbuntuTrusty,
2221218893Sdim  UnknownDistro
2222218893Sdim};
2223198092Srdivacky
2224249423Sdimstatic bool IsRedhat(enum Distro Distro) {
2225263508Sdim  return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6);
2226218893Sdim}
2227198092Srdivacky
2228263508Sdimstatic bool IsOpenSUSE(enum Distro Distro) {
2229263508Sdim  return Distro == OpenSUSE;
2230193326Sed}
2231193326Sed
2232249423Sdimstatic bool IsDebian(enum Distro Distro) {
2233249423Sdim  return Distro >= DebianLenny && Distro <= DebianJessie;
2234218893Sdim}
2235218893Sdim
2236249423Sdimstatic bool IsUbuntu(enum Distro Distro) {
2237263508Sdim  return Distro >= UbuntuHardy && Distro <= UbuntuTrusty;
2238218893Sdim}
2239218893Sdim
2240249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) {
2241234353Sdim  OwningPtr<llvm::MemoryBuffer> File;
2242218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
2243226633Sdim    StringRef Data = File.get()->getBuffer();
2244226633Sdim    SmallVector<StringRef, 8> Lines;
2245218893Sdim    Data.split(Lines, "\n");
2246249423Sdim    Distro Version = UnknownDistro;
2247234353Sdim    for (unsigned i = 0, s = Lines.size(); i != s; ++i)
2248234353Sdim      if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME="))
2249249423Sdim        Version = llvm::StringSwitch<Distro>(Lines[i].substr(17))
2250234353Sdim          .Case("hardy", UbuntuHardy)
2251234353Sdim          .Case("intrepid", UbuntuIntrepid)
2252234353Sdim          .Case("jaunty", UbuntuJaunty)
2253234353Sdim          .Case("karmic", UbuntuKarmic)
2254234353Sdim          .Case("lucid", UbuntuLucid)
2255234353Sdim          .Case("maverick", UbuntuMaverick)
2256234353Sdim          .Case("natty", UbuntuNatty)
2257234353Sdim          .Case("oneiric", UbuntuOneiric)
2258234353Sdim          .Case("precise", UbuntuPrecise)
2259244628Sdim          .Case("quantal", UbuntuQuantal)
2260244628Sdim          .Case("raring", UbuntuRaring)
2261263508Sdim          .Case("saucy", UbuntuSaucy)
2262263508Sdim          .Case("trusty", UbuntuTrusty)
2263234353Sdim          .Default(UnknownDistro);
2264234353Sdim    return Version;
2265218893Sdim  }
2266218893Sdim
2267218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
2268226633Sdim    StringRef Data = File.get()->getBuffer();
2269263508Sdim    if (Data.startswith("Fedora release"))
2270263508Sdim      return Fedora;
2271223017Sdim    else if (Data.startswith("Red Hat Enterprise Linux") &&
2272226633Sdim             Data.find("release 6") != StringRef::npos)
2273223017Sdim      return RHEL6;
2274223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2275249423Sdim              Data.startswith("CentOS")) &&
2276226633Sdim             Data.find("release 5") != StringRef::npos)
2277223017Sdim      return RHEL5;
2278223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2279249423Sdim              Data.startswith("CentOS")) &&
2280226633Sdim             Data.find("release 4") != StringRef::npos)
2281223017Sdim      return RHEL4;
2282218893Sdim    return UnknownDistro;
2283218893Sdim  }
2284218893Sdim
2285218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
2286226633Sdim    StringRef Data = File.get()->getBuffer();
2287218893Sdim    if (Data[0] == '5')
2288218893Sdim      return DebianLenny;
2289234353Sdim    else if (Data.startswith("squeeze/sid") || Data[0] == '6')
2290218893Sdim      return DebianSqueeze;
2291234353Sdim    else if (Data.startswith("wheezy/sid")  || Data[0] == '7')
2292223017Sdim      return DebianWheezy;
2293249423Sdim    else if (Data.startswith("jessie/sid")  || Data[0] == '8')
2294249423Sdim      return DebianJessie;
2295218893Sdim    return UnknownDistro;
2296218893Sdim  }
2297218893Sdim
2298263508Sdim  if (llvm::sys::fs::exists("/etc/SuSE-release"))
2299263508Sdim    return OpenSUSE;
2300218893Sdim
2301263508Sdim  if (llvm::sys::fs::exists("/etc/exherbo-release"))
2302218893Sdim    return Exherbo;
2303218893Sdim
2304263508Sdim  if (llvm::sys::fs::exists("/etc/arch-release"))
2305219077Sdim    return ArchLinux;
2306219077Sdim
2307218893Sdim  return UnknownDistro;
2308218893Sdim}
2309218893Sdim
2310228379Sdim/// \brief Get our best guess at the multiarch triple for a target.
2311228379Sdim///
2312228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use
2313228379Sdim/// a target-triple directory in the library and header search paths.
2314228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple,
2315228379Sdim/// so we provide a rough mapping here.
2316228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple,
2317228379Sdim                                      StringRef SysRoot) {
2318228379Sdim  // For most architectures, just use whatever we have rather than trying to be
2319228379Sdim  // clever.
2320228379Sdim  switch (TargetTriple.getArch()) {
2321228379Sdim  default:
2322228379Sdim    return TargetTriple.str();
2323226633Sdim
2324228379Sdim    // We use the existence of '/lib/<triple>' as a directory to detect some
2325228379Sdim    // common linux triples that don't quite match the Clang triple for both
2326234353Sdim    // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
2327234353Sdim    // regardless of what the actual target triple is.
2328239462Sdim  case llvm::Triple::arm:
2329239462Sdim  case llvm::Triple::thumb:
2330239462Sdim    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
2331239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
2332239462Sdim        return "arm-linux-gnueabihf";
2333239462Sdim    } else {
2334239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
2335239462Sdim        return "arm-linux-gnueabi";
2336239462Sdim    }
2337239462Sdim    return TargetTriple.str();
2338228379Sdim  case llvm::Triple::x86:
2339228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
2340228379Sdim      return "i386-linux-gnu";
2341228379Sdim    return TargetTriple.str();
2342228379Sdim  case llvm::Triple::x86_64:
2343228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
2344228379Sdim      return "x86_64-linux-gnu";
2345228379Sdim    return TargetTriple.str();
2346249423Sdim  case llvm::Triple::aarch64:
2347249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
2348249423Sdim      return "aarch64-linux-gnu";
2349263508Sdim    return TargetTriple.str();
2350234353Sdim  case llvm::Triple::mips:
2351234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
2352234353Sdim      return "mips-linux-gnu";
2353234353Sdim    return TargetTriple.str();
2354234353Sdim  case llvm::Triple::mipsel:
2355234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
2356234353Sdim      return "mipsel-linux-gnu";
2357234353Sdim    return TargetTriple.str();
2358234353Sdim  case llvm::Triple::ppc:
2359249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
2360249423Sdim      return "powerpc-linux-gnuspe";
2361234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))
2362234353Sdim      return "powerpc-linux-gnu";
2363234353Sdim    return TargetTriple.str();
2364234353Sdim  case llvm::Triple::ppc64:
2365234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))
2366234353Sdim      return "powerpc64-linux-gnu";
2367263508Sdim  case llvm::Triple::ppc64le:
2368263508Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
2369263508Sdim      return "powerpc64le-linux-gnu";
2370234353Sdim    return TargetTriple.str();
2371226633Sdim  }
2372226633Sdim}
2373226633Sdim
2374234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
2375234353Sdim  if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
2376234353Sdim}
2377234353Sdim
2378243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple,
2379243830Sdim                                const ArgList &Args) {
2380263508Sdim  if (isMipsArch(Triple.getArch())) {
2381263508Sdim    // lib32 directory has a special meaning on MIPS targets.
2382263508Sdim    // It contains N32 ABI binaries. Use this folder if produce
2383263508Sdim    // code for N32 ABI only.
2384263508Sdim    if (hasMipsN32ABIArg(Args))
2385263508Sdim      return "lib32";
2386263508Sdim    return Triple.isArch32Bit() ? "lib" : "lib64";
2387263508Sdim  }
2388243830Sdim
2389263508Sdim  // It happens that only x86 and PPC use the 'lib32' variant of multilib, and
2390263508Sdim  // using that variant while targeting other architectures causes problems
2391263508Sdim  // because the libraries are laid out in shared system roots that can't cope
2392263508Sdim  // with a 'lib32' multilib search path being considered. So we only enable
2393263508Sdim  // them when we know we may need it.
2394263508Sdim  //
2395263508Sdim  // FIXME: This is a bit of a hack. We should really unify this code for
2396263508Sdim  // reasoning about multilib spellings with the lib dir spellings in the
2397263508Sdim  // GCCInstallationDetector, but that is a more significant refactoring.
2398263508Sdim  if (Triple.getArch() == llvm::Triple::x86 ||
2399263508Sdim      Triple.getArch() == llvm::Triple::ppc)
2400243830Sdim    return "lib32";
2401243830Sdim
2402243830Sdim  return Triple.isArch32Bit() ? "lib" : "lib64";
2403243830Sdim}
2404243830Sdim
2405234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
2406234353Sdim  : Generic_ELF(D, Triple, Args) {
2407263508Sdim  GCCInstallation.init(Triple, Args);
2408234353Sdim  llvm::Triple::ArchType Arch = Triple.getArch();
2409263508Sdim  std::string SysRoot = computeSysRoot();
2410226633Sdim
2411263508Sdim  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
2412263508Sdim  // least) put various tools in a triple-prefixed directory off of the parent
2413263508Sdim  // of the GCC installation. We use the GCC triple here to ensure that we end
2414263508Sdim  // up with tools that support the same amount of cross compiling as the
2415263508Sdim  // detected GCC installation. For example, if we find a GCC installation
2416263508Sdim  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
2417263508Sdim  // used to target i386.
2418263508Sdim  // FIXME: This seems unlikely to be Linux-specific.
2419226633Sdim  ToolChain::path_list &PPaths = getProgramPaths();
2420228379Sdim  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
2421234353Sdim                         GCCInstallation.getTriple().str() + "/bin").str());
2422226633Sdim
2423226633Sdim  Linker = GetProgramPath("ld");
2424226633Sdim
2425249423Sdim  Distro Distro = DetectDistro(Arch);
2426218893Sdim
2427263508Sdim  if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
2428218893Sdim    ExtraOpts.push_back("-z");
2429218893Sdim    ExtraOpts.push_back("relro");
2430218893Sdim  }
2431218893Sdim
2432221345Sdim  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
2433218893Sdim    ExtraOpts.push_back("-X");
2434218893Sdim
2435243830Sdim  const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android;
2436251662Sdim  const bool IsMips = isMipsArch(Arch);
2437218893Sdim
2438251662Sdim  if (IsMips && !SysRoot.empty())
2439251662Sdim    ExtraOpts.push_back("--sysroot=" + SysRoot);
2440251662Sdim
2441234353Sdim  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
2442234353Sdim  // and the MIPS ABI require .dynsym to be sorted in different ways.
2443234353Sdim  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
2444234353Sdim  // ABI requires a mapping between the GOT and the symbol table.
2445234353Sdim  // Android loader does not support .gnu.hash.
2446251662Sdim  if (!IsMips && !IsAndroid) {
2447263508Sdim    if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
2448234353Sdim        (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
2449234353Sdim      ExtraOpts.push_back("--hash-style=gnu");
2450234353Sdim
2451263508Sdim    if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
2452234353Sdim        Distro == UbuntuJaunty || Distro == UbuntuKarmic)
2453234353Sdim      ExtraOpts.push_back("--hash-style=both");
2454234353Sdim  }
2455234353Sdim
2456223017Sdim  if (IsRedhat(Distro))
2457218893Sdim    ExtraOpts.push_back("--no-add-needed");
2458218893Sdim
2459223017Sdim  if (Distro == DebianSqueeze || Distro == DebianWheezy ||
2460263508Sdim      Distro == DebianJessie || IsOpenSUSE(Distro) ||
2461223017Sdim      (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
2462234353Sdim      (IsUbuntu(Distro) && Distro >= UbuntuKarmic))
2463218893Sdim    ExtraOpts.push_back("--build-id");
2464218893Sdim
2465263508Sdim  if (IsOpenSUSE(Distro))
2466223017Sdim    ExtraOpts.push_back("--enable-new-dtags");
2467223017Sdim
2468226633Sdim  // The selection of paths to try here is designed to match the patterns which
2469226633Sdim  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
2470226633Sdim  // This was determined by running GCC in a fake filesystem, creating all
2471226633Sdim  // possible permutations of these directories, and seeing which ones it added
2472226633Sdim  // to the link paths.
2473226633Sdim  path_list &Paths = getFilePaths();
2474219077Sdim
2475243830Sdim  const std::string Multilib = getMultilibDir(Triple, Args);
2476228379Sdim  const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
2477226633Sdim
2478228379Sdim  // Add the multilib suffixed paths where they are available.
2479228379Sdim  if (GCCInstallation.isValid()) {
2480234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2481228379Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2482234353Sdim
2483263508Sdim    // Sourcery CodeBench MIPS toolchain holds some libraries under
2484263508Sdim    // a biarch-like suffix of the GCC installation.
2485263508Sdim    //
2486263508Sdim    // FIXME: It would be cleaner to model this as a variant of bi-arch. IE,
2487263508Sdim    // instead of a '64' biarch suffix it would be 'el' or something.
2488263508Sdim    if (IsAndroid && IsMips && isMips32r2(Args)) {
2489263508Sdim      assert(GCCInstallation.getBiarchSuffix().empty() &&
2490263508Sdim             "Unexpected bi-arch suffix");
2491263508Sdim      addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths);
2492263508Sdim    } else {
2493243830Sdim      addPathIfExists((GCCInstallation.getInstallPath() +
2494263508Sdim                       GCCInstallation.getMIPSABIDirSuffix() +
2495263508Sdim                       GCCInstallation.getBiarchSuffix()),
2496243830Sdim                      Paths);
2497263508Sdim    }
2498243830Sdim
2499263508Sdim    // GCC cross compiling toolchains will install target libraries which ship
2500263508Sdim    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
2501263508Sdim    // any part of the GCC installation in
2502263508Sdim    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
2503263508Sdim    // debatable, but is the reality today. We need to search this tree even
2504263508Sdim    // when we have a sysroot somewhere else. It is the responsibility of
2505263508Sdim    // whomever is doing the cross build targetting a sysroot using a GCC
2506263508Sdim    // installation that is *not* within the system root to ensure two things:
2507263508Sdim    //
2508263508Sdim    //  1) Any DSOs that are linked in from this tree or from the install path
2509263508Sdim    //     above must be preasant on the system root and found via an
2510263508Sdim    //     appropriate rpath.
2511263508Sdim    //  2) There must not be libraries installed into
2512263508Sdim    //     <prefix>/<triple>/<libdir> unless they should be preferred over
2513263508Sdim    //     those within the system root.
2514263508Sdim    //
2515263508Sdim    // Note that this matches the GCC behavior. See the below comment for where
2516263508Sdim    // Clang diverges from GCC's behavior.
2517263508Sdim    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib +
2518263508Sdim                    GCCInstallation.getMIPSABIDirSuffix(),
2519263508Sdim                    Paths);
2520263508Sdim
2521234353Sdim    // If the GCC installation we found is inside of the sysroot, we want to
2522234353Sdim    // prefer libraries installed in the parent prefix of the GCC installation.
2523234353Sdim    // It is important to *not* use these paths when the GCC installation is
2524234982Sdim    // outside of the system root as that can pick up unintended libraries.
2525234353Sdim    // This usually happens when there is an external cross compiler on the
2526234353Sdim    // host system, and a more minimal sysroot available that is the target of
2527263508Sdim    // the cross. Note that GCC does include some of these directories in some
2528263508Sdim    // configurations but this seems somewhere between questionable and simply
2529263508Sdim    // a bug.
2530234353Sdim    if (StringRef(LibPath).startswith(SysRoot)) {
2531234353Sdim      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
2532234353Sdim      addPathIfExists(LibPath + "/../" + Multilib, Paths);
2533234353Sdim    }
2534228379Sdim  }
2535228379Sdim  addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
2536228379Sdim  addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
2537228379Sdim  addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
2538228379Sdim  addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
2539226633Sdim
2540263508Sdim  // Try walking via the GCC triple path in case of biarch or multiarch GCC
2541228379Sdim  // installations with strange symlinks.
2542263508Sdim  if (GCCInstallation.isValid()) {
2543234353Sdim    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
2544228379Sdim                    "/../../" + Multilib, Paths);
2545226633Sdim
2546263508Sdim    // Add the non-multilib suffixed paths (if potentially different).
2547226633Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2548234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2549263508Sdim    if (!GCCInstallation.getBiarchSuffix().empty())
2550263508Sdim      addPathIfExists(GCCInstallation.getInstallPath() +
2551263508Sdim                      GCCInstallation.getMIPSABIDirSuffix(), Paths);
2552234353Sdim
2553263508Sdim    // See comments above on the multilib variant for details of why this is
2554263508Sdim    // included even from outside the sysroot.
2555263508Sdim    addPathIfExists(LibPath + "/../" + GCCTriple.str() +
2556263508Sdim                    "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths);
2557263508Sdim
2558263508Sdim    // See comments above on the multilib variant for details of why this is
2559263508Sdim    // only included from within the sysroot.
2560263508Sdim    if (StringRef(LibPath).startswith(SysRoot))
2561234353Sdim      addPathIfExists(LibPath, Paths);
2562226633Sdim  }
2563226633Sdim  addPathIfExists(SysRoot + "/lib", Paths);
2564226633Sdim  addPathIfExists(SysRoot + "/usr/lib", Paths);
2565263508Sdim}
2566251662Sdim
2567263508Sdimbool FreeBSD::HasNativeLLVMSupport() const {
2568263508Sdim  return true;
2569218893Sdim}
2570218893Sdim
2571218893Sdimbool Linux::HasNativeLLVMSupport() const {
2572218893Sdim  return true;
2573218893Sdim}
2574218893Sdim
2575249423SdimTool *Linux::buildLinker() const {
2576249423Sdim  return new tools::gnutools::Link(*this);
2577249423Sdim}
2578212904Sdim
2579249423SdimTool *Linux::buildAssembler() const {
2580249423Sdim  return new tools::gnutools::Assemble(*this);
2581212904Sdim}
2582212904Sdim
2583263508Sdimstd::string Linux::computeSysRoot() const {
2584251662Sdim  if (!getDriver().SysRoot.empty())
2585251662Sdim    return getDriver().SysRoot;
2586251662Sdim
2587251662Sdim  if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
2588251662Sdim    return std::string();
2589251662Sdim
2590263508Sdim  // Standalone MIPS toolchains use different names for sysroot folder
2591263508Sdim  // and put it into different places. Here we try to check some known
2592263508Sdim  // variants.
2593251662Sdim
2594263508Sdim  const StringRef InstallDir = GCCInstallation.getInstallPath();
2595263508Sdim  const StringRef TripleStr = GCCInstallation.getTriple().str();
2596263508Sdim  const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
2597263508Sdim
2598263508Sdim  std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
2599263508Sdim                      MIPSABIDirSuffix).str();
2600263508Sdim
2601263508Sdim  if (llvm::sys::fs::exists(Path))
2602263508Sdim    return Path;
2603263508Sdim
2604263508Sdim  Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str();
2605263508Sdim
2606263508Sdim  if (llvm::sys::fs::exists(Path))
2607263508Sdim    return Path;
2608263508Sdim
2609263508Sdim  return std::string();
2610251662Sdim}
2611251662Sdim
2612228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2613228379Sdim                                      ArgStringList &CC1Args) const {
2614228379Sdim  const Driver &D = getDriver();
2615263508Sdim  std::string SysRoot = computeSysRoot();
2616228379Sdim
2617228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc))
2618228379Sdim    return;
2619228379Sdim
2620228379Sdim  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
2621251662Sdim    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
2622228379Sdim
2623228379Sdim  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2624263508Sdim    SmallString<128> P(D.ResourceDir);
2625263508Sdim    llvm::sys::path::append(P, "include");
2626228379Sdim    addSystemInclude(DriverArgs, CC1Args, P.str());
2627228379Sdim  }
2628228379Sdim
2629228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2630228379Sdim    return;
2631228379Sdim
2632228379Sdim  // Check for configure-time C include directories.
2633228379Sdim  StringRef CIncludeDirs(C_INCLUDE_DIRS);
2634228379Sdim  if (CIncludeDirs != "") {
2635228379Sdim    SmallVector<StringRef, 5> dirs;
2636228379Sdim    CIncludeDirs.split(dirs, ":");
2637228379Sdim    for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end();
2638228379Sdim         I != E; ++I) {
2639251662Sdim      StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : "";
2640228379Sdim      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I);
2641228379Sdim    }
2642228379Sdim    return;
2643228379Sdim  }
2644228379Sdim
2645228379Sdim  // Lacking those, try to detect the correct set of system includes for the
2646228379Sdim  // target triple.
2647228379Sdim
2648251662Sdim  // Sourcery CodeBench and modern FSF Mips toolchains put extern C
2649251662Sdim  // system includes under three additional directories.
2650251662Sdim  if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) {
2651263508Sdim    addExternCSystemIncludeIfExists(
2652263508Sdim        DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include");
2653251662Sdim
2654263508Sdim    addExternCSystemIncludeIfExists(
2655263508Sdim        DriverArgs, CC1Args,
2656263508Sdim        GCCInstallation.getInstallPath() + "/../../../../" +
2657263508Sdim            GCCInstallation.getTriple().str() + "/libc/usr/include");
2658263508Sdim
2659263508Sdim    addExternCSystemIncludeIfExists(
2660263508Sdim        DriverArgs, CC1Args,
2661263508Sdim        GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include");
2662251662Sdim  }
2663251662Sdim
2664228379Sdim  // Implement generic Debian multiarch support.
2665228379Sdim  const StringRef X86_64MultiarchIncludeDirs[] = {
2666228379Sdim    "/usr/include/x86_64-linux-gnu",
2667228379Sdim
2668228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2669228379Sdim    // in use in any released version of Debian, so we should consider
2670228379Sdim    // removing them.
2671263508Sdim    "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"
2672228379Sdim  };
2673228379Sdim  const StringRef X86MultiarchIncludeDirs[] = {
2674228379Sdim    "/usr/include/i386-linux-gnu",
2675228379Sdim
2676228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2677228379Sdim    // in use in any released version of Debian, so we should consider
2678228379Sdim    // removing them.
2679263508Sdim    "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
2680228379Sdim    "/usr/include/i486-linux-gnu"
2681228379Sdim  };
2682249423Sdim  const StringRef AArch64MultiarchIncludeDirs[] = {
2683249423Sdim    "/usr/include/aarch64-linux-gnu"
2684249423Sdim  };
2685228379Sdim  const StringRef ARMMultiarchIncludeDirs[] = {
2686228379Sdim    "/usr/include/arm-linux-gnueabi"
2687228379Sdim  };
2688239462Sdim  const StringRef ARMHFMultiarchIncludeDirs[] = {
2689239462Sdim    "/usr/include/arm-linux-gnueabihf"
2690239462Sdim  };
2691234353Sdim  const StringRef MIPSMultiarchIncludeDirs[] = {
2692234353Sdim    "/usr/include/mips-linux-gnu"
2693234353Sdim  };
2694234353Sdim  const StringRef MIPSELMultiarchIncludeDirs[] = {
2695234353Sdim    "/usr/include/mipsel-linux-gnu"
2696234353Sdim  };
2697234353Sdim  const StringRef PPCMultiarchIncludeDirs[] = {
2698234353Sdim    "/usr/include/powerpc-linux-gnu"
2699234353Sdim  };
2700234353Sdim  const StringRef PPC64MultiarchIncludeDirs[] = {
2701234353Sdim    "/usr/include/powerpc64-linux-gnu"
2702234353Sdim  };
2703228379Sdim  ArrayRef<StringRef> MultiarchIncludeDirs;
2704228379Sdim  if (getTriple().getArch() == llvm::Triple::x86_64) {
2705228379Sdim    MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
2706228379Sdim  } else if (getTriple().getArch() == llvm::Triple::x86) {
2707228379Sdim    MultiarchIncludeDirs = X86MultiarchIncludeDirs;
2708249423Sdim  } else if (getTriple().getArch() == llvm::Triple::aarch64) {
2709249423Sdim    MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
2710228379Sdim  } else if (getTriple().getArch() == llvm::Triple::arm) {
2711239462Sdim    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
2712239462Sdim      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
2713239462Sdim    else
2714239462Sdim      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
2715234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mips) {
2716234353Sdim    MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
2717234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mipsel) {
2718234353Sdim    MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
2719234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc) {
2720234353Sdim    MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
2721234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc64) {
2722234353Sdim    MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
2723228379Sdim  }
2724228379Sdim  for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(),
2725228379Sdim                                     E = MultiarchIncludeDirs.end();
2726228379Sdim       I != E; ++I) {
2727251662Sdim    if (llvm::sys::fs::exists(SysRoot + *I)) {
2728251662Sdim      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I);
2729228379Sdim      break;
2730228379Sdim    }
2731228379Sdim  }
2732228379Sdim
2733228379Sdim  if (getTriple().getOS() == llvm::Triple::RTEMS)
2734228379Sdim    return;
2735228379Sdim
2736234353Sdim  // Add an include of '/include' directly. This isn't provided by default by
2737234353Sdim  // system GCCs, but is often used with cross-compiling GCCs, and harmless to
2738234353Sdim  // add even when Clang is acting as-if it were a system compiler.
2739251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
2740234353Sdim
2741251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
2742228379Sdim}
2743228379Sdim
2744249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation.
2745234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
2746234353Sdim                                                const ArgList &DriverArgs,
2747234353Sdim                                                ArgStringList &CC1Args) {
2748228379Sdim  if (!llvm::sys::fs::exists(Base))
2749228379Sdim    return false;
2750228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base);
2751228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir);
2752228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/backward");
2753228379Sdim  return true;
2754228379Sdim}
2755228379Sdim
2756249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
2757249423Sdim/// libstdc++ installation.
2758249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
2759249423Sdim                                                Twine TargetArchDir,
2760263508Sdim                                                Twine BiarchSuffix,
2761263508Sdim                                                Twine MIPSABIDirSuffix,
2762249423Sdim                                                const ArgList &DriverArgs,
2763249423Sdim                                                ArgStringList &CC1Args) {
2764263508Sdim  if (!addLibStdCXXIncludePaths(Base + Suffix,
2765263508Sdim                                TargetArchDir + MIPSABIDirSuffix + BiarchSuffix,
2766249423Sdim                                DriverArgs, CC1Args))
2767249423Sdim    return false;
2768249423Sdim
2769249423Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
2770263508Sdim                   + MIPSABIDirSuffix + BiarchSuffix);
2771249423Sdim  return true;
2772249423Sdim}
2773249423Sdim
2774228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2775228379Sdim                                         ArgStringList &CC1Args) const {
2776228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2777228379Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
2778228379Sdim    return;
2779228379Sdim
2780228379Sdim  // Check if libc++ has been enabled and provide its include paths if so.
2781228379Sdim  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
2782228379Sdim    // libc++ is always installed at a fixed path on Linux currently.
2783228379Sdim    addSystemInclude(DriverArgs, CC1Args,
2784228379Sdim                     getDriver().SysRoot + "/usr/include/c++/v1");
2785228379Sdim    return;
2786228379Sdim  }
2787228379Sdim
2788234353Sdim  // We need a detected GCC installation on Linux to provide libstdc++'s
2789234353Sdim  // headers. We handled the libc++ case above.
2790234353Sdim  if (!GCCInstallation.isValid())
2791228379Sdim    return;
2792228379Sdim
2793228379Sdim  // By default, look for the C++ headers in an include directory adjacent to
2794228379Sdim  // the lib directory of the GCC installation. Note that this is expect to be
2795228379Sdim  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
2796228379Sdim  StringRef LibDir = GCCInstallation.getParentLibPath();
2797228379Sdim  StringRef InstallDir = GCCInstallation.getInstallPath();
2798243830Sdim  StringRef TripleStr = GCCInstallation.getTriple().str();
2799263508Sdim  StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
2800263508Sdim  StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix();
2801263508Sdim  const GCCVersion &Version = GCCInstallation.getVersion();
2802243830Sdim
2803263508Sdim  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
2804263508Sdim                               "/c++/" + Version.Text, TripleStr, BiarchSuffix,
2805263508Sdim                               MIPSABIDirSuffix, DriverArgs, CC1Args))
2806249423Sdim    return;
2807249423Sdim
2808243830Sdim  const std::string IncludePathCandidates[] = {
2809228379Sdim    // Gentoo is weird and places its headers inside the GCC install, so if the
2810263508Sdim    // first attempt to find the headers fails, try these patterns.
2811263508Sdim    InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
2812263508Sdim        Version.MinorStr,
2813263508Sdim    InstallDir.str() + "/include/g++-v" + Version.MajorStr,
2814243830Sdim    // Android standalone toolchain has C++ headers in yet another place.
2815263508Sdim    LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
2816243830Sdim    // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
2817243830Sdim    // without a subdirectory corresponding to the gcc version.
2818243830Sdim    LibDir.str() + "/../include/c++",
2819243830Sdim  };
2820243830Sdim
2821243830Sdim  for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
2822263508Sdim    if (addLibStdCXXIncludePaths(IncludePathCandidates[i],
2823263508Sdim                                 TripleStr + MIPSABIDirSuffix + BiarchSuffix,
2824263508Sdim                                 DriverArgs, CC1Args))
2825243830Sdim      break;
2826228379Sdim  }
2827228379Sdim}
2828228379Sdim
2829251662Sdimbool Linux::isPIEDefault() const {
2830263508Sdim  return getSanitizerArgs().hasZeroBaseShadow();
2831251662Sdim}
2832251662Sdim
2833193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
2834193326Sed
2835234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2836234353Sdim  : Generic_ELF(D, Triple, Args) {
2837193326Sed
2838193326Sed  // Path mangling to find libexec
2839212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2840221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2841212904Sdim    getProgramPaths().push_back(getDriver().Dir);
2842193326Sed
2843201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
2844193326Sed  getFilePaths().push_back("/usr/lib");
2845251662Sdim  if (llvm::sys::fs::exists("/usr/lib/gcc47"))
2846251662Sdim    getFilePaths().push_back("/usr/lib/gcc47");
2847251662Sdim  else
2848251662Sdim    getFilePaths().push_back("/usr/lib/gcc44");
2849193326Sed}
2850193326Sed
2851249423SdimTool *DragonFly::buildAssembler() const {
2852249423Sdim  return new tools::dragonfly::Assemble(*this);
2853249423Sdim}
2854193326Sed
2855249423SdimTool *DragonFly::buildLinker() const {
2856249423Sdim  return new tools::dragonfly::Link(*this);
2857193326Sed}
2858263508Sdim
2859263508Sdim
2860263508Sdim/// XCore tool chain
2861263508SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple,
2862263508Sdim             const ArgList &Args) : ToolChain(D, Triple, Args) {
2863263508Sdim  // ProgramPaths are found via 'PATH' environment variable.
2864263508Sdim}
2865263508Sdim
2866263508SdimTool *XCore::buildAssembler() const {
2867263508Sdim  return new tools::XCore::Assemble(*this);
2868263508Sdim}
2869263508Sdim
2870263508SdimTool *XCore::buildLinker() const {
2871263508Sdim  return new tools::XCore::Link(*this);
2872263508Sdim}
2873263508Sdim
2874263508Sdimbool XCore::isPICDefault() const {
2875263508Sdim  return false;
2876263508Sdim}
2877263508Sdim
2878263508Sdimbool XCore::isPIEDefault() const {
2879263508Sdim  return false;
2880263508Sdim}
2881263508Sdim
2882263508Sdimbool XCore::isPICDefaultForced() const {
2883263508Sdim  return false;
2884263508Sdim}
2885263508Sdim
2886263508Sdimbool XCore::SupportsProfiling() const {
2887263508Sdim  return false;
2888263508Sdim}
2889263508Sdim
2890263508Sdimbool XCore::hasBlocksRuntime() const {
2891263508Sdim  return false;
2892263508Sdim}
2893263508Sdim
2894263508Sdim
2895263508Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2896263508Sdim                                      ArgStringList &CC1Args) const {
2897263508Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
2898263508Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
2899263508Sdim    return;
2900263508Sdim  if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
2901263508Sdim    SmallVector<StringRef, 4> Dirs;
2902263508Sdim    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
2903263508Sdim    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
2904263508Sdim    ArrayRef<StringRef> DirVec(Dirs);
2905263508Sdim    addSystemIncludes(DriverArgs, CC1Args, DirVec);
2906263508Sdim  }
2907263508Sdim}
2908263508Sdim
2909263508Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
2910263508Sdim                                     llvm::opt::ArgStringList &CC1Args) const {
2911263508Sdim  CC1Args.push_back("-nostdsysteminc");
2912263508Sdim}
2913263508Sdim
2914263508Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2915263508Sdim                                         ArgStringList &CC1Args) const {
2916263508Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
2917263508Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
2918263508Sdim    return;
2919263508Sdim  if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
2920263508Sdim    SmallVector<StringRef, 4> Dirs;
2921263508Sdim    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
2922263508Sdim    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
2923263508Sdim    ArrayRef<StringRef> DirVec(Dirs);
2924263508Sdim    addSystemIncludes(DriverArgs, CC1Args, DirVec);
2925263508Sdim  }
2926263508Sdim}
2927263508Sdim
2928263508Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args,
2929263508Sdim                                ArgStringList &CmdArgs) const {
2930263508Sdim  // We don't output any lib args. This is handled by xcc.
2931263508Sdim}
2932