ToolChains.cpp revision 263763
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
1653234353Sdim/// Hexagon Toolchain
1654193326Sed
1655249423Sdimstd::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) {
1656249423Sdim
1657249423Sdim  // Locate the rest of the toolchain ...
1658249423Sdim  if (strlen(GCC_INSTALL_PREFIX))
1659249423Sdim    return std::string(GCC_INSTALL_PREFIX);
1660249423Sdim
1661249423Sdim  std::string InstallRelDir = InstalledDir + "/../../gnu";
1662249423Sdim  if (llvm::sys::fs::exists(InstallRelDir))
1663249423Sdim    return InstallRelDir;
1664249423Sdim
1665249423Sdim  std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
1666249423Sdim  if (llvm::sys::fs::exists(PrefixRelDir))
1667249423Sdim    return PrefixRelDir;
1668249423Sdim
1669249423Sdim  return InstallRelDir;
1670234353Sdim}
1671234353Sdim
1672249423Sdimstatic void GetHexagonLibraryPaths(
1673249423Sdim  const ArgList &Args,
1674249423Sdim  const std::string Ver,
1675249423Sdim  const std::string MarchString,
1676249423Sdim  const std::string &InstalledDir,
1677249423Sdim  ToolChain::path_list *LibPaths)
1678249423Sdim{
1679249423Sdim  bool buildingLib = Args.hasArg(options::OPT_shared);
1680249423Sdim
1681249423Sdim  //----------------------------------------------------------------------------
1682249423Sdim  // -L Args
1683249423Sdim  //----------------------------------------------------------------------------
1684249423Sdim  for (arg_iterator
1685249423Sdim         it = Args.filtered_begin(options::OPT_L),
1686249423Sdim         ie = Args.filtered_end();
1687249423Sdim       it != ie;
1688249423Sdim       ++it) {
1689249423Sdim    for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
1690249423Sdim      LibPaths->push_back((*it)->getValue(i));
1691249423Sdim  }
1692249423Sdim
1693249423Sdim  //----------------------------------------------------------------------------
1694249423Sdim  // Other standard paths
1695249423Sdim  //----------------------------------------------------------------------------
1696249423Sdim  const std::string MarchSuffix = "/" + MarchString;
1697249423Sdim  const std::string G0Suffix = "/G0";
1698249423Sdim  const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
1699249423Sdim  const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/";
1700249423Sdim
1701249423Sdim  // lib/gcc/hexagon/...
1702249423Sdim  std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
1703249423Sdim  if (buildingLib) {
1704249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
1705249423Sdim    LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
1706249423Sdim  }
1707249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
1708249423Sdim  LibPaths->push_back(LibGCCHexagonDir + Ver);
1709249423Sdim
1710249423Sdim  // lib/gcc/...
1711249423Sdim  LibPaths->push_back(RootDir + "lib/gcc");
1712249423Sdim
1713249423Sdim  // hexagon/lib/...
1714249423Sdim  std::string HexagonLibDir = RootDir + "hexagon/lib";
1715249423Sdim  if (buildingLib) {
1716249423Sdim    LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
1717249423Sdim    LibPaths->push_back(HexagonLibDir + G0Suffix);
1718249423Sdim  }
1719249423Sdim  LibPaths->push_back(HexagonLibDir + MarchSuffix);
1720249423Sdim  LibPaths->push_back(HexagonLibDir);
1721249423Sdim}
1722249423Sdim
1723249423SdimHexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
1724249423Sdim                       const ArgList &Args)
1725249423Sdim  : Linux(D, Triple, Args) {
1726249423Sdim  const std::string InstalledDir(getDriver().getInstalledDir());
1727249423Sdim  const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir);
1728249423Sdim
1729249423Sdim  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
1730249423Sdim  // program paths
1731249423Sdim  const std::string BinDir(GnuDir + "/bin");
1732249423Sdim  if (llvm::sys::fs::exists(BinDir))
1733249423Sdim    getProgramPaths().push_back(BinDir);
1734249423Sdim
1735249423Sdim  // Determine version of GCC libraries and headers to use.
1736249423Sdim  const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
1737249423Sdim  llvm::error_code ec;
1738249423Sdim  GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
1739249423Sdim  for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
1740249423Sdim       !ec && di != de; di = di.increment(ec)) {
1741249423Sdim    GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
1742249423Sdim    if (MaxVersion < cv)
1743249423Sdim      MaxVersion = cv;
1744249423Sdim  }
1745249423Sdim  GCCLibAndIncVersion = MaxVersion;
1746249423Sdim
1747249423Sdim  ToolChain::path_list *LibPaths= &getFilePaths();
1748249423Sdim
1749249423Sdim  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
1750249423Sdim  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
1751249423Sdim  // support 'linux' we'll need to fix this up
1752249423Sdim  LibPaths->clear();
1753249423Sdim
1754249423Sdim  GetHexagonLibraryPaths(
1755249423Sdim    Args,
1756249423Sdim    GetGCCLibAndIncVersion(),
1757249423Sdim    GetTargetCPU(Args),
1758249423Sdim    InstalledDir,
1759249423Sdim    LibPaths);
1760249423Sdim}
1761249423Sdim
1762234353SdimHexagon_TC::~Hexagon_TC() {
1763234353Sdim}
1764234353Sdim
1765249423SdimTool *Hexagon_TC::buildAssembler() const {
1766249423Sdim  return new tools::hexagon::Assemble(*this);
1767249423Sdim}
1768234353Sdim
1769249423SdimTool *Hexagon_TC::buildLinker() const {
1770249423Sdim  return new tools::hexagon::Link(*this);
1771249423Sdim}
1772234353Sdim
1773249423Sdimvoid Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1774249423Sdim                                           ArgStringList &CC1Args) const {
1775249423Sdim  const Driver &D = getDriver();
1776249423Sdim
1777249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
1778249423Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
1779249423Sdim    return;
1780249423Sdim
1781249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1782249423Sdim  std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
1783249423Sdim  std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
1784249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
1785249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
1786249423Sdim  addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
1787249423Sdim}
1788249423Sdim
1789249423Sdimvoid Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1790249423Sdim                                              ArgStringList &CC1Args) const {
1791249423Sdim
1792249423Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1793249423Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1794249423Sdim    return;
1795249423Sdim
1796249423Sdim  const Driver &D = getDriver();
1797249423Sdim  std::string Ver(GetGCCLibAndIncVersion());
1798263508Sdim  SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
1799249423Sdim
1800263508Sdim  llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");
1801263508Sdim  llvm::sys::path::append(IncludeDir, Ver);
1802249423Sdim  addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
1803249423Sdim}
1804249423Sdim
1805249423SdimToolChain::CXXStdlibType
1806249423SdimHexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
1807249423Sdim  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1808249423Sdim  if (!A)
1809249423Sdim    return ToolChain::CST_Libstdcxx;
1810249423Sdim
1811249423Sdim  StringRef Value = A->getValue();
1812249423Sdim  if (Value != "libstdc++") {
1813249423Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1814249423Sdim      << A->getAsString(Args);
1815234353Sdim  }
1816234353Sdim
1817249423Sdim  return ToolChain::CST_Libstdcxx;
1818234353Sdim}
1819234353Sdim
1820263508Sdimstatic int getHexagonVersion(const ArgList &Args) {
1821263508Sdim  Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ);
1822263508Sdim  // Select the default CPU (v4) if none was given.
1823263508Sdim  if (!A)
1824263508Sdim    return 4;
1825249423Sdim
1826263508Sdim  // FIXME: produce errors if we cannot parse the version.
1827263508Sdim  StringRef WhichHexagon = A->getValue();
1828263508Sdim  if (WhichHexagon.startswith("hexagonv")) {
1829263508Sdim    int Val;
1830263508Sdim    if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val))
1831263508Sdim      return Val;
1832249423Sdim  }
1833263508Sdim  if (WhichHexagon.startswith("v")) {
1834263508Sdim    int Val;
1835263508Sdim    if (!WhichHexagon.substr(1).getAsInteger(10, Val))
1836263508Sdim      return Val;
1837263508Sdim  }
1838263508Sdim
1839263508Sdim  // FIXME: should probably be an error.
1840263508Sdim  return 4;
1841234353Sdim}
1842234353Sdim
1843249423SdimStringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
1844249423Sdim{
1845263508Sdim  int V = getHexagonVersion(Args);
1846263508Sdim  // FIXME: We don't support versions < 4. We should error on them.
1847263508Sdim  switch (V) {
1848263508Sdim  default:
1849263508Sdim    llvm_unreachable("Unexpected version");
1850263508Sdim  case 5:
1851263508Sdim    return "v5";
1852263508Sdim  case 4:
1853263508Sdim    return "v4";
1854263508Sdim  case 3:
1855263508Sdim    return "v3";
1856263508Sdim  case 2:
1857263508Sdim    return "v2";
1858263508Sdim  case 1:
1859263508Sdim    return "v1";
1860249423Sdim  }
1861234353Sdim}
1862249423Sdim// End Hexagon
1863234353Sdim
1864204793Srdivacky/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
1865204793Srdivacky/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
1866204793Srdivacky/// Currently does not support anything else but compilation.
1867204793Srdivacky
1868249423SdimTCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple,
1869249423Sdim                           const ArgList &Args)
1870249423Sdim  : ToolChain(D, Triple, Args) {
1871204793Srdivacky  // Path mangling to find libexec
1872204793Srdivacky  std::string Path(getDriver().Dir);
1873204793Srdivacky
1874204793Srdivacky  Path += "/../libexec";
1875204793Srdivacky  getProgramPaths().push_back(Path);
1876204793Srdivacky}
1877204793Srdivacky
1878204793SrdivackyTCEToolChain::~TCEToolChain() {
1879204793Srdivacky}
1880204793Srdivacky
1881223017Sdimbool TCEToolChain::IsMathErrnoDefault() const {
1882223017Sdim  return true;
1883204793Srdivacky}
1884204793Srdivacky
1885243830Sdimbool TCEToolChain::isPICDefault() const {
1886204793Srdivacky  return false;
1887204793Srdivacky}
1888204793Srdivacky
1889251662Sdimbool TCEToolChain::isPIEDefault() const {
1890251662Sdim  return false;
1891251662Sdim}
1892251662Sdim
1893243830Sdimbool TCEToolChain::isPICDefaultForced() const {
1894243830Sdim  return false;
1895204793Srdivacky}
1896204793Srdivacky
1897195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
1898195341Sed
1899234353SdimOpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1900234353Sdim  : Generic_ELF(D, Triple, Args) {
1901201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
1902195341Sed  getFilePaths().push_back("/usr/lib");
1903195341Sed}
1904195341Sed
1905249423SdimTool *OpenBSD::buildAssembler() const {
1906249423Sdim  return new tools::openbsd::Assemble(*this);
1907249423Sdim}
1908195341Sed
1909249423SdimTool *OpenBSD::buildLinker() const {
1910249423Sdim  return new tools::openbsd::Link(*this);
1911195341Sed}
1912195341Sed
1913239462Sdim/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
1914239462Sdim
1915239462SdimBitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1916239462Sdim  : Generic_ELF(D, Triple, Args) {
1917239462Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
1918239462Sdim  getFilePaths().push_back("/usr/lib");
1919239462Sdim}
1920239462Sdim
1921249423SdimTool *Bitrig::buildAssembler() const {
1922249423Sdim  return new tools::bitrig::Assemble(*this);
1923249423Sdim}
1924239462Sdim
1925249423SdimTool *Bitrig::buildLinker() const {
1926249423Sdim  return new tools::bitrig::Link(*this);
1927239462Sdim}
1928239462Sdim
1929239462Sdimvoid Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1930239462Sdim                                          ArgStringList &CC1Args) const {
1931239462Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
1932239462Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
1933239462Sdim    return;
1934239462Sdim
1935243830Sdim  switch (GetCXXStdlibType(DriverArgs)) {
1936243830Sdim  case ToolChain::CST_Libcxx:
1937243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1938243830Sdim                     getDriver().SysRoot + "/usr/include/c++/");
1939243830Sdim    break;
1940243830Sdim  case ToolChain::CST_Libstdcxx:
1941243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1942243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++");
1943243830Sdim    addSystemInclude(DriverArgs, CC1Args,
1944243830Sdim                     getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
1945239462Sdim
1946243830Sdim    StringRef Triple = getTriple().str();
1947243830Sdim    if (Triple.startswith("amd64"))
1948243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1949243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
1950243830Sdim                       Triple.substr(5));
1951243830Sdim    else
1952243830Sdim      addSystemInclude(DriverArgs, CC1Args,
1953243830Sdim                       getDriver().SysRoot + "/usr/include/c++/stdc++/" +
1954243830Sdim                       Triple);
1955243830Sdim    break;
1956243830Sdim  }
1957239462Sdim}
1958239462Sdim
1959239462Sdimvoid Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
1960239462Sdim                                 ArgStringList &CmdArgs) const {
1961243830Sdim  switch (GetCXXStdlibType(Args)) {
1962243830Sdim  case ToolChain::CST_Libcxx:
1963243830Sdim    CmdArgs.push_back("-lc++");
1964243830Sdim    CmdArgs.push_back("-lcxxrt");
1965243830Sdim    // Include supc++ to provide Unwind until provided by libcxx.
1966243830Sdim    CmdArgs.push_back("-lgcc");
1967243830Sdim    break;
1968243830Sdim  case ToolChain::CST_Libstdcxx:
1969243830Sdim    CmdArgs.push_back("-lstdc++");
1970243830Sdim    break;
1971243830Sdim  }
1972239462Sdim}
1973239462Sdim
1974193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
1975193326Sed
1976234353SdimFreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
1977234353Sdim  : Generic_ELF(D, Triple, Args) {
1978212904Sdim
1979234353Sdim  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
1980234353Sdim  // back to '/usr/lib' if it doesn't exist.
1981234353Sdim  if ((Triple.getArch() == llvm::Triple::x86 ||
1982234353Sdim       Triple.getArch() == llvm::Triple::ppc) &&
1983234982Sdim      llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
1984234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
1985234353Sdim  else
1986234982Sdim    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
1987193326Sed}
1988193326Sed
1989255321StheravenToolChain::CXXStdlibType
1990255321StheravenFreeBSD::GetCXXStdlibType(const ArgList &Args) const {
1991255321Stheraven  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
1992255321Stheraven    StringRef Value = A->getValue();
1993263508Sdim    if (Value == "libstdc++")
1994263508Sdim      return ToolChain::CST_Libstdcxx;
1995255321Stheraven    if (Value == "libc++")
1996255321Stheraven      return ToolChain::CST_Libcxx;
1997263508Sdim
1998255321Stheraven    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1999255321Stheraven      << A->getAsString(Args);
2000255321Stheraven  }
2001263508Sdim  if (getTriple().getOSMajorVersion() >= 10)
2002263508Sdim    return ToolChain::CST_Libcxx;
2003263508Sdim  return ToolChain::CST_Libstdcxx;
2004255321Stheraven}
2005255321Stheraven
2006255321Stheravenvoid FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2007263508Sdim                                           ArgStringList &CC1Args) const {
2008255321Stheraven  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2009255321Stheraven      DriverArgs.hasArg(options::OPT_nostdincxx))
2010255321Stheraven    return;
2011255321Stheraven
2012263508Sdim  switch (GetCXXStdlibType(DriverArgs)) {
2013263508Sdim  case ToolChain::CST_Libcxx:
2014255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
2015255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/v1");
2016263508Sdim    break;
2017263508Sdim  case ToolChain::CST_Libstdcxx:
2018255321Stheraven    addSystemInclude(DriverArgs, CC1Args,
2019255321Stheraven                     getDriver().SysRoot + "/usr/include/c++/4.2");
2020263508Sdim    addSystemInclude(DriverArgs, CC1Args,
2021263508Sdim                     getDriver().SysRoot + "/usr/include/c++/4.2/backward");
2022263508Sdim    break;
2023263508Sdim  }
2024263508Sdim}
2025255321Stheraven
2026263508SdimTool *FreeBSD::buildAssembler() const {
2027263508Sdim  return new tools::freebsd::Assemble(*this);
2028255321Stheraven}
2029255321Stheraven
2030263508SdimTool *FreeBSD::buildLinker() const {
2031263508Sdim  return new tools::freebsd::Link(*this);
2032263508Sdim}
2033263508Sdim
2034263508Sdimbool FreeBSD::UseSjLjExceptions() const {
2035263508Sdim  // FreeBSD uses SjLj exceptions on ARM oabi.
2036263508Sdim  switch (getTriple().getEnvironment()) {
2037263508Sdim  case llvm::Triple::GNUEABI:
2038263508Sdim  case llvm::Triple::EABI:
2039263508Sdim    return false;
2040263508Sdim
2041263508Sdim  default:
2042263508Sdim    return (getTriple().getArch() == llvm::Triple::arm ||
2043263508Sdim            getTriple().getArch() == llvm::Triple::thumb);
2044263508Sdim  }
2045263508Sdim}
2046263508Sdim
2047218893Sdim/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
2048218893Sdim
2049234353SdimNetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2050234353Sdim  : Generic_ELF(D, Triple, Args) {
2051218893Sdim
2052221345Sdim  if (getDriver().UseStdLib) {
2053234353Sdim    // When targeting a 32-bit platform, try the special directory used on
2054234353Sdim    // 64-bit hosts, and only fall back to the main library directory if that
2055234353Sdim    // doesn't work.
2056234353Sdim    // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
2057234353Sdim    // what all logic is needed to emulate the '=' prefix here.
2058234353Sdim    if (Triple.getArch() == llvm::Triple::x86)
2059221345Sdim      getFilePaths().push_back("=/usr/lib/i386");
2060234353Sdim
2061234353Sdim    getFilePaths().push_back("=/usr/lib");
2062218893Sdim  }
2063218893Sdim}
2064218893Sdim
2065249423SdimTool *NetBSD::buildAssembler() const {
2066249423Sdim  return new tools::netbsd::Assemble(*this);
2067249423Sdim}
2068218893Sdim
2069249423SdimTool *NetBSD::buildLinker() const {
2070249423Sdim  return new tools::netbsd::Link(*this);
2071218893Sdim}
2072218893Sdim
2073251662SdimToolChain::CXXStdlibType
2074251662SdimNetBSD::GetCXXStdlibType(const ArgList &Args) const {
2075251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
2076251662Sdim    StringRef Value = A->getValue();
2077251662Sdim    if (Value == "libstdc++")
2078251662Sdim      return ToolChain::CST_Libstdcxx;
2079251662Sdim    if (Value == "libc++")
2080251662Sdim      return ToolChain::CST_Libcxx;
2081251662Sdim
2082251662Sdim    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2083251662Sdim      << A->getAsString(Args);
2084251662Sdim  }
2085251662Sdim
2086263508Sdim  unsigned Major, Minor, Micro;
2087263508Sdim  getTriple().getOSVersion(Major, Minor, Micro);
2088263508Sdim  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
2089263508Sdim    if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64)
2090263508Sdim      return ToolChain::CST_Libcxx;
2091263508Sdim  }
2092251662Sdim  return ToolChain::CST_Libstdcxx;
2093251662Sdim}
2094251662Sdim
2095251662Sdimvoid NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2096251662Sdim                                          ArgStringList &CC1Args) const {
2097251662Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2098251662Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
2099251662Sdim    return;
2100251662Sdim
2101251662Sdim  switch (GetCXXStdlibType(DriverArgs)) {
2102251662Sdim  case ToolChain::CST_Libcxx:
2103251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2104251662Sdim                     getDriver().SysRoot + "/usr/include/c++/");
2105251662Sdim    break;
2106251662Sdim  case ToolChain::CST_Libstdcxx:
2107251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2108251662Sdim                     getDriver().SysRoot + "/usr/include/g++");
2109251662Sdim    addSystemInclude(DriverArgs, CC1Args,
2110251662Sdim                     getDriver().SysRoot + "/usr/include/g++/backward");
2111251662Sdim    break;
2112251662Sdim  }
2113251662Sdim}
2114251662Sdim
2115210299Sed/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
2116210299Sed
2117234353SdimMinix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2118234353Sdim  : Generic_ELF(D, Triple, Args) {
2119210299Sed  getFilePaths().push_back(getDriver().Dir + "/../lib");
2120210299Sed  getFilePaths().push_back("/usr/lib");
2121210299Sed}
2122210299Sed
2123249423SdimTool *Minix::buildAssembler() const {
2124249423Sdim  return new tools::minix::Assemble(*this);
2125249423Sdim}
2126210299Sed
2127249423SdimTool *Minix::buildLinker() const {
2128249423Sdim  return new tools::minix::Link(*this);
2129210299Sed}
2130210299Sed
2131198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
2132198092Srdivacky
2133234353SdimAuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
2134234353Sdim                   const ArgList &Args)
2135234353Sdim  : Generic_GCC(D, Triple, Args) {
2136198092Srdivacky
2137212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2138221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2139212904Sdim    getProgramPaths().push_back(getDriver().Dir);
2140198092Srdivacky
2141201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
2142198092Srdivacky  getFilePaths().push_back("/usr/lib");
2143198092Srdivacky  getFilePaths().push_back("/usr/sfw/lib");
2144198092Srdivacky  getFilePaths().push_back("/opt/gcc4/lib");
2145198398Srdivacky  getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
2146198092Srdivacky
2147198092Srdivacky}
2148198092Srdivacky
2149249423SdimTool *AuroraUX::buildAssembler() const {
2150249423Sdim  return new tools::auroraux::Assemble(*this);
2151249423Sdim}
2152198092Srdivacky
2153249423SdimTool *AuroraUX::buildLinker() const {
2154249423Sdim  return new tools::auroraux::Link(*this);
2155198092Srdivacky}
2156198092Srdivacky
2157234353Sdim/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
2158198092Srdivacky
2159234353SdimSolaris::Solaris(const Driver &D, const llvm::Triple& Triple,
2160234353Sdim                 const ArgList &Args)
2161234353Sdim  : Generic_GCC(D, Triple, Args) {
2162234353Sdim
2163234353Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2164234353Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2165234353Sdim    getProgramPaths().push_back(getDriver().Dir);
2166234353Sdim
2167234353Sdim  getFilePaths().push_back(getDriver().Dir + "/../lib");
2168234353Sdim  getFilePaths().push_back("/usr/lib");
2169234353Sdim}
2170234353Sdim
2171249423SdimTool *Solaris::buildAssembler() const {
2172249423Sdim  return new tools::solaris::Assemble(*this);
2173249423Sdim}
2174234353Sdim
2175249423SdimTool *Solaris::buildLinker() const {
2176249423Sdim  return new tools::solaris::Link(*this);
2177234353Sdim}
2178234353Sdim
2179249423Sdim/// Distribution (very bare-bones at the moment).
2180193326Sed
2181249423Sdimenum Distro {
2182219077Sdim  ArchLinux,
2183218893Sdim  DebianLenny,
2184218893Sdim  DebianSqueeze,
2185223017Sdim  DebianWheezy,
2186249423Sdim  DebianJessie,
2187218893Sdim  Exherbo,
2188223017Sdim  RHEL4,
2189223017Sdim  RHEL5,
2190223017Sdim  RHEL6,
2191263508Sdim  Fedora,
2192263508Sdim  OpenSUSE,
2193221345Sdim  UbuntuHardy,
2194221345Sdim  UbuntuIntrepid,
2195218893Sdim  UbuntuJaunty,
2196218893Sdim  UbuntuKarmic,
2197218893Sdim  UbuntuLucid,
2198218893Sdim  UbuntuMaverick,
2199221345Sdim  UbuntuNatty,
2200223017Sdim  UbuntuOneiric,
2201234353Sdim  UbuntuPrecise,
2202244628Sdim  UbuntuQuantal,
2203244628Sdim  UbuntuRaring,
2204263508Sdim  UbuntuSaucy,
2205263508Sdim  UbuntuTrusty,
2206218893Sdim  UnknownDistro
2207218893Sdim};
2208198092Srdivacky
2209249423Sdimstatic bool IsRedhat(enum Distro Distro) {
2210263508Sdim  return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6);
2211218893Sdim}
2212198092Srdivacky
2213263508Sdimstatic bool IsOpenSUSE(enum Distro Distro) {
2214263508Sdim  return Distro == OpenSUSE;
2215193326Sed}
2216193326Sed
2217249423Sdimstatic bool IsDebian(enum Distro Distro) {
2218249423Sdim  return Distro >= DebianLenny && Distro <= DebianJessie;
2219218893Sdim}
2220218893Sdim
2221249423Sdimstatic bool IsUbuntu(enum Distro Distro) {
2222263508Sdim  return Distro >= UbuntuHardy && Distro <= UbuntuTrusty;
2223218893Sdim}
2224218893Sdim
2225249423Sdimstatic Distro DetectDistro(llvm::Triple::ArchType Arch) {
2226234353Sdim  OwningPtr<llvm::MemoryBuffer> File;
2227218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
2228226633Sdim    StringRef Data = File.get()->getBuffer();
2229226633Sdim    SmallVector<StringRef, 8> Lines;
2230218893Sdim    Data.split(Lines, "\n");
2231249423Sdim    Distro Version = UnknownDistro;
2232234353Sdim    for (unsigned i = 0, s = Lines.size(); i != s; ++i)
2233234353Sdim      if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME="))
2234249423Sdim        Version = llvm::StringSwitch<Distro>(Lines[i].substr(17))
2235234353Sdim          .Case("hardy", UbuntuHardy)
2236234353Sdim          .Case("intrepid", UbuntuIntrepid)
2237234353Sdim          .Case("jaunty", UbuntuJaunty)
2238234353Sdim          .Case("karmic", UbuntuKarmic)
2239234353Sdim          .Case("lucid", UbuntuLucid)
2240234353Sdim          .Case("maverick", UbuntuMaverick)
2241234353Sdim          .Case("natty", UbuntuNatty)
2242234353Sdim          .Case("oneiric", UbuntuOneiric)
2243234353Sdim          .Case("precise", UbuntuPrecise)
2244244628Sdim          .Case("quantal", UbuntuQuantal)
2245244628Sdim          .Case("raring", UbuntuRaring)
2246263508Sdim          .Case("saucy", UbuntuSaucy)
2247263508Sdim          .Case("trusty", UbuntuTrusty)
2248234353Sdim          .Default(UnknownDistro);
2249234353Sdim    return Version;
2250218893Sdim  }
2251218893Sdim
2252218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
2253226633Sdim    StringRef Data = File.get()->getBuffer();
2254263508Sdim    if (Data.startswith("Fedora release"))
2255263508Sdim      return Fedora;
2256223017Sdim    else if (Data.startswith("Red Hat Enterprise Linux") &&
2257226633Sdim             Data.find("release 6") != StringRef::npos)
2258223017Sdim      return RHEL6;
2259223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2260249423Sdim              Data.startswith("CentOS")) &&
2261226633Sdim             Data.find("release 5") != StringRef::npos)
2262223017Sdim      return RHEL5;
2263223017Sdim    else if ((Data.startswith("Red Hat Enterprise Linux") ||
2264249423Sdim              Data.startswith("CentOS")) &&
2265226633Sdim             Data.find("release 4") != StringRef::npos)
2266223017Sdim      return RHEL4;
2267218893Sdim    return UnknownDistro;
2268218893Sdim  }
2269218893Sdim
2270218893Sdim  if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
2271226633Sdim    StringRef Data = File.get()->getBuffer();
2272218893Sdim    if (Data[0] == '5')
2273218893Sdim      return DebianLenny;
2274234353Sdim    else if (Data.startswith("squeeze/sid") || Data[0] == '6')
2275218893Sdim      return DebianSqueeze;
2276234353Sdim    else if (Data.startswith("wheezy/sid")  || Data[0] == '7')
2277223017Sdim      return DebianWheezy;
2278249423Sdim    else if (Data.startswith("jessie/sid")  || Data[0] == '8')
2279249423Sdim      return DebianJessie;
2280218893Sdim    return UnknownDistro;
2281218893Sdim  }
2282218893Sdim
2283263508Sdim  if (llvm::sys::fs::exists("/etc/SuSE-release"))
2284263508Sdim    return OpenSUSE;
2285218893Sdim
2286263508Sdim  if (llvm::sys::fs::exists("/etc/exherbo-release"))
2287218893Sdim    return Exherbo;
2288218893Sdim
2289263508Sdim  if (llvm::sys::fs::exists("/etc/arch-release"))
2290219077Sdim    return ArchLinux;
2291219077Sdim
2292218893Sdim  return UnknownDistro;
2293218893Sdim}
2294218893Sdim
2295228379Sdim/// \brief Get our best guess at the multiarch triple for a target.
2296228379Sdim///
2297228379Sdim/// Debian-based systems are starting to use a multiarch setup where they use
2298228379Sdim/// a target-triple directory in the library and header search paths.
2299228379Sdim/// Unfortunately, this triple does not align with the vanilla target triple,
2300228379Sdim/// so we provide a rough mapping here.
2301228379Sdimstatic std::string getMultiarchTriple(const llvm::Triple TargetTriple,
2302228379Sdim                                      StringRef SysRoot) {
2303228379Sdim  // For most architectures, just use whatever we have rather than trying to be
2304228379Sdim  // clever.
2305228379Sdim  switch (TargetTriple.getArch()) {
2306228379Sdim  default:
2307228379Sdim    return TargetTriple.str();
2308226633Sdim
2309228379Sdim    // We use the existence of '/lib/<triple>' as a directory to detect some
2310228379Sdim    // common linux triples that don't quite match the Clang triple for both
2311234353Sdim    // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
2312234353Sdim    // regardless of what the actual target triple is.
2313239462Sdim  case llvm::Triple::arm:
2314239462Sdim  case llvm::Triple::thumb:
2315239462Sdim    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
2316239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
2317239462Sdim        return "arm-linux-gnueabihf";
2318239462Sdim    } else {
2319239462Sdim      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
2320239462Sdim        return "arm-linux-gnueabi";
2321239462Sdim    }
2322239462Sdim    return TargetTriple.str();
2323228379Sdim  case llvm::Triple::x86:
2324228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
2325228379Sdim      return "i386-linux-gnu";
2326228379Sdim    return TargetTriple.str();
2327228379Sdim  case llvm::Triple::x86_64:
2328228379Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
2329228379Sdim      return "x86_64-linux-gnu";
2330228379Sdim    return TargetTriple.str();
2331249423Sdim  case llvm::Triple::aarch64:
2332249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
2333249423Sdim      return "aarch64-linux-gnu";
2334263508Sdim    return TargetTriple.str();
2335234353Sdim  case llvm::Triple::mips:
2336234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
2337234353Sdim      return "mips-linux-gnu";
2338234353Sdim    return TargetTriple.str();
2339234353Sdim  case llvm::Triple::mipsel:
2340234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
2341234353Sdim      return "mipsel-linux-gnu";
2342234353Sdim    return TargetTriple.str();
2343234353Sdim  case llvm::Triple::ppc:
2344249423Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
2345249423Sdim      return "powerpc-linux-gnuspe";
2346234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))
2347234353Sdim      return "powerpc-linux-gnu";
2348234353Sdim    return TargetTriple.str();
2349234353Sdim  case llvm::Triple::ppc64:
2350234353Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))
2351234353Sdim      return "powerpc64-linux-gnu";
2352263508Sdim  case llvm::Triple::ppc64le:
2353263508Sdim    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
2354263508Sdim      return "powerpc64le-linux-gnu";
2355234353Sdim    return TargetTriple.str();
2356226633Sdim  }
2357226633Sdim}
2358226633Sdim
2359234353Sdimstatic void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
2360234353Sdim  if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
2361234353Sdim}
2362234353Sdim
2363243830Sdimstatic StringRef getMultilibDir(const llvm::Triple &Triple,
2364243830Sdim                                const ArgList &Args) {
2365263508Sdim  if (isMipsArch(Triple.getArch())) {
2366263508Sdim    // lib32 directory has a special meaning on MIPS targets.
2367263508Sdim    // It contains N32 ABI binaries. Use this folder if produce
2368263508Sdim    // code for N32 ABI only.
2369263508Sdim    if (hasMipsN32ABIArg(Args))
2370263508Sdim      return "lib32";
2371263508Sdim    return Triple.isArch32Bit() ? "lib" : "lib64";
2372263508Sdim  }
2373243830Sdim
2374263508Sdim  // It happens that only x86 and PPC use the 'lib32' variant of multilib, and
2375263508Sdim  // using that variant while targeting other architectures causes problems
2376263508Sdim  // because the libraries are laid out in shared system roots that can't cope
2377263508Sdim  // with a 'lib32' multilib search path being considered. So we only enable
2378263508Sdim  // them when we know we may need it.
2379263508Sdim  //
2380263508Sdim  // FIXME: This is a bit of a hack. We should really unify this code for
2381263508Sdim  // reasoning about multilib spellings with the lib dir spellings in the
2382263508Sdim  // GCCInstallationDetector, but that is a more significant refactoring.
2383263508Sdim  if (Triple.getArch() == llvm::Triple::x86 ||
2384263508Sdim      Triple.getArch() == llvm::Triple::ppc)
2385243830Sdim    return "lib32";
2386243830Sdim
2387243830Sdim  return Triple.isArch32Bit() ? "lib" : "lib64";
2388243830Sdim}
2389243830Sdim
2390234353SdimLinux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
2391234353Sdim  : Generic_ELF(D, Triple, Args) {
2392263508Sdim  GCCInstallation.init(Triple, Args);
2393234353Sdim  llvm::Triple::ArchType Arch = Triple.getArch();
2394263508Sdim  std::string SysRoot = computeSysRoot();
2395226633Sdim
2396263508Sdim  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
2397263508Sdim  // least) put various tools in a triple-prefixed directory off of the parent
2398263508Sdim  // of the GCC installation. We use the GCC triple here to ensure that we end
2399263508Sdim  // up with tools that support the same amount of cross compiling as the
2400263508Sdim  // detected GCC installation. For example, if we find a GCC installation
2401263508Sdim  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
2402263508Sdim  // used to target i386.
2403263508Sdim  // FIXME: This seems unlikely to be Linux-specific.
2404226633Sdim  ToolChain::path_list &PPaths = getProgramPaths();
2405228379Sdim  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
2406234353Sdim                         GCCInstallation.getTriple().str() + "/bin").str());
2407226633Sdim
2408226633Sdim  Linker = GetProgramPath("ld");
2409226633Sdim
2410249423Sdim  Distro Distro = DetectDistro(Arch);
2411218893Sdim
2412263508Sdim  if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
2413218893Sdim    ExtraOpts.push_back("-z");
2414218893Sdim    ExtraOpts.push_back("relro");
2415218893Sdim  }
2416218893Sdim
2417221345Sdim  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
2418218893Sdim    ExtraOpts.push_back("-X");
2419218893Sdim
2420243830Sdim  const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android;
2421251662Sdim  const bool IsMips = isMipsArch(Arch);
2422218893Sdim
2423251662Sdim  if (IsMips && !SysRoot.empty())
2424251662Sdim    ExtraOpts.push_back("--sysroot=" + SysRoot);
2425251662Sdim
2426234353Sdim  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
2427234353Sdim  // and the MIPS ABI require .dynsym to be sorted in different ways.
2428234353Sdim  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
2429234353Sdim  // ABI requires a mapping between the GOT and the symbol table.
2430234353Sdim  // Android loader does not support .gnu.hash.
2431251662Sdim  if (!IsMips && !IsAndroid) {
2432263508Sdim    if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
2433234353Sdim        (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
2434234353Sdim      ExtraOpts.push_back("--hash-style=gnu");
2435234353Sdim
2436263508Sdim    if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
2437234353Sdim        Distro == UbuntuJaunty || Distro == UbuntuKarmic)
2438234353Sdim      ExtraOpts.push_back("--hash-style=both");
2439234353Sdim  }
2440234353Sdim
2441223017Sdim  if (IsRedhat(Distro))
2442218893Sdim    ExtraOpts.push_back("--no-add-needed");
2443218893Sdim
2444223017Sdim  if (Distro == DebianSqueeze || Distro == DebianWheezy ||
2445263508Sdim      Distro == DebianJessie || IsOpenSUSE(Distro) ||
2446223017Sdim      (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
2447234353Sdim      (IsUbuntu(Distro) && Distro >= UbuntuKarmic))
2448218893Sdim    ExtraOpts.push_back("--build-id");
2449218893Sdim
2450263508Sdim  if (IsOpenSUSE(Distro))
2451223017Sdim    ExtraOpts.push_back("--enable-new-dtags");
2452223017Sdim
2453226633Sdim  // The selection of paths to try here is designed to match the patterns which
2454226633Sdim  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
2455226633Sdim  // This was determined by running GCC in a fake filesystem, creating all
2456226633Sdim  // possible permutations of these directories, and seeing which ones it added
2457226633Sdim  // to the link paths.
2458226633Sdim  path_list &Paths = getFilePaths();
2459219077Sdim
2460243830Sdim  const std::string Multilib = getMultilibDir(Triple, Args);
2461228379Sdim  const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
2462226633Sdim
2463228379Sdim  // Add the multilib suffixed paths where they are available.
2464228379Sdim  if (GCCInstallation.isValid()) {
2465234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2466228379Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2467234353Sdim
2468263508Sdim    // Sourcery CodeBench MIPS toolchain holds some libraries under
2469263508Sdim    // a biarch-like suffix of the GCC installation.
2470263508Sdim    //
2471263508Sdim    // FIXME: It would be cleaner to model this as a variant of bi-arch. IE,
2472263508Sdim    // instead of a '64' biarch suffix it would be 'el' or something.
2473263508Sdim    if (IsAndroid && IsMips && isMips32r2(Args)) {
2474263508Sdim      assert(GCCInstallation.getBiarchSuffix().empty() &&
2475263508Sdim             "Unexpected bi-arch suffix");
2476263508Sdim      addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths);
2477263508Sdim    } else {
2478243830Sdim      addPathIfExists((GCCInstallation.getInstallPath() +
2479263508Sdim                       GCCInstallation.getMIPSABIDirSuffix() +
2480263508Sdim                       GCCInstallation.getBiarchSuffix()),
2481243830Sdim                      Paths);
2482263508Sdim    }
2483243830Sdim
2484263508Sdim    // GCC cross compiling toolchains will install target libraries which ship
2485263508Sdim    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
2486263508Sdim    // any part of the GCC installation in
2487263508Sdim    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
2488263508Sdim    // debatable, but is the reality today. We need to search this tree even
2489263508Sdim    // when we have a sysroot somewhere else. It is the responsibility of
2490263508Sdim    // whomever is doing the cross build targetting a sysroot using a GCC
2491263508Sdim    // installation that is *not* within the system root to ensure two things:
2492263508Sdim    //
2493263508Sdim    //  1) Any DSOs that are linked in from this tree or from the install path
2494263508Sdim    //     above must be preasant on the system root and found via an
2495263508Sdim    //     appropriate rpath.
2496263508Sdim    //  2) There must not be libraries installed into
2497263508Sdim    //     <prefix>/<triple>/<libdir> unless they should be preferred over
2498263508Sdim    //     those within the system root.
2499263508Sdim    //
2500263508Sdim    // Note that this matches the GCC behavior. See the below comment for where
2501263508Sdim    // Clang diverges from GCC's behavior.
2502263508Sdim    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib +
2503263508Sdim                    GCCInstallation.getMIPSABIDirSuffix(),
2504263508Sdim                    Paths);
2505263508Sdim
2506234353Sdim    // If the GCC installation we found is inside of the sysroot, we want to
2507234353Sdim    // prefer libraries installed in the parent prefix of the GCC installation.
2508234353Sdim    // It is important to *not* use these paths when the GCC installation is
2509234982Sdim    // outside of the system root as that can pick up unintended libraries.
2510234353Sdim    // This usually happens when there is an external cross compiler on the
2511234353Sdim    // host system, and a more minimal sysroot available that is the target of
2512263508Sdim    // the cross. Note that GCC does include some of these directories in some
2513263508Sdim    // configurations but this seems somewhere between questionable and simply
2514263508Sdim    // a bug.
2515234353Sdim    if (StringRef(LibPath).startswith(SysRoot)) {
2516234353Sdim      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
2517234353Sdim      addPathIfExists(LibPath + "/../" + Multilib, Paths);
2518234353Sdim    }
2519228379Sdim  }
2520228379Sdim  addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
2521228379Sdim  addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
2522228379Sdim  addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
2523228379Sdim  addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
2524226633Sdim
2525263508Sdim  // Try walking via the GCC triple path in case of biarch or multiarch GCC
2526228379Sdim  // installations with strange symlinks.
2527263508Sdim  if (GCCInstallation.isValid()) {
2528234353Sdim    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
2529228379Sdim                    "/../../" + Multilib, Paths);
2530226633Sdim
2531263508Sdim    // Add the non-multilib suffixed paths (if potentially different).
2532226633Sdim    const std::string &LibPath = GCCInstallation.getParentLibPath();
2533234353Sdim    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
2534263508Sdim    if (!GCCInstallation.getBiarchSuffix().empty())
2535263508Sdim      addPathIfExists(GCCInstallation.getInstallPath() +
2536263508Sdim                      GCCInstallation.getMIPSABIDirSuffix(), Paths);
2537234353Sdim
2538263508Sdim    // See comments above on the multilib variant for details of why this is
2539263508Sdim    // included even from outside the sysroot.
2540263508Sdim    addPathIfExists(LibPath + "/../" + GCCTriple.str() +
2541263508Sdim                    "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths);
2542263508Sdim
2543263508Sdim    // See comments above on the multilib variant for details of why this is
2544263508Sdim    // only included from within the sysroot.
2545263508Sdim    if (StringRef(LibPath).startswith(SysRoot))
2546234353Sdim      addPathIfExists(LibPath, Paths);
2547226633Sdim  }
2548226633Sdim  addPathIfExists(SysRoot + "/lib", Paths);
2549226633Sdim  addPathIfExists(SysRoot + "/usr/lib", Paths);
2550263508Sdim}
2551251662Sdim
2552263508Sdimbool FreeBSD::HasNativeLLVMSupport() const {
2553263508Sdim  return true;
2554218893Sdim}
2555218893Sdim
2556218893Sdimbool Linux::HasNativeLLVMSupport() const {
2557218893Sdim  return true;
2558218893Sdim}
2559218893Sdim
2560249423SdimTool *Linux::buildLinker() const {
2561249423Sdim  return new tools::gnutools::Link(*this);
2562249423Sdim}
2563212904Sdim
2564249423SdimTool *Linux::buildAssembler() const {
2565249423Sdim  return new tools::gnutools::Assemble(*this);
2566212904Sdim}
2567212904Sdim
2568249423Sdimvoid Linux::addClangTargetOptions(const ArgList &DriverArgs,
2569249423Sdim                                  ArgStringList &CC1Args) const {
2570239462Sdim  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
2571263508Sdim  bool UseInitArrayDefault =
2572263508Sdim      !V.isOlderThan(4, 7, 0) ||
2573249423Sdim      getTriple().getArch() == llvm::Triple::aarch64 ||
2574249423Sdim      getTriple().getEnvironment() == llvm::Triple::Android;
2575249423Sdim  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
2576249423Sdim                         options::OPT_fno_use_init_array,
2577249423Sdim                         UseInitArrayDefault))
2578239462Sdim    CC1Args.push_back("-fuse-init-array");
2579239462Sdim}
2580239462Sdim
2581263508Sdimstd::string Linux::computeSysRoot() const {
2582251662Sdim  if (!getDriver().SysRoot.empty())
2583251662Sdim    return getDriver().SysRoot;
2584251662Sdim
2585251662Sdim  if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
2586251662Sdim    return std::string();
2587251662Sdim
2588263508Sdim  // Standalone MIPS toolchains use different names for sysroot folder
2589263508Sdim  // and put it into different places. Here we try to check some known
2590263508Sdim  // variants.
2591251662Sdim
2592263508Sdim  const StringRef InstallDir = GCCInstallation.getInstallPath();
2593263508Sdim  const StringRef TripleStr = GCCInstallation.getTriple().str();
2594263508Sdim  const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
2595263508Sdim
2596263508Sdim  std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
2597263508Sdim                      MIPSABIDirSuffix).str();
2598263508Sdim
2599263508Sdim  if (llvm::sys::fs::exists(Path))
2600263508Sdim    return Path;
2601263508Sdim
2602263508Sdim  Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str();
2603263508Sdim
2604263508Sdim  if (llvm::sys::fs::exists(Path))
2605263508Sdim    return Path;
2606263508Sdim
2607263508Sdim  return std::string();
2608251662Sdim}
2609251662Sdim
2610228379Sdimvoid Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2611228379Sdim                                      ArgStringList &CC1Args) const {
2612228379Sdim  const Driver &D = getDriver();
2613263508Sdim  std::string SysRoot = computeSysRoot();
2614228379Sdim
2615228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc))
2616228379Sdim    return;
2617228379Sdim
2618228379Sdim  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
2619251662Sdim    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
2620228379Sdim
2621228379Sdim  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2622263508Sdim    SmallString<128> P(D.ResourceDir);
2623263508Sdim    llvm::sys::path::append(P, "include");
2624228379Sdim    addSystemInclude(DriverArgs, CC1Args, P.str());
2625228379Sdim  }
2626228379Sdim
2627228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2628228379Sdim    return;
2629228379Sdim
2630228379Sdim  // Check for configure-time C include directories.
2631228379Sdim  StringRef CIncludeDirs(C_INCLUDE_DIRS);
2632228379Sdim  if (CIncludeDirs != "") {
2633228379Sdim    SmallVector<StringRef, 5> dirs;
2634228379Sdim    CIncludeDirs.split(dirs, ":");
2635228379Sdim    for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end();
2636228379Sdim         I != E; ++I) {
2637251662Sdim      StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : "";
2638228379Sdim      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I);
2639228379Sdim    }
2640228379Sdim    return;
2641228379Sdim  }
2642228379Sdim
2643228379Sdim  // Lacking those, try to detect the correct set of system includes for the
2644228379Sdim  // target triple.
2645228379Sdim
2646251662Sdim  // Sourcery CodeBench and modern FSF Mips toolchains put extern C
2647251662Sdim  // system includes under three additional directories.
2648251662Sdim  if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) {
2649263508Sdim    addExternCSystemIncludeIfExists(
2650263508Sdim        DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include");
2651251662Sdim
2652263508Sdim    addExternCSystemIncludeIfExists(
2653263508Sdim        DriverArgs, CC1Args,
2654263508Sdim        GCCInstallation.getInstallPath() + "/../../../../" +
2655263508Sdim            GCCInstallation.getTriple().str() + "/libc/usr/include");
2656263508Sdim
2657263508Sdim    addExternCSystemIncludeIfExists(
2658263508Sdim        DriverArgs, CC1Args,
2659263508Sdim        GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include");
2660251662Sdim  }
2661251662Sdim
2662228379Sdim  // Implement generic Debian multiarch support.
2663228379Sdim  const StringRef X86_64MultiarchIncludeDirs[] = {
2664228379Sdim    "/usr/include/x86_64-linux-gnu",
2665228379Sdim
2666228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2667228379Sdim    // in use in any released version of Debian, so we should consider
2668228379Sdim    // removing them.
2669263508Sdim    "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"
2670228379Sdim  };
2671228379Sdim  const StringRef X86MultiarchIncludeDirs[] = {
2672228379Sdim    "/usr/include/i386-linux-gnu",
2673228379Sdim
2674228379Sdim    // FIXME: These are older forms of multiarch. It's not clear that they're
2675228379Sdim    // in use in any released version of Debian, so we should consider
2676228379Sdim    // removing them.
2677263508Sdim    "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
2678228379Sdim    "/usr/include/i486-linux-gnu"
2679228379Sdim  };
2680249423Sdim  const StringRef AArch64MultiarchIncludeDirs[] = {
2681249423Sdim    "/usr/include/aarch64-linux-gnu"
2682249423Sdim  };
2683228379Sdim  const StringRef ARMMultiarchIncludeDirs[] = {
2684228379Sdim    "/usr/include/arm-linux-gnueabi"
2685228379Sdim  };
2686239462Sdim  const StringRef ARMHFMultiarchIncludeDirs[] = {
2687239462Sdim    "/usr/include/arm-linux-gnueabihf"
2688239462Sdim  };
2689234353Sdim  const StringRef MIPSMultiarchIncludeDirs[] = {
2690234353Sdim    "/usr/include/mips-linux-gnu"
2691234353Sdim  };
2692234353Sdim  const StringRef MIPSELMultiarchIncludeDirs[] = {
2693234353Sdim    "/usr/include/mipsel-linux-gnu"
2694234353Sdim  };
2695234353Sdim  const StringRef PPCMultiarchIncludeDirs[] = {
2696234353Sdim    "/usr/include/powerpc-linux-gnu"
2697234353Sdim  };
2698234353Sdim  const StringRef PPC64MultiarchIncludeDirs[] = {
2699234353Sdim    "/usr/include/powerpc64-linux-gnu"
2700234353Sdim  };
2701228379Sdim  ArrayRef<StringRef> MultiarchIncludeDirs;
2702228379Sdim  if (getTriple().getArch() == llvm::Triple::x86_64) {
2703228379Sdim    MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
2704228379Sdim  } else if (getTriple().getArch() == llvm::Triple::x86) {
2705228379Sdim    MultiarchIncludeDirs = X86MultiarchIncludeDirs;
2706249423Sdim  } else if (getTriple().getArch() == llvm::Triple::aarch64) {
2707249423Sdim    MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
2708228379Sdim  } else if (getTriple().getArch() == llvm::Triple::arm) {
2709239462Sdim    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
2710239462Sdim      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
2711239462Sdim    else
2712239462Sdim      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
2713234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mips) {
2714234353Sdim    MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
2715234353Sdim  } else if (getTriple().getArch() == llvm::Triple::mipsel) {
2716234353Sdim    MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
2717234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc) {
2718234353Sdim    MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
2719234353Sdim  } else if (getTriple().getArch() == llvm::Triple::ppc64) {
2720234353Sdim    MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
2721228379Sdim  }
2722228379Sdim  for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(),
2723228379Sdim                                     E = MultiarchIncludeDirs.end();
2724228379Sdim       I != E; ++I) {
2725251662Sdim    if (llvm::sys::fs::exists(SysRoot + *I)) {
2726251662Sdim      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I);
2727228379Sdim      break;
2728228379Sdim    }
2729228379Sdim  }
2730228379Sdim
2731228379Sdim  if (getTriple().getOS() == llvm::Triple::RTEMS)
2732228379Sdim    return;
2733228379Sdim
2734234353Sdim  // Add an include of '/include' directly. This isn't provided by default by
2735234353Sdim  // system GCCs, but is often used with cross-compiling GCCs, and harmless to
2736234353Sdim  // add even when Clang is acting as-if it were a system compiler.
2737251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
2738234353Sdim
2739251662Sdim  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
2740228379Sdim}
2741228379Sdim
2742249423Sdim/// \brief Helper to add the three variant paths for a libstdc++ installation.
2743234353Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
2744234353Sdim                                                const ArgList &DriverArgs,
2745234353Sdim                                                ArgStringList &CC1Args) {
2746228379Sdim  if (!llvm::sys::fs::exists(Base))
2747228379Sdim    return false;
2748228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base);
2749228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir);
2750228379Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/backward");
2751228379Sdim  return true;
2752228379Sdim}
2753228379Sdim
2754249423Sdim/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
2755249423Sdim/// libstdc++ installation.
2756249423Sdim/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
2757249423Sdim                                                Twine TargetArchDir,
2758263508Sdim                                                Twine BiarchSuffix,
2759263508Sdim                                                Twine MIPSABIDirSuffix,
2760249423Sdim                                                const ArgList &DriverArgs,
2761249423Sdim                                                ArgStringList &CC1Args) {
2762263508Sdim  if (!addLibStdCXXIncludePaths(Base + Suffix,
2763263508Sdim                                TargetArchDir + MIPSABIDirSuffix + BiarchSuffix,
2764249423Sdim                                DriverArgs, CC1Args))
2765249423Sdim    return false;
2766249423Sdim
2767249423Sdim  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
2768263508Sdim                   + MIPSABIDirSuffix + BiarchSuffix);
2769249423Sdim  return true;
2770249423Sdim}
2771249423Sdim
2772228379Sdimvoid Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2773228379Sdim                                         ArgStringList &CC1Args) const {
2774228379Sdim  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2775228379Sdim      DriverArgs.hasArg(options::OPT_nostdincxx))
2776228379Sdim    return;
2777228379Sdim
2778228379Sdim  // Check if libc++ has been enabled and provide its include paths if so.
2779228379Sdim  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
2780228379Sdim    // libc++ is always installed at a fixed path on Linux currently.
2781228379Sdim    addSystemInclude(DriverArgs, CC1Args,
2782228379Sdim                     getDriver().SysRoot + "/usr/include/c++/v1");
2783228379Sdim    return;
2784228379Sdim  }
2785228379Sdim
2786234353Sdim  // We need a detected GCC installation on Linux to provide libstdc++'s
2787234353Sdim  // headers. We handled the libc++ case above.
2788234353Sdim  if (!GCCInstallation.isValid())
2789228379Sdim    return;
2790228379Sdim
2791228379Sdim  // By default, look for the C++ headers in an include directory adjacent to
2792228379Sdim  // the lib directory of the GCC installation. Note that this is expect to be
2793228379Sdim  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
2794228379Sdim  StringRef LibDir = GCCInstallation.getParentLibPath();
2795228379Sdim  StringRef InstallDir = GCCInstallation.getInstallPath();
2796243830Sdim  StringRef TripleStr = GCCInstallation.getTriple().str();
2797263508Sdim  StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
2798263508Sdim  StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix();
2799263508Sdim  const GCCVersion &Version = GCCInstallation.getVersion();
2800243830Sdim
2801263508Sdim  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
2802263508Sdim                               "/c++/" + Version.Text, TripleStr, BiarchSuffix,
2803263508Sdim                               MIPSABIDirSuffix, DriverArgs, CC1Args))
2804249423Sdim    return;
2805249423Sdim
2806243830Sdim  const std::string IncludePathCandidates[] = {
2807228379Sdim    // Gentoo is weird and places its headers inside the GCC install, so if the
2808263508Sdim    // first attempt to find the headers fails, try these patterns.
2809263508Sdim    InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
2810263508Sdim        Version.MinorStr,
2811263508Sdim    InstallDir.str() + "/include/g++-v" + Version.MajorStr,
2812243830Sdim    // Android standalone toolchain has C++ headers in yet another place.
2813263508Sdim    LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
2814243830Sdim    // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
2815243830Sdim    // without a subdirectory corresponding to the gcc version.
2816243830Sdim    LibDir.str() + "/../include/c++",
2817243830Sdim  };
2818243830Sdim
2819243830Sdim  for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
2820263508Sdim    if (addLibStdCXXIncludePaths(IncludePathCandidates[i],
2821263508Sdim                                 TripleStr + MIPSABIDirSuffix + BiarchSuffix,
2822263508Sdim                                 DriverArgs, CC1Args))
2823243830Sdim      break;
2824228379Sdim  }
2825228379Sdim}
2826228379Sdim
2827251662Sdimbool Linux::isPIEDefault() const {
2828263508Sdim  return getSanitizerArgs().hasZeroBaseShadow();
2829251662Sdim}
2830251662Sdim
2831193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
2832193326Sed
2833234353SdimDragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
2834234353Sdim  : Generic_ELF(D, Triple, Args) {
2835193326Sed
2836193326Sed  // Path mangling to find libexec
2837212904Sdim  getProgramPaths().push_back(getDriver().getInstalledDir());
2838221345Sdim  if (getDriver().getInstalledDir() != getDriver().Dir)
2839212904Sdim    getProgramPaths().push_back(getDriver().Dir);
2840193326Sed
2841201361Srdivacky  getFilePaths().push_back(getDriver().Dir + "/../lib");
2842193326Sed  getFilePaths().push_back("/usr/lib");
2843251662Sdim  if (llvm::sys::fs::exists("/usr/lib/gcc47"))
2844251662Sdim    getFilePaths().push_back("/usr/lib/gcc47");
2845251662Sdim  else
2846251662Sdim    getFilePaths().push_back("/usr/lib/gcc44");
2847193326Sed}
2848193326Sed
2849249423SdimTool *DragonFly::buildAssembler() const {
2850249423Sdim  return new tools::dragonfly::Assemble(*this);
2851249423Sdim}
2852193326Sed
2853249423SdimTool *DragonFly::buildLinker() const {
2854249423Sdim  return new tools::dragonfly::Link(*this);
2855193326Sed}
2856263508Sdim
2857263508Sdim
2858263508Sdim/// XCore tool chain
2859263508SdimXCore::XCore(const Driver &D, const llvm::Triple &Triple,
2860263508Sdim             const ArgList &Args) : ToolChain(D, Triple, Args) {
2861263508Sdim  // ProgramPaths are found via 'PATH' environment variable.
2862263508Sdim}
2863263508Sdim
2864263508SdimTool *XCore::buildAssembler() const {
2865263508Sdim  return new tools::XCore::Assemble(*this);
2866263508Sdim}
2867263508Sdim
2868263508SdimTool *XCore::buildLinker() const {
2869263508Sdim  return new tools::XCore::Link(*this);
2870263508Sdim}
2871263508Sdim
2872263508Sdimbool XCore::isPICDefault() const {
2873263508Sdim  return false;
2874263508Sdim}
2875263508Sdim
2876263508Sdimbool XCore::isPIEDefault() const {
2877263508Sdim  return false;
2878263508Sdim}
2879263508Sdim
2880263508Sdimbool XCore::isPICDefaultForced() const {
2881263508Sdim  return false;
2882263508Sdim}
2883263508Sdim
2884263508Sdimbool XCore::SupportsProfiling() const {
2885263508Sdim  return false;
2886263508Sdim}
2887263508Sdim
2888263508Sdimbool XCore::hasBlocksRuntime() const {
2889263508Sdim  return false;
2890263508Sdim}
2891263508Sdim
2892263508Sdim
2893263508Sdimvoid XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
2894263508Sdim                                      ArgStringList &CC1Args) const {
2895263508Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
2896263508Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
2897263508Sdim    return;
2898263508Sdim  if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
2899263508Sdim    SmallVector<StringRef, 4> Dirs;
2900263508Sdim    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
2901263508Sdim    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
2902263508Sdim    ArrayRef<StringRef> DirVec(Dirs);
2903263508Sdim    addSystemIncludes(DriverArgs, CC1Args, DirVec);
2904263508Sdim  }
2905263508Sdim}
2906263508Sdim
2907263508Sdimvoid XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
2908263508Sdim                                     llvm::opt::ArgStringList &CC1Args) const {
2909263508Sdim  CC1Args.push_back("-nostdsysteminc");
2910263508Sdim}
2911263508Sdim
2912263508Sdimvoid XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
2913263508Sdim                                         ArgStringList &CC1Args) const {
2914263508Sdim  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
2915263508Sdim      DriverArgs.hasArg(options::OPT_nostdlibinc))
2916263508Sdim    return;
2917263508Sdim  if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
2918263508Sdim    SmallVector<StringRef, 4> Dirs;
2919263508Sdim    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
2920263508Sdim    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
2921263508Sdim    ArrayRef<StringRef> DirVec(Dirs);
2922263508Sdim    addSystemIncludes(DriverArgs, CC1Args, DirVec);
2923263508Sdim  }
2924263508Sdim}
2925263508Sdim
2926263508Sdimvoid XCore::AddCXXStdlibLibArgs(const ArgList &Args,
2927263508Sdim                                ArgStringList &CmdArgs) const {
2928263508Sdim  // We don't output any lib args. This is handled by xcc.
2929263508Sdim}
2930