//===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Gnu.h"
#include "Arch/ARM.h"
#include "Arch/Mips.h"
#include "Arch/PPC.h"
#include "Arch/RISCV.h"
#include "Arch/Sparc.h"
#include "Arch/SystemZ.h"
#include "CommonArgs.h"
#include "Linux.h"
#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <system_error>

using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;

using tools::addMultilibFlag;
using tools::addPathIfExists;

static bool forwardToGCC(const Option &O) {
  // LinkerInput options have been forwarded. Don't duplicate.
  if (O.hasFlag(options::LinkerInput))
    return false;
  return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption);
}

// Switch CPU names not recognized by GNU assembler to a close CPU that it does
// recognize, instead of a lower march from being picked in the absence of a cpu
// flag.
static void normalizeCPUNamesForAssembler(const ArgList &Args,
                                          ArgStringList &CmdArgs) {
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
    StringRef CPUArg(A->getValue());
    if (CPUArg.equals_insensitive("krait"))
      CmdArgs.push_back("-mcpu=cortex-a15");
    else if (CPUArg.equals_insensitive("kryo"))
      CmdArgs.push_back("-mcpu=cortex-a57");
    else
      Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
  }
}

void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
                                      const InputInfo &Output,
                                      const InputInfoList &Inputs,
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
  const Driver &D = getToolChain().getDriver();
  ArgStringList CmdArgs;

  for (const auto &A : Args) {
    if (forwardToGCC(A->getOption())) {
      // It is unfortunate that we have to claim here, as this means
      // we will basically never report anything interesting for
      // platforms using a generic gcc, even if we are just using gcc
      // to get to the assembler.
      A->claim();

      A->render(Args, CmdArgs);
    }
  }

  RenderExtraToolArgs(JA, CmdArgs);

  // If using a driver driver, force the arch.
  if (getToolChain().getTriple().isOSDarwin()) {
    CmdArgs.push_back("-arch");
    CmdArgs.push_back(
        Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
  }

  // Try to force gcc to match the tool chain we want, if we recognize
  // the arch.
  //
  // FIXME: The triple class should directly provide the information we want
  // here.
  switch (getToolChain().getArch()) {
  default:
    break;
  case llvm::Triple::x86:
  case llvm::Triple::ppc:
  case llvm::Triple::ppcle:
    CmdArgs.push_back("-m32");
    break;
  case llvm::Triple::x86_64:
  case llvm::Triple::ppc64:
  case llvm::Triple::ppc64le:
    CmdArgs.push_back("-m64");
    break;
  case llvm::Triple::sparcel:
    CmdArgs.push_back("-EL");
    break;
  }

  if (Output.isFilename()) {
    CmdArgs.push_back("-o");
    CmdArgs.push_back(Output.getFilename());
  } else {
    assert(Output.isNothing() && "Unexpected output");
    CmdArgs.push_back("-fsyntax-only");
  }

  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

  // Only pass -x if gcc will understand it; otherwise hope gcc
  // understands the suffix correctly. The main use case this would go
  // wrong in is for linker inputs if they happened to have an odd
  // suffix; really the only way to get this to happen is a command
  // like '-x foobar a.c' which will treat a.c like a linker input.
  //
  // FIXME: For the linker case specifically, can we safely convert
  // inputs into '-Wl,' options?
  for (const auto &II : Inputs) {
    // Don't try to pass LLVM or AST inputs to a generic gcc.
    if (types::isLLVMIR(II.getType()))
      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
          << getToolChain().getTripleString();
    else if (II.getType() == types::TY_AST)
      D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString();
    else if (II.getType() == types::TY_ModuleFile)
      D.Diag(diag::err_drv_no_module_support)
          << getToolChain().getTripleString();

    if (types::canTypeBeUserSpecified(II.getType())) {
      CmdArgs.push_back("-x");
      CmdArgs.push_back(types::getTypeName(II.getType()));
    }

    if (II.isFilename())
      CmdArgs.push_back(II.getFilename());
    else {
      const Arg &A = II.getInputArg();

      // Reverse translate some rewritten options.
      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
        CmdArgs.push_back("-lstdc++");
        continue;
      }

      // Don't render as input, we need gcc to do the translations.
      A.render(Args, CmdArgs);
    }
  }

  const std::string &customGCCName = D.getCCCGenericGCCName();
  const char *GCCName;
  if (!customGCCName.empty())
    GCCName = customGCCName.c_str();
  else if (D.CCCIsCXX()) {
    GCCName = "g++";
  } else
    GCCName = "gcc";

  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
  C.addCommand(std::make_unique<Command>(JA, *this,
                                         ResponseFileSupport::AtFileCurCP(),
                                         Exec, CmdArgs, Inputs, Output));
}

void tools::gcc::Preprocessor::RenderExtraToolArgs(
    const JobAction &JA, ArgStringList &CmdArgs) const {
  CmdArgs.push_back("-E");
}

void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,
                                               ArgStringList &CmdArgs) const {
  const Driver &D = getToolChain().getDriver();

  switch (JA.getType()) {
  // If -flto, etc. are present then make sure not to force assembly output.
  case types::TY_LLVM_IR:
  case types::TY_LTO_IR:
  case types::TY_LLVM_BC:
  case types::TY_LTO_BC:
    CmdArgs.push_back("-c");
    break;
  // We assume we've got an "integrated" assembler in that gcc will produce an
  // object file itself.
  case types::TY_Object:
    CmdArgs.push_back("-c");
    break;
  case types::TY_PP_Asm:
    CmdArgs.push_back("-S");
    break;
  case types::TY_Nothing:
    CmdArgs.push_back("-fsyntax-only");
    break;
  default:
    D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());
  }
}

void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
                                             ArgStringList &CmdArgs) const {
  // The types are (hopefully) good enough.
}

// On Arm the endianness of the output file is determined by the target and
// can be overridden by the pseudo-target flags '-mlittle-endian'/'-EL' and
// '-mbig-endian'/'-EB'. Unlike other targets the flag does not result in a
// normalized triple so we must handle the flag here.
static bool isArmBigEndian(const llvm::Triple &Triple,
                           const ArgList &Args) {
  bool IsBigEndian = false;
  switch (Triple.getArch()) {
  case llvm::Triple::armeb:
  case llvm::Triple::thumbeb:
    IsBigEndian = true;
    LLVM_FALLTHROUGH;
  case llvm::Triple::arm:
  case llvm::Triple::thumb:
    if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
                               options::OPT_mbig_endian))
      IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
    break;
  default:
    break;
  }
  return IsBigEndian;
}

static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
  switch (T.getArch()) {
  case llvm::Triple::x86:
    if (T.isOSIAMCU())
      return "elf_iamcu";
    return "elf_i386";
  case llvm::Triple::aarch64:
    return "aarch64linux";
  case llvm::Triple::aarch64_be:
    return "aarch64linuxb";
  case llvm::Triple::arm:
  case llvm::Triple::thumb:
  case llvm::Triple::armeb:
  case llvm::Triple::thumbeb:
    return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi";
  case llvm::Triple::m68k:
    return "m68kelf";
  case llvm::Triple::ppc:
    if (T.isOSLinux())
      return "elf32ppclinux";
    return "elf32ppc";
  case llvm::Triple::ppcle:
    if (T.isOSLinux())
      return "elf32lppclinux";
    return "elf32lppc";
  case llvm::Triple::ppc64:
    return "elf64ppc";
  case llvm::Triple::ppc64le:
    return "elf64lppc";
  case llvm::Triple::riscv32:
    return "elf32lriscv";
  case llvm::Triple::riscv64:
    return "elf64lriscv";
  case llvm::Triple::sparc:
  case llvm::Triple::sparcel:
    return "elf32_sparc";
  case llvm::Triple::sparcv9:
    return "elf64_sparc";
  case llvm::Triple::mips:
    return "elf32btsmip";
  case llvm::Triple::mipsel:
    return "elf32ltsmip";
  case llvm::Triple::mips64:
    if (tools::mips::hasMipsAbiArg(Args, "n32") ||
        T.getEnvironment() == llvm::Triple::GNUABIN32)
      return "elf32btsmipn32";
    return "elf64btsmip";
  case llvm::Triple::mips64el:
    if (tools::mips::hasMipsAbiArg(Args, "n32") ||
        T.getEnvironment() == llvm::Triple::GNUABIN32)
      return "elf32ltsmipn32";
    return "elf64ltsmip";
  case llvm::Triple::systemz:
    return "elf64_s390";
  case llvm::Triple::x86_64:
    if (T.isX32())
      return "elf32_x86_64";
    return "elf_x86_64";
  case llvm::Triple::ve:
    return "elf64ve";
  default:
    return nullptr;
  }
}

static bool getPIE(const ArgList &Args, const ToolChain &TC) {
  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) ||
      Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie))
    return false;

  Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
                           options::OPT_nopie);
  if (!A)
    return TC.isPIEDefault();
  return A->getOption().matches(options::OPT_pie);
}

static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
  bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
  // -no-pie is an alias for -nopie. So, handling -nopie takes care of
  // -no-pie as well.
  if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) {
    const Driver &D = TC.getDriver();
    const llvm::opt::OptTable &Opts = D.getOpts();
    const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
    const char *NoPIEName = Opts.getOptionName(options::OPT_nopie);
    D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
  }
  return HasStaticPIE;
}

static bool getStatic(const ArgList &Args) {
  return Args.hasArg(options::OPT_static) &&
      !Args.hasArg(options::OPT_static_pie);
}

void tools::gnutools::StaticLibTool::ConstructJob(
    Compilation &C, const JobAction &JA, const InputInfo &Output,
    const InputInfoList &Inputs, const ArgList &Args,
    const char *LinkingOutput) const {
  const Driver &D = getToolChain().getDriver();

  // Silence warning for "clang -g foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_g_Group);
  // and "clang -emit-llvm foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_emit_llvm);
  // and for "clang -w foo.o -o foo". Other warning options are already
  // handled somewhere else.
  Args.ClaimAllArgs(options::OPT_w);
  // Silence warnings when linking C code with a C++ '-stdlib' argument.
  Args.ClaimAllArgs(options::OPT_stdlib_EQ);

  // ar tool command "llvm-ar <options> <output_file> <input_files>".
  ArgStringList CmdArgs;
  // Create and insert file members with a deterministic index.
  CmdArgs.push_back("rcsD");
  CmdArgs.push_back(Output.getFilename());

  for (const auto &II : Inputs) {
    if (II.isFilename()) {
       CmdArgs.push_back(II.getFilename());
    }
  }

  // Delete old output archive file if it already exists before generating a new
  // archive file.
  auto OutputFileName = Output.getFilename();
  if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {
    if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
      D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
      return;
    }
  }

  const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
  C.addCommand(std::make_unique<Command>(JA, *this,
                                         ResponseFileSupport::AtFileCurCP(),
                                         Exec, CmdArgs, Inputs, Output));
}

void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                           const InputInfo &Output,
                                           const InputInfoList &Inputs,
                                           const ArgList &Args,
                                           const char *LinkingOutput) const {
  // FIXME: The Linker class constructor takes a ToolChain and not a
  // Generic_ELF, so the static_cast might return a reference to a invalid
  // instance (see PR45061). Ideally, the Linker constructor needs to take a
  // Generic_ELF instead.
  const toolchains::Generic_ELF &ToolChain =
      static_cast<const toolchains::Generic_ELF &>(getToolChain());
  const Driver &D = ToolChain.getDriver();

  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();

  const llvm::Triple::ArchType Arch = ToolChain.getArch();
  const bool isAndroid = ToolChain.getTriple().isAndroid();
  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
  const bool IsVE = ToolChain.getTriple().isVE();
  const bool IsPIE = getPIE(Args, ToolChain);
  const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
  const bool IsStatic = getStatic(Args);
  const bool HasCRTBeginEndFiles =
      ToolChain.getTriple().hasEnvironment() ||
      (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);

  ArgStringList CmdArgs;

  // Silence warning for "clang -g foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_g_Group);
  // and "clang -emit-llvm foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_emit_llvm);
  // and for "clang -w foo.o -o foo". Other warning options are already
  // handled somewhere else.
  Args.ClaimAllArgs(options::OPT_w);

  if (!D.SysRoot.empty())
    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));

  if (IsPIE)
    CmdArgs.push_back("-pie");

  if (IsStaticPIE) {
    CmdArgs.push_back("-static");
    CmdArgs.push_back("-pie");
    CmdArgs.push_back("--no-dynamic-linker");
    CmdArgs.push_back("-z");
    CmdArgs.push_back("text");
  }

  if (ToolChain.isNoExecStackDefault()) {
    CmdArgs.push_back("-z");
    CmdArgs.push_back("noexecstack");
  }

  if (Args.hasArg(options::OPT_rdynamic))
    CmdArgs.push_back("-export-dynamic");

  if (Args.hasArg(options::OPT_s))
    CmdArgs.push_back("-s");

  if (Triple.isARM() || Triple.isThumb() || Triple.isAArch64()) {
    bool IsBigEndian = isArmBigEndian(Triple, Args);
    if (IsBigEndian)
      arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
    IsBigEndian = IsBigEndian || Arch == llvm::Triple::aarch64_be;
    CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
  }

  // Most Android ARM64 targets should enable the linker fix for erratum
  // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
  if (Arch == llvm::Triple::aarch64 && isAndroid) {
    std::string CPU = getCPUName(Args, Triple);
    if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
      CmdArgs.push_back("--fix-cortex-a53-843419");
  }

  // Android does not allow shared text relocations. Emit a warning if the
  // user's code contains any.
  if (isAndroid)
      CmdArgs.push_back("--warn-shared-textrel");

  ToolChain.addExtraOpts(CmdArgs);

  CmdArgs.push_back("--eh-frame-hdr");

  if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) {
    CmdArgs.push_back("-m");
    CmdArgs.push_back(LDMOption);
  } else {
    D.Diag(diag::err_target_unknown_triple) << Triple.str();
    return;
  }

  if (IsStatic) {
    if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
        Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb)
      CmdArgs.push_back("-Bstatic");
    else
      CmdArgs.push_back("-static");
  } else if (Args.hasArg(options::OPT_shared)) {
    CmdArgs.push_back("-shared");
  }

  if (!IsStatic) {
    if (Args.hasArg(options::OPT_rdynamic))
      CmdArgs.push_back("-export-dynamic");

    if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE) {
      CmdArgs.push_back("-dynamic-linker");
      CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
                                           ToolChain.getDynamicLinker(Args)));
    }
  }

  CmdArgs.push_back("-o");
  CmdArgs.push_back(Output.getFilename());

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
    if (!isAndroid && !IsIAMCU) {
      const char *crt1 = nullptr;
      if (!Args.hasArg(options::OPT_shared)) {
        if (Args.hasArg(options::OPT_pg))
          crt1 = "gcrt1.o";
        else if (IsPIE)
          crt1 = "Scrt1.o";
        else if (IsStaticPIE)
          crt1 = "rcrt1.o";
        else
          crt1 = "crt1.o";
      }
      if (crt1)
        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));

      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
    }

    if (IsVE) {
      CmdArgs.push_back("-z");
      CmdArgs.push_back("max-page-size=0x4000000");
    }

    if (IsIAMCU)
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
    else if (HasCRTBeginEndFiles) {
      std::string P;
      if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
          !isAndroid) {
        std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin",
                                                       ToolChain::FT_Object);
        if (ToolChain.getVFS().exists(crtbegin))
          P = crtbegin;
      }
      if (P.empty()) {
        const char *crtbegin;
        if (IsStatic)
          crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
        else if (Args.hasArg(options::OPT_shared))
          crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
        else if (IsPIE || IsStaticPIE)
          crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
        else
          crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
        P = ToolChain.GetFilePath(crtbegin);
      }
      CmdArgs.push_back(Args.MakeArgString(P));
    }

    // Add crtfastmath.o if available and fast math is enabled.
    ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs);
  }

  Args.AddAllArgs(CmdArgs, options::OPT_L);
  Args.AddAllArgs(CmdArgs, options::OPT_u);

  ToolChain.AddFilePathLibArgs(Args, CmdArgs);

  if (D.isUsingLTO()) {
    assert(!Inputs.empty() && "Must have at least one input.");
    addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0],
                  D.getLTOMode() == LTOK_Thin);
  }

  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
    CmdArgs.push_back("--no-demangle");

  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
  addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
  // The profile runtime also needs access to system libraries.
  getToolChain().addProfileRTLibs(Args, CmdArgs);

  if (D.CCCIsCXX() &&
      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
    if (ToolChain.ShouldLinkCXXStdlib(Args)) {
      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
                                 !Args.hasArg(options::OPT_static);
      if (OnlyLibstdcxxStatic)
        CmdArgs.push_back("-Bstatic");
      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
      if (OnlyLibstdcxxStatic)
        CmdArgs.push_back("-Bdynamic");
    }
    CmdArgs.push_back("-lm");
  }
  // Silence warnings when linking C code with a C++ '-stdlib' argument.
  Args.ClaimAllArgs(options::OPT_stdlib_EQ);

  if (!Args.hasArg(options::OPT_nostdlib)) {
    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
      if (IsStatic || IsStaticPIE)
        CmdArgs.push_back("--start-group");

      if (NeedsSanitizerDeps)
        linkSanitizerRuntimeDeps(ToolChain, CmdArgs);

      if (NeedsXRayDeps)
        linkXRayRuntimeDeps(ToolChain, CmdArgs);

      bool WantPthread = Args.hasArg(options::OPT_pthread) ||
                         Args.hasArg(options::OPT_pthreads);

      // Use the static OpenMP runtime with -static-openmp
      bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
                          !Args.hasArg(options::OPT_static);

      // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that
      // require librt. Most modern Linux platforms do, but some may not.
      if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP,
                           JA.isHostOffloading(Action::OFK_OpenMP),
                           /* GompNeedsRT= */ true))
        // OpenMP runtimes implies pthreads when using the GNU toolchain.
        // FIXME: Does this really make sense for all GNU toolchains?
        WantPthread = true;

      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);

      if (WantPthread && !isAndroid)
        CmdArgs.push_back("-lpthread");

      if (Args.hasArg(options::OPT_fsplit_stack))
        CmdArgs.push_back("--wrap=pthread_create");

      if (!Args.hasArg(options::OPT_nolibc))
        CmdArgs.push_back("-lc");

      // Add IAMCU specific libs, if needed.
      if (IsIAMCU)
        CmdArgs.push_back("-lgloss");

      if (IsStatic || IsStaticPIE)
        CmdArgs.push_back("--end-group");
      else
        AddRunTimeLibs(ToolChain, D, CmdArgs, Args);

      // Add IAMCU specific libs (outside the group), if needed.
      if (IsIAMCU) {
        CmdArgs.push_back("--as-needed");
        CmdArgs.push_back("-lsoftfp");
        CmdArgs.push_back("--no-as-needed");
      }
    }

    if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
      if (HasCRTBeginEndFiles) {
        std::string P;
        if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
            !isAndroid) {
          std::string crtend = ToolChain.getCompilerRT(Args, "crtend",
                                                       ToolChain::FT_Object);
          if (ToolChain.getVFS().exists(crtend))
            P = crtend;
        }
        if (P.empty()) {
          const char *crtend;
          if (Args.hasArg(options::OPT_shared))
            crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
          else if (IsPIE || IsStaticPIE)
            crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
          else
            crtend = isAndroid ? "crtend_android.o" : "crtend.o";
          P = ToolChain.GetFilePath(crtend);
        }
        CmdArgs.push_back(Args.MakeArgString(P));
      }
      if (!isAndroid)
        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
    }
  }

  Args.AddAllArgs(CmdArgs, options::OPT_T);

  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
  C.addCommand(std::make_unique<Command>(JA, *this,
                                         ResponseFileSupport::AtFileCurCP(),
                                         Exec, CmdArgs, Inputs, Output));
}

void tools::gnutools::Assembler::ConstructJob(Compilation &C,
                                              const JobAction &JA,
                                              const InputInfo &Output,
                                              const InputInfoList &Inputs,
                                              const ArgList &Args,
                                              const char *LinkingOutput) const {
  const auto &D = getToolChain().getDriver();

  claimNoWarnArgs(Args);

  ArgStringList CmdArgs;

  llvm::Reloc::Model RelocationModel;
  unsigned PICLevel;
  bool IsPIE;
  const char *DefaultAssembler = "as";
  std::tie(RelocationModel, PICLevel, IsPIE) =
      ParsePICArgs(getToolChain(), Args);

  if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) {
    if (A->getOption().getID() == options::OPT_gz) {
      CmdArgs.push_back("--compress-debug-sections");
    } else {
      StringRef Value = A->getValue();
      if (Value == "none" || Value == "zlib" || Value == "zlib-gnu") {
        CmdArgs.push_back(
            Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
      } else {
        D.Diag(diag::err_drv_unsupported_option_argument)
            << A->getOption().getName() << Value;
      }
    }
  }

  if (getToolChain().isNoExecStackDefault()) {
      CmdArgs.push_back("--noexecstack");
  }

  switch (getToolChain().getArch()) {
  default:
    break;
  // Add --32/--64 to make sure we get the format we want.
  // This is incomplete
  case llvm::Triple::x86:
    CmdArgs.push_back("--32");
    break;
  case llvm::Triple::x86_64:
    if (getToolChain().getTriple().isX32())
      CmdArgs.push_back("--x32");
    else
      CmdArgs.push_back("--64");
    break;
  case llvm::Triple::ppc: {
    CmdArgs.push_back("-a32");
    CmdArgs.push_back("-mppc");
    CmdArgs.push_back("-mbig-endian");
    CmdArgs.push_back(
      ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
    break;
  }
  case llvm::Triple::ppcle: {
    CmdArgs.push_back("-a32");
    CmdArgs.push_back("-mppc");
    CmdArgs.push_back("-mlittle-endian");
    CmdArgs.push_back(
        ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
    break;
  }
  case llvm::Triple::ppc64: {
    CmdArgs.push_back("-a64");
    CmdArgs.push_back("-mppc64");
    CmdArgs.push_back("-mbig-endian");
    CmdArgs.push_back(
      ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
    break;
  }
  case llvm::Triple::ppc64le: {
    CmdArgs.push_back("-a64");
    CmdArgs.push_back("-mppc64");
    CmdArgs.push_back("-mlittle-endian");
    CmdArgs.push_back(
      ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
    break;
  }
  case llvm::Triple::riscv32:
  case llvm::Triple::riscv64: {
    StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
    CmdArgs.push_back("-mabi");
    CmdArgs.push_back(ABIName.data());
    StringRef MArchName = riscv::getRISCVArch(Args, getToolChain().getTriple());
    CmdArgs.push_back("-march");
    CmdArgs.push_back(MArchName.data());
    break;
  }
  case llvm::Triple::sparc:
  case llvm::Triple::sparcel: {
    CmdArgs.push_back("-32");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(
        sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }
  case llvm::Triple::sparcv9: {
    CmdArgs.push_back("-64");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(
        sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }
  case llvm::Triple::arm:
  case llvm::Triple::armeb:
  case llvm::Triple::thumb:
  case llvm::Triple::thumbeb: {
    const llvm::Triple &Triple2 = getToolChain().getTriple();
    CmdArgs.push_back(isArmBigEndian(Triple2, Args) ? "-EB" : "-EL");
    switch (Triple2.getSubArch()) {
    case llvm::Triple::ARMSubArch_v7:
      CmdArgs.push_back("-mfpu=neon");
      break;
    case llvm::Triple::ARMSubArch_v8:
      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
      break;
    default:
      break;
    }

    switch (arm::getARMFloatABI(getToolChain(), Args)) {
    case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
    case arm::FloatABI::Soft:
      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));
      break;
    case arm::FloatABI::SoftFP:
      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));
      break;
    case arm::FloatABI::Hard:
      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));
      break;
    }

    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
    normalizeCPUNamesForAssembler(Args, CmdArgs);

    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
    break;
  }
  case llvm::Triple::aarch64:
  case llvm::Triple::aarch64_be: {
    CmdArgs.push_back(
        getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL");
    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
    normalizeCPUNamesForAssembler(Args, CmdArgs);

    break;
  }
  case llvm::Triple::mips:
  case llvm::Triple::mipsel:
  case llvm::Triple::mips64:
  case llvm::Triple::mips64el: {
    StringRef CPUName;
    StringRef ABIName;
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
    ABIName = mips::getGnuCompatibleMipsABIName(ABIName);

    CmdArgs.push_back("-march");
    CmdArgs.push_back(CPUName.data());

    CmdArgs.push_back("-mabi");
    CmdArgs.push_back(ABIName.data());

    // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
    // or -mshared (not implemented) is in effect.
    if (RelocationModel == llvm::Reloc::Static)
      CmdArgs.push_back("-mno-shared");

    // LLVM doesn't support -mplt yet and acts as if it is always given.
    // However, -mplt has no effect with the N64 ABI.
    if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls))
      CmdArgs.push_back("-call_nonpic");

    if (getToolChain().getTriple().isLittleEndian())
      CmdArgs.push_back("-EL");
    else
      CmdArgs.push_back("-EB");

    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
      if (StringRef(A->getValue()) == "2008")
        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
    }

    // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
                                 options::OPT_mfp64)) {
      A->claim();
      A->render(Args, CmdArgs);
    } else if (mips::shouldUseFPXX(
                   Args, getToolChain().getTriple(), CPUName, ABIName,
                   mips::getMipsFloatABI(getToolChain().getDriver(), Args,
                                         getToolChain().getTriple())))
      CmdArgs.push_back("-mfpxx");

    // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
    // -mno-mips16 is actually -no-mips16.
    if (Arg *A =
            Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {
      if (A->getOption().matches(options::OPT_mips16)) {
        A->claim();
        A->render(Args, CmdArgs);
      } else {
        A->claim();
        CmdArgs.push_back("-no-mips16");
      }
    }

    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
                    options::OPT_mno_micromips);
    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);

    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
      // Do not use AddLastArg because not all versions of MIPS assembler
      // support -mmsa / -mno-msa options.
      if (A->getOption().matches(options::OPT_mmsa))
        CmdArgs.push_back(Args.MakeArgString("-mmsa"));
    }

    Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
                    options::OPT_msoft_float);

    Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,
                    options::OPT_msingle_float);

    Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
                    options::OPT_mno_odd_spreg);

    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }
  case llvm::Triple::systemz: {
    // Always pass an -march option, since our default of z10 is later
    // than the GNU assembler's default.
    std::string CPUName = systemz::getSystemZTargetCPU(Args);
    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
    break;
  }
  case llvm::Triple::ve:
    DefaultAssembler = "nas";
  }

  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
                                    options::OPT_fdebug_prefix_map_EQ)) {
    StringRef Map = A->getValue();
    if (Map.find('=') == StringRef::npos)
      D.Diag(diag::err_drv_invalid_argument_to_option)
          << Map << A->getOption().getName();
    else {
      CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map"));
      CmdArgs.push_back(Args.MakeArgString(Map));
    }
    A->claim();
  }

  Args.AddAllArgs(CmdArgs, options::OPT_I);
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

  CmdArgs.push_back("-o");
  CmdArgs.push_back(Output.getFilename());

  for (const auto &II : Inputs)
    CmdArgs.push_back(II.getFilename());

  const char *Exec =
      Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));
  C.addCommand(std::make_unique<Command>(JA, *this,
                                         ResponseFileSupport::AtFileCurCP(),
                                         Exec, CmdArgs, Inputs, Output));

  // Handle the debug info splitting at object creation time if we're
  // creating an object.
  // TODO: Currently only works on linux with newer objcopy.
  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
      getToolChain().getTriple().isOSLinux())
    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
                   SplitDebugName(JA, Args, Inputs[0], Output));
}

namespace {
// Filter to remove Multilibs that don't exist as a suffix to Path
class FilterNonExistent {
  StringRef Base, File;
  llvm::vfs::FileSystem &VFS;

public:
  FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS)
      : Base(Base), File(File), VFS(VFS) {}
  bool operator()(const Multilib &M) {
    return !VFS.exists(Base + M.gccSuffix() + File);
  }
};
} // end anonymous namespace

static bool isSoftFloatABI(const ArgList &Args) {
  Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
                           options::OPT_mfloat_abi_EQ);
  if (!A)
    return false;

  return A->getOption().matches(options::OPT_msoft_float) ||
         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
          A->getValue() == StringRef("soft"));
}

static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
  return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
}

static bool isMipsEL(llvm::Triple::ArchType Arch) {
  return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
}

static bool isMips16(const ArgList &Args) {
  Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
  return A && A->getOption().matches(options::OPT_mips16);
}

static bool isMicroMips(const ArgList &Args) {
  Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
  return A && A->getOption().matches(options::OPT_mmicromips);
}

static bool isMSP430(llvm::Triple::ArchType Arch) {
  return Arch == llvm::Triple::msp430;
}

static Multilib makeMultilib(StringRef commonSuffix) {
  return Multilib(commonSuffix, commonSuffix, commonSuffix);
}

static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
                                FilterNonExistent &NonExistent,
                                DetectedMultilibs &Result) {
  // Check for Code Sourcery toolchain multilibs
  MultilibSet CSMipsMultilibs;
  {
    auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");

    auto MArchMicroMips =
        makeMultilib("/micromips").flag("+m32").flag("+mmicromips");

    auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");

    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");

    auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");

    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");

    auto DefaultFloat =
        makeMultilib("").flag("-msoft-float").flag("-mnan=2008");

    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");

    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");

    // Note that this one's osSuffix is ""
    auto MAbi64 = makeMultilib("")
                      .gccSuffix("/64")
                      .includeSuffix("/64")
                      .flag("+mabi=n64")
                      .flag("-mabi=n32")
                      .flag("-m32");

    CSMipsMultilibs =
        MultilibSet()
            .Either(MArchMips16, MArchMicroMips, MArchDefault)
            .Maybe(UCLibc)
            .Either(SoftFloat, Nan2008, DefaultFloat)
            .FilterOut("/micromips/nan2008")
            .FilterOut("/mips16/nan2008")
            .Either(BigEndian, LittleEndian)
            .Maybe(MAbi64)
            .FilterOut("/mips16.*/64")
            .FilterOut("/micromips.*/64")
            .FilterOut(NonExistent)
            .setIncludeDirsCallback([](const Multilib &M) {
              std::vector<std::string> Dirs({"/include"});
              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
                Dirs.push_back(
                    "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
              else
                Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
              return Dirs;
            });
  }

  MultilibSet DebianMipsMultilibs;
  {
    Multilib MAbiN32 =
        Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");

    Multilib M64 = Multilib()
                       .gccSuffix("/64")
                       .includeSuffix("/64")
                       .flag("+m64")
                       .flag("-m32")
                       .flag("-mabi=n32");

    Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");

    DebianMipsMultilibs =
        MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
  }

  // Sort candidates. Toolchain that best meets the directories tree goes first.
  // Then select the first toolchains matches command line flags.
  MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
  if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
    std::iter_swap(Candidates, Candidates + 1);
  for (const MultilibSet *Candidate : Candidates) {
    if (Candidate->select(Flags, Result.SelectedMultilib)) {
      if (Candidate == &DebianMipsMultilibs)
        Result.BiarchSibling = Multilib();
      Result.Multilibs = *Candidate;
      return true;
    }
  }
  return false;
}

static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path,
                                     const Multilib::flags_list &Flags,
                                     FilterNonExistent &NonExistent,
                                     DetectedMultilibs &Result) {

  MultilibSet AndroidMipsMultilibs =
      MultilibSet()
          .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
          .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
          .FilterOut(NonExistent);

  MultilibSet AndroidMipselMultilibs =
      MultilibSet()
          .Either(Multilib().flag("+march=mips32"),
                  Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
                  Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
          .FilterOut(NonExistent);

  MultilibSet AndroidMips64elMultilibs =
      MultilibSet()
          .Either(
              Multilib().flag("+march=mips64r6"),
              Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
              Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
              Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
          .FilterOut(NonExistent);

  MultilibSet *MS = &AndroidMipsMultilibs;
  if (VFS.exists(Path + "/mips-r6"))
    MS = &AndroidMipselMultilibs;
  else if (VFS.exists(Path + "/32"))
    MS = &AndroidMips64elMultilibs;
  if (MS->select(Flags, Result.SelectedMultilib)) {
    Result.Multilibs = *MS;
    return true;
  }
  return false;
}

static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
                                  FilterNonExistent &NonExistent,
                                  DetectedMultilibs &Result) {
  // Musl toolchain multilibs
  MultilibSet MuslMipsMultilibs;
  {
    auto MArchMipsR2 = makeMultilib("")
                           .osSuffix("/mips-r2-hard-musl")
                           .flag("+EB")
                           .flag("-EL")
                           .flag("+march=mips32r2");

    auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
                             .flag("-EB")
                             .flag("+EL")
                             .flag("+march=mips32r2");

    MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);

    // Specify the callback that computes the include directories.
    MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
      return std::vector<std::string>(
          {"/../sysroot" + M.osSuffix() + "/usr/include"});
    });
  }
  if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
    Result.Multilibs = MuslMipsMultilibs;
    return true;
  }
  return false;
}

static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
                                 FilterNonExistent &NonExistent,
                                 DetectedMultilibs &Result) {
  // CodeScape MTI toolchain v1.2 and early.
  MultilibSet MtiMipsMultilibsV1;
  {
    auto MArchMips32 = makeMultilib("/mips32")
                           .flag("+m32")
                           .flag("-m64")
                           .flag("-mmicromips")
                           .flag("+march=mips32");

    auto MArchMicroMips = makeMultilib("/micromips")
                              .flag("+m32")
                              .flag("-m64")
                              .flag("+mmicromips");

    auto MArchMips64r2 = makeMultilib("/mips64r2")
                             .flag("-m32")
                             .flag("+m64")
                             .flag("+march=mips64r2");

    auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
        "-march=mips64r2");

    auto MArchDefault = makeMultilib("")
                            .flag("+m32")
                            .flag("-m64")
                            .flag("-mmicromips")
                            .flag("+march=mips32r2");

    auto Mips16 = makeMultilib("/mips16").flag("+mips16");

    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");

    auto MAbi64 =
        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");

    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");

    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");

    auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");

    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");

    MtiMipsMultilibsV1 =
        MultilibSet()
            .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
                    MArchDefault)
            .Maybe(UCLibc)
            .Maybe(Mips16)
            .FilterOut("/mips64/mips16")
            .FilterOut("/mips64r2/mips16")
            .FilterOut("/micromips/mips16")
            .Maybe(MAbi64)
            .FilterOut("/micromips/64")
            .FilterOut("/mips32/64")
            .FilterOut("^/64")
            .FilterOut("/mips16/64")
            .Either(BigEndian, LittleEndian)
            .Maybe(SoftFloat)
            .Maybe(Nan2008)
            .FilterOut(".*sof/nan2008")
            .FilterOut(NonExistent)
            .setIncludeDirsCallback([](const Multilib &M) {
              std::vector<std::string> Dirs({"/include"});
              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
                Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
              else
                Dirs.push_back("/../../../../sysroot/usr/include");
              return Dirs;
            });
  }

  // CodeScape IMG toolchain starting from v1.3.
  MultilibSet MtiMipsMultilibsV2;
  {
    auto BeHard = makeMultilib("/mips-r2-hard")
                      .flag("+EB")
                      .flag("-msoft-float")
                      .flag("-mnan=2008")
                      .flag("-muclibc");
    auto BeSoft = makeMultilib("/mips-r2-soft")
                      .flag("+EB")
                      .flag("+msoft-float")
                      .flag("-mnan=2008");
    auto ElHard = makeMultilib("/mipsel-r2-hard")
                      .flag("+EL")
                      .flag("-msoft-float")
                      .flag("-mnan=2008")
                      .flag("-muclibc");
    auto ElSoft = makeMultilib("/mipsel-r2-soft")
                      .flag("+EL")
                      .flag("+msoft-float")
                      .flag("-mnan=2008")
                      .flag("-mmicromips");
    auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
                         .flag("+EB")
                         .flag("-msoft-float")
                         .flag("+mnan=2008")
                         .flag("-muclibc");
    auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
                         .flag("+EL")
                         .flag("-msoft-float")
                         .flag("+mnan=2008")
                         .flag("-muclibc")
                         .flag("-mmicromips");
    auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
                               .flag("+EB")
                               .flag("-msoft-float")
                               .flag("+mnan=2008")
                               .flag("+muclibc");
    auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
                               .flag("+EL")
                               .flag("-msoft-float")
                               .flag("+mnan=2008")
                               .flag("+muclibc");
    auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
                            .flag("+EB")
                            .flag("-msoft-float")
                            .flag("-mnan=2008")
                            .flag("+muclibc");
    auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
                            .flag("+EL")
                            .flag("-msoft-float")
                            .flag("-mnan=2008")
                            .flag("+muclibc");
    auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
                              .flag("+EL")
                              .flag("-msoft-float")
                              .flag("+mnan=2008")
                              .flag("+mmicromips");
    auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
                           .flag("+EL")
                           .flag("+msoft-float")
                           .flag("-mnan=2008")
                           .flag("+mmicromips");

    auto O32 =
        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
    auto N32 =
        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
    auto N64 =
        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");

    MtiMipsMultilibsV2 =
        MultilibSet()
            .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
                     BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
                     ElHardUclibc, ElMicroHardNan, ElMicroSoft})
            .Either(O32, N32, N64)
            .FilterOut(NonExistent)
            .setIncludeDirsCallback([](const Multilib &M) {
              return std::vector<std::string>({"/../../../../sysroot" +
                                               M.includeSuffix() +
                                               "/../usr/include"});
            })
            .setFilePathsCallback([](const Multilib &M) {
              return std::vector<std::string>(
                  {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
            });
  }
  for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
    if (Candidate->select(Flags, Result.SelectedMultilib)) {
      Result.Multilibs = *Candidate;
      return true;
    }
  }
  return false;
}

static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
                                 FilterNonExistent &NonExistent,
                                 DetectedMultilibs &Result) {
  // CodeScape IMG toolchain v1.2 and early.
  MultilibSet ImgMultilibsV1;
  {
    auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");

    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");

    auto MAbi64 =
        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");

    ImgMultilibsV1 =
        MultilibSet()
            .Maybe(Mips64r6)
            .Maybe(MAbi64)
            .Maybe(LittleEndian)
            .FilterOut(NonExistent)
            .setIncludeDirsCallback([](const Multilib &M) {
              return std::vector<std::string>(
                  {"/include", "/../../../../sysroot/usr/include"});
            });
  }

  // CodeScape IMG toolchain starting from v1.3.
  MultilibSet ImgMultilibsV2;
  {
    auto BeHard = makeMultilib("/mips-r6-hard")
                      .flag("+EB")
                      .flag("-msoft-float")
                      .flag("-mmicromips");
    auto BeSoft = makeMultilib("/mips-r6-soft")
                      .flag("+EB")
                      .flag("+msoft-float")
                      .flag("-mmicromips");
    auto ElHard = makeMultilib("/mipsel-r6-hard")
                      .flag("+EL")
                      .flag("-msoft-float")
                      .flag("-mmicromips");
    auto ElSoft = makeMultilib("/mipsel-r6-soft")
                      .flag("+EL")
                      .flag("+msoft-float")
                      .flag("-mmicromips");
    auto BeMicroHard = makeMultilib("/micromips-r6-hard")
                           .flag("+EB")
                           .flag("-msoft-float")
                           .flag("+mmicromips");
    auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
                           .flag("+EB")
                           .flag("+msoft-float")
                           .flag("+mmicromips");
    auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
                           .flag("+EL")
                           .flag("-msoft-float")
                           .flag("+mmicromips");
    auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
                           .flag("+EL")
                           .flag("+msoft-float")
                           .flag("+mmicromips");

    auto O32 =
        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
    auto N32 =
        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
    auto N64 =
        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");

    ImgMultilibsV2 =
        MultilibSet()
            .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
                     ElMicroHard, ElMicroSoft})
            .Either(O32, N32, N64)
            .FilterOut(NonExistent)
            .setIncludeDirsCallback([](const Multilib &M) {
              return std::vector<std::string>({"/../../../../sysroot" +
                                               M.includeSuffix() +
                                               "/../usr/include"});
            })
            .setFilePathsCallback([](const Multilib &M) {
              return std::vector<std::string>(
                  {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
            });
  }
  for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
    if (Candidate->select(Flags, Result.SelectedMultilib)) {
      Result.Multilibs = *Candidate;
      return true;
    }
  }
  return false;
}

bool clang::driver::findMIPSMultilibs(const Driver &D,
                                      const llvm::Triple &TargetTriple,
                                      StringRef Path, const ArgList &Args,
                                      DetectedMultilibs &Result) {
  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

  StringRef CPUName;
  StringRef ABIName;
  tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);

  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();

  Multilib::flags_list Flags;
  addMultilibFlag(TargetTriple.isMIPS32(), "m32", Flags);
  addMultilibFlag(TargetTriple.isMIPS64(), "m64", Flags);
  addMultilibFlag(isMips16(Args), "mips16", Flags);
  addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
  addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
                      CPUName == "mips32r5" || CPUName == "p5600",
                  "march=mips32r2", Flags);
  addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
  addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
  addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
                      CPUName == "mips64r5" || CPUName == "octeon" ||
                      CPUName == "octeon+",
                  "march=mips64r2", Flags);
  addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
  addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
  addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
  addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
                  Flags);
  addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
  addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
  addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
  addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
  addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
  addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);

  if (TargetTriple.isAndroid())
    return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
                                    Result);

  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
      TargetTriple.getOS() == llvm::Triple::Linux &&
      TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
    return findMipsMuslMultilibs(Flags, NonExistent, Result);

  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
      TargetTriple.getOS() == llvm::Triple::Linux &&
      TargetTriple.isGNUEnvironment())
    return findMipsMtiMultilibs(Flags, NonExistent, Result);

  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
      TargetTriple.getOS() == llvm::Triple::Linux &&
      TargetTriple.isGNUEnvironment())
    return findMipsImgMultilibs(Flags, NonExistent, Result);

  if (findMipsCsMultilibs(Flags, NonExistent, Result))
    return true;

  // Fallback to the regular toolchain-tree structure.
  Multilib Default;
  Result.Multilibs.push_back(Default);
  Result.Multilibs.FilterOut(NonExistent);

  if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
    Result.BiarchSibling = Multilib();
    return true;
  }

  return false;
}

static void findAndroidArmMultilibs(const Driver &D,
                                    const llvm::Triple &TargetTriple,
                                    StringRef Path, const ArgList &Args,
                                    DetectedMultilibs &Result) {
  // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
  Multilib ArmV7Multilib = makeMultilib("/armv7-a")
                               .flag("+march=armv7-a")
                               .flag("-mthumb");
  Multilib ThumbMultilib = makeMultilib("/thumb")
                               .flag("-march=armv7-a")
                               .flag("+mthumb");
  Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
                               .flag("+march=armv7-a")
                               .flag("+mthumb");
  Multilib DefaultMultilib = makeMultilib("")
                               .flag("-march=armv7-a")
                               .flag("-mthumb");
  MultilibSet AndroidArmMultilibs =
      MultilibSet()
          .Either(ThumbMultilib, ArmV7Multilib,
                  ArmV7ThumbMultilib, DefaultMultilib)
          .FilterOut(NonExistent);

  Multilib::flags_list Flags;
  llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
  bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
  bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
  bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
  bool IsThumbMode = IsThumbArch ||
      Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
      (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB);
  bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
      (llvm::ARM::parseArchVersion(Arch) == 7 ||
       (IsArmArch && Arch == "" && IsV7SubArch));
  addMultilibFlag(IsArmV7Mode, "march=armv7-a", Flags);
  addMultilibFlag(IsThumbMode, "mthumb", Flags);

  if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
    Result.Multilibs = AndroidArmMultilibs;
}

static bool findMSP430Multilibs(const Driver &D,
                                const llvm::Triple &TargetTriple,
                                StringRef Path, const ArgList &Args,
                                DetectedMultilibs &Result) {
  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
  Multilib WithoutExceptions = makeMultilib("/430").flag("-exceptions");
  Multilib WithExceptions = makeMultilib("/430/exceptions").flag("+exceptions");

  // FIXME: when clang starts to support msp430x ISA additional logic
  // to select between multilib must be implemented
  // Multilib MSP430xMultilib = makeMultilib("/large");

  Result.Multilibs.push_back(WithoutExceptions);
  Result.Multilibs.push_back(WithExceptions);
  Result.Multilibs.FilterOut(NonExistent);

  Multilib::flags_list Flags;
  addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
                               options::OPT_fno_exceptions, false),
                  "exceptions", Flags);
  if (Result.Multilibs.select(Flags, Result.SelectedMultilib))
    return true;

  return false;
}

static void findRISCVBareMetalMultilibs(const Driver &D,
                                        const llvm::Triple &TargetTriple,
                                        StringRef Path, const ArgList &Args,
                                        DetectedMultilibs &Result) {
  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
  struct RiscvMultilib {
    StringRef march;
    StringRef mabi;
  };
  // currently only support the set of multilibs like riscv-gnu-toolchain does.
  // TODO: support MULTILIB_REUSE
  constexpr RiscvMultilib RISCVMultilibSet[] = {
      {"rv32i", "ilp32"},     {"rv32im", "ilp32"},     {"rv32iac", "ilp32"},
      {"rv32imac", "ilp32"},  {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},
      {"rv64imafdc", "lp64d"}};

  std::vector<Multilib> Ms;
  for (auto Element : RISCVMultilibSet) {
    // multilib path rule is ${march}/${mabi}
    Ms.emplace_back(
        makeMultilib((Twine(Element.march) + "/" + Twine(Element.mabi)).str())
            .flag(Twine("+march=", Element.march).str())
            .flag(Twine("+mabi=", Element.mabi).str()));
  }
  MultilibSet RISCVMultilibs =
      MultilibSet()
          .Either(ArrayRef<Multilib>(Ms))
          .FilterOut(NonExistent)
          .setFilePathsCallback([](const Multilib &M) {
            return std::vector<std::string>(
                {M.gccSuffix(),
                 "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),
                 "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});
          });


  Multilib::flags_list Flags;
  llvm::StringSet<> Added_ABIs;
  StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
  StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple);
  for (auto Element : RISCVMultilibSet) {
    addMultilibFlag(MArch == Element.march,
                    Twine("march=", Element.march).str().c_str(), Flags);
    if (!Added_ABIs.count(Element.mabi)) {
      Added_ABIs.insert(Element.mabi);
      addMultilibFlag(ABIName == Element.mabi,
                      Twine("mabi=", Element.mabi).str().c_str(), Flags);
    }
  }

  if (RISCVMultilibs.select(Flags, Result.SelectedMultilib))
    Result.Multilibs = RISCVMultilibs;
}

static void findRISCVMultilibs(const Driver &D,
                               const llvm::Triple &TargetTriple, StringRef Path,
                               const ArgList &Args, DetectedMultilibs &Result) {
  if (TargetTriple.getOS() == llvm::Triple::UnknownOS)
    return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result);

  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
  Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32");
  Multilib Ilp32f =
      makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f");
  Multilib Ilp32d =
      makeMultilib("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d");
  Multilib Lp64 = makeMultilib("lib64/lp64").flag("+m64").flag("+mabi=lp64");
  Multilib Lp64f = makeMultilib("lib64/lp64f").flag("+m64").flag("+mabi=lp64f");
  Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d");
  MultilibSet RISCVMultilibs =
      MultilibSet()
          .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
          .FilterOut(NonExistent);

  Multilib::flags_list Flags;
  bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
  StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);

  addMultilibFlag(!IsRV64, "m32", Flags);
  addMultilibFlag(IsRV64, "m64", Flags);
  addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags);
  addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags);
  addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags);
  addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags);
  addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags);
  addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags);

  if (RISCVMultilibs.select(Flags, Result.SelectedMultilib))
    Result.Multilibs = RISCVMultilibs;
}

static bool findBiarchMultilibs(const Driver &D,
                                const llvm::Triple &TargetTriple,
                                StringRef Path, const ArgList &Args,
                                bool NeedsBiarchSuffix,
                                DetectedMultilibs &Result) {
  Multilib Default;

  // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
  // in what would normally be GCCInstallPath and put the 64-bit
  // libs in a subdirectory named 64. The simple logic we follow is that
  // *if* there is a subdirectory of the right name with crtbegin.o in it,
  // we use that. If not, and if not a biarch triple alias, we look for
  // crtbegin.o without the subdirectory.

  StringRef Suff64 = "/64";
  // Solaris uses platform-specific suffixes instead of /64.
  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
    switch (TargetTriple.getArch()) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      Suff64 = "/amd64";
      break;
    case llvm::Triple::sparc:
    case llvm::Triple::sparcv9:
      Suff64 = "/sparcv9";
      break;
    default:
      break;
    }
  }

  Multilib Alt64 = Multilib()
                       .gccSuffix(Suff64)
                       .includeSuffix(Suff64)
                       .flag("-m32")
                       .flag("+m64")
                       .flag("-mx32");
  Multilib Alt32 = Multilib()
                       .gccSuffix("/32")
                       .includeSuffix("/32")
                       .flag("+m32")
                       .flag("-m64")
                       .flag("-mx32");
  Multilib Altx32 = Multilib()
                        .gccSuffix("/x32")
                        .includeSuffix("/x32")
                        .flag("-m32")
                        .flag("-m64")
                        .flag("+mx32");

  // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
  FilterNonExistent NonExistent(
      Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());

  // Determine default multilib from: 32, 64, x32
  // Also handle cases such as 64 on 32, 32 on 64, etc.
  enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
  const bool IsX32 = TargetTriple.isX32();
  if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
    Want = WANT64;
  else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
    Want = WANT64;
  else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
    Want = WANT32;
  else {
    if (TargetTriple.isArch32Bit())
      Want = NeedsBiarchSuffix ? WANT64 : WANT32;
    else if (IsX32)
      Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
    else
      Want = NeedsBiarchSuffix ? WANT32 : WANT64;
  }

  if (Want == WANT32)
    Default.flag("+m32").flag("-m64").flag("-mx32");
  else if (Want == WANT64)
    Default.flag("-m32").flag("+m64").flag("-mx32");
  else if (Want == WANTX32)
    Default.flag("-m32").flag("-m64").flag("+mx32");
  else
    return false;

  Result.Multilibs.push_back(Default);
  Result.Multilibs.push_back(Alt64);
  Result.Multilibs.push_back(Alt32);
  Result.Multilibs.push_back(Altx32);

  Result.Multilibs.FilterOut(NonExistent);

  Multilib::flags_list Flags;
  addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
  addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
  addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);

  if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
    return false;

  if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 ||
      Result.SelectedMultilib == Altx32)
    Result.BiarchSibling = Default;

  return true;
}

/// Generic_GCC - A tool chain using the 'gcc' command to perform
/// all subcommands; this relies on gcc translating the majority of
/// command line options.

/// Less-than for GCCVersion, implementing a Strict Weak Ordering.
bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
                                          int RHSPatch,
                                          StringRef RHSPatchSuffix) const {
  if (Major != RHSMajor)
    return Major < RHSMajor;
  if (Minor != RHSMinor)
    return Minor < RHSMinor;
  if (Patch != RHSPatch) {
    // Note that versions without a specified patch sort higher than those with
    // a patch.
    if (RHSPatch == -1)
      return true;
    if (Patch == -1)
      return false;

    // Otherwise just sort on the patch itself.
    return Patch < RHSPatch;
  }
  if (PatchSuffix != RHSPatchSuffix) {
    // Sort empty suffixes higher.
    if (RHSPatchSuffix.empty())
      return true;
    if (PatchSuffix.empty())
      return false;

    // Provide a lexicographic sort to make this a total ordering.
    return PatchSuffix < RHSPatchSuffix;
  }

  // The versions are equal.
  return false;
}

/// Parse a GCCVersion object out of a string of text.
///
/// This is the primary means of forming GCCVersion objects.
/*static*/
Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) {
  const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
  std::pair<StringRef, StringRef> First = VersionText.split('.');
  std::pair<StringRef, StringRef> Second = First.second.split('.');

  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
  if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
    return BadVersion;
  GoodVersion.MajorStr = First.first.str();
  if (First.second.empty())
    return GoodVersion;
  StringRef MinorStr = Second.first;
  if (Second.second.empty()) {
    if (size_t EndNumber = MinorStr.find_first_not_of("0123456789")) {
      GoodVersion.PatchSuffix = std::string(MinorStr.substr(EndNumber));
      MinorStr = MinorStr.slice(0, EndNumber);
    }
  }
  if (MinorStr.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
    return BadVersion;
  GoodVersion.MinorStr = MinorStr.str();

  // First look for a number prefix and parse that if present. Otherwise just
  // stash the entire patch string in the suffix, and leave the number
  // unspecified. This covers versions strings such as:
  //   5        (handled above)
  //   4.4
  //   4.4-patched
  //   4.4.0
  //   4.4.x
  //   4.4.2-rc4
  //   4.4.x-patched
  // And retains any patch number it finds.
  StringRef PatchText = Second.second;
  if (!PatchText.empty()) {
    if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
      // Try to parse the number and any suffix.
      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
          GoodVersion.Patch < 0)
        return BadVersion;
      GoodVersion.PatchSuffix = std::string(PatchText.substr(EndNumber));
    }
  }

  return GoodVersion;
}

static llvm::StringRef getGCCToolchainDir(const ArgList &Args,
                                          llvm::StringRef SysRoot) {
  const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain);
  if (A)
    return A->getValue();

  // If we have a SysRoot, ignore GCC_INSTALL_PREFIX.
  // GCC_INSTALL_PREFIX specifies the gcc installation for the default
  // sysroot and is likely not valid with a different sysroot.
  if (!SysRoot.empty())
    return "";

  return GCC_INSTALL_PREFIX;
}

/// Initialize a GCCInstallationDetector from the driver.
///
/// This performs all of the autodetection and sets up the various paths.
/// Once constructed, a GCCInstallationDetector is essentially immutable.
///
/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
/// should instead pull the target out of the driver. This is currently
/// necessary because the driver doesn't store the final version of the target
/// triple.
void Generic_GCC::GCCInstallationDetector::init(
    const llvm::Triple &TargetTriple, const ArgList &Args,
    ArrayRef<std::string> ExtraTripleAliases) {
  llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
                                         ? TargetTriple.get64BitArchVariant()
                                         : TargetTriple.get32BitArchVariant();
  // The library directories which may contain GCC installations.
  SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
  // The compatible GCC triples for this particular architecture.
  SmallVector<StringRef, 16> CandidateTripleAliases;
  SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
  CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
                           CandidateTripleAliases, CandidateBiarchLibDirs,
                           CandidateBiarchTripleAliases);

  // Compute the set of prefixes for our search.
  SmallVector<std::string, 8> Prefixes;
  StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot);
  if (GCCToolchainDir != "") {
    if (GCCToolchainDir.back() == '/')
      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /

    Prefixes.push_back(std::string(GCCToolchainDir));
  } else {
    // If we have a SysRoot, try that first.
    if (!D.SysRoot.empty()) {
      Prefixes.push_back(D.SysRoot);
      AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);
    }

    // Then look for gcc installed alongside clang.
    Prefixes.push_back(D.InstalledDir + "/..");

    // Next, look for prefix(es) that correspond to distribution-supplied gcc
    // installations.
    if (D.SysRoot.empty()) {
      // Typically /usr.
      AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);
    }

    // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided.
    // This avoids accidentally enforcing the system GCC version when using a
    // custom toolchain.
    SmallVector<StringRef, 16> GentooTestTriples;
    // Try to match an exact triple as target triple first.
    // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for
    // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu"
    // may pick the libraries for x86_64-pc-linux-gnu even when exact matching
    // triple x86_64-gentoo-linux-gnu is present.
    GentooTestTriples.push_back(TargetTriple.str());
    // Check rest of triples.
    GentooTestTriples.append(ExtraTripleAliases.begin(),
                             ExtraTripleAliases.end());
    GentooTestTriples.append(CandidateTripleAliases.begin(),
                             CandidateTripleAliases.end());
    if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples,
                          CandidateBiarchTripleAliases))
      return;
  }

  // Loop over the various components which exist and select the best GCC
  // installation available. GCC installs are ranked by version number.
  const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");
  Version = VersionZero;
  for (const std::string &Prefix : Prefixes) {
    auto &VFS = D.getVFS();
    if (!VFS.exists(Prefix))
      continue;
    for (StringRef Suffix : CandidateLibDirs) {
      const std::string LibDir = Prefix + Suffix.str();
      if (!VFS.exists(LibDir))
        continue;
      // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross.
      bool GCCDirExists = VFS.exists(LibDir + "/gcc");
      bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");
      // Try to match the exact target triple first.
      ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TargetTriple.str(),
                             false, GCCDirExists, GCCCrossDirExists);
      // Try rest of possible triples.
      for (StringRef Candidate : ExtraTripleAliases) // Try these first.
        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,
                               GCCDirExists, GCCCrossDirExists);
      for (StringRef Candidate : CandidateTripleAliases)
        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,
                               GCCDirExists, GCCCrossDirExists);
    }
    for (StringRef Suffix : CandidateBiarchLibDirs) {
      const std::string LibDir = Prefix + Suffix.str();
      if (!VFS.exists(LibDir))
        continue;
      bool GCCDirExists = VFS.exists(LibDir + "/gcc");
      bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");
      for (StringRef Candidate : CandidateBiarchTripleAliases)
        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true,
                               GCCDirExists, GCCCrossDirExists);
    }

    // Skip other prefixes once a GCC installation is found.
    if (Version > VersionZero)
      break;
  }
}

void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
  for (const auto &InstallPath : CandidateGCCInstallPaths)
    OS << "Found candidate GCC installation: " << InstallPath << "\n";

  if (!GCCInstallPath.empty())
    OS << "Selected GCC installation: " << GCCInstallPath << "\n";

  for (const auto &Multilib : Multilibs)
    OS << "Candidate multilib: " << Multilib << "\n";

  if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
    OS << "Selected multilib: " << SelectedMultilib << "\n";
}

bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
  if (BiarchSibling.hasValue()) {
    M = BiarchSibling.getValue();
    return true;
  }
  return false;
}

void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
    const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes,
    StringRef SysRoot) {
  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
    // Solaris is a special case.
    // The GCC installation is under
    //   /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/
    // so we need to find those /usr/gcc/*/lib/gcc libdirs and go with
    // /usr/gcc/<version> as a prefix.

    std::string PrefixDir = SysRoot.str() + "/usr/gcc";
    std::error_code EC;
    for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),
                                       LE;
         !EC && LI != LE; LI = LI.increment(EC)) {
      StringRef VersionText = llvm::sys::path::filename(LI->path());
      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);

      // Filter out obviously bad entries.
      if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1))
        continue;

      std::string CandidatePrefix = PrefixDir + "/" + VersionText.str();
      std::string CandidateLibPath = CandidatePrefix + "/lib/gcc";
      if (!D.getVFS().exists(CandidateLibPath))
        continue;

      Prefixes.push_back(CandidatePrefix);
    }
    return;
  }

  // Non-Solaris is much simpler - most systems just go with "/usr".
  if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux) {
    // Yet, still look for RHEL devtoolsets.
    Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
    Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
  }
  Prefixes.push_back(SysRoot.str() + "/usr");
}

/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
    const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
    SmallVectorImpl<StringRef> &LibDirs,
    SmallVectorImpl<StringRef> &TripleAliases,
    SmallVectorImpl<StringRef> &BiarchLibDirs,
    SmallVectorImpl<StringRef> &BiarchTripleAliases) {
  // Declare a bunch of static data sets that we'll select between below. These
  // are specifically designed to always refer to string literals to avoid any
  // lifetime or initialization issues.
  static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
  static const char *const AArch64Triples[] = {
      "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux",
      "aarch64-suse-linux", "aarch64-linux-android"};
  static const char *const AArch64beLibDirs[] = {"/lib"};
  static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
                                                 "aarch64_be-linux-gnu"};

  static const char *const ARMLibDirs[] = {"/lib"};
  static const char *const ARMTriples[] = {"arm-linux-gnueabi",
                                           "arm-linux-androideabi"};
  static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
                                             "armv7hl-redhat-linux-gnueabi",
                                             "armv6hl-suse-linux-gnueabi",
                                             "armv7hl-suse-linux-gnueabi"};
  static const char *const ARMebLibDirs[] = {"/lib"};
  static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
                                             "armeb-linux-androideabi"};
  static const char *const ARMebHFTriples[] = {
      "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};

  static const char *const AVRLibDirs[] = {"/lib"};
  static const char *const AVRTriples[] = {"avr"};

  static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
  static const char *const X86_64Triples[] = {
      "x86_64-linux-gnu",       "x86_64-unknown-linux-gnu",
      "x86_64-pc-linux-gnu",    "x86_64-redhat-linux6E",
      "x86_64-redhat-linux",    "x86_64-suse-linux",
      "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
      "x86_64-slackware-linux", "x86_64-unknown-linux",
      "x86_64-amazon-linux",    "x86_64-linux-android"};
  static const char *const X32Triples[] = {"x86_64-linux-gnux32",
                                           "x86_64-pc-linux-gnux32"};
  static const char *const X32LibDirs[] = {"/libx32", "/lib"};
  static const char *const X86LibDirs[] = {"/lib32", "/lib"};
  static const char *const X86Triples[] = {
      "i586-linux-gnu",     "i686-linux-gnu",
      "i686-pc-linux-gnu",  "i386-redhat-linux6E",
      "i686-redhat-linux",  "i386-redhat-linux",
      "i586-suse-linux",    "i686-montavista-linux",
      "i686-linux-android", "i686-gnu",
  };

  static const char *const M68kLibDirs[] = {"/lib"};
  static const char *const M68kTriples[] = {
      "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux"};

  static const char *const MIPSLibDirs[] = {"/lib"};
  static const char *const MIPSTriples[] = {
      "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu",
      "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"};
  static const char *const MIPSELLibDirs[] = {"/lib"};
  static const char *const MIPSELTriples[] = {
      "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu",
      "mipsel-linux-android"};

  static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
  static const char *const MIPS64Triples[] = {
      "mips64-linux-gnu",      "mips-mti-linux-gnu",
      "mips-img-linux-gnu",    "mips64-linux-gnuabi64",
      "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"};
  static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};
  static const char *const MIPS64ELTriples[] = {
      "mips64el-linux-gnu",      "mips-mti-linux-gnu",
      "mips-img-linux-gnu",      "mips64el-linux-gnuabi64",
      "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64",
      "mips64el-linux-android"};

  static const char *const MIPSN32LibDirs[] = {"/lib32"};
  static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32",
                                               "mipsisa64r6-linux-gnuabin32"};
  static const char *const MIPSN32ELLibDirs[] = {"/lib32"};
  static const char *const MIPSN32ELTriples[] = {
      "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};

  static const char *const MSP430LibDirs[] = {"/lib"};
  static const char *const MSP430Triples[] = {"msp430-elf"};

  static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
  static const char *const PPCTriples[] = {
      "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
      // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
      // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
      "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};
  static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};
  static const char *const PPCLETriples[] = {"powerpcle-linux-gnu",
                                             "powerpcle-unknown-linux-gnu",
                                             "powerpcle-linux-musl"};

  static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
  static const char *const PPC64Triples[] = {
      "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
      "powerpc64-suse-linux", "ppc64-redhat-linux"};
  static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
  static const char *const PPC64LETriples[] = {
      "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
      "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux",
      "ppc64le-redhat-linux"};

  static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};
  static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",
                                               "riscv32-linux-gnu",
                                               "riscv32-unknown-elf"};
  static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
  static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
                                               "riscv64-linux-gnu",
                                               "riscv64-unknown-elf",
                                               "riscv64-redhat-linux",
                                               "riscv64-suse-linux"};

  static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
  static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
                                               "sparcv8-linux-gnu"};
  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
  static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
                                               "sparcv9-linux-gnu"};

  static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
  static const char *const SystemZTriples[] = {
      "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
      "s390x-suse-linux", "s390x-redhat-linux"};


  using std::begin;
  using std::end;

  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
    static const char *const SolarisLibDirs[] = {"/lib"};
    static const char *const SolarisSparcV8Triples[] = {
        "sparc-sun-solaris2.11", "sparc-sun-solaris2.12"};
    static const char *const SolarisSparcV9Triples[] = {
        "sparcv9-sun-solaris2.11", "sparcv9-sun-solaris2.12"};
    static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11",
                                                    "i386-pc-solaris2.12"};
    static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11",
                                                       "x86_64-pc-solaris2.12"};
    LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));
    BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));
    switch (TargetTriple.getArch()) {
    case llvm::Triple::x86:
      TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples));
      BiarchTripleAliases.append(begin(SolarisX86_64Triples),
                                 end(SolarisX86_64Triples));
      break;
    case llvm::Triple::x86_64:
      TripleAliases.append(begin(SolarisX86_64Triples),
                           end(SolarisX86_64Triples));
      BiarchTripleAliases.append(begin(SolarisX86Triples),
                                 end(SolarisX86Triples));
      break;
    case llvm::Triple::sparc:
      TripleAliases.append(begin(SolarisSparcV8Triples),
                           end(SolarisSparcV8Triples));
      BiarchTripleAliases.append(begin(SolarisSparcV9Triples),
                                 end(SolarisSparcV9Triples));
      break;
    case llvm::Triple::sparcv9:
      TripleAliases.append(begin(SolarisSparcV9Triples),
                           end(SolarisSparcV9Triples));
      BiarchTripleAliases.append(begin(SolarisSparcV8Triples),
                                 end(SolarisSparcV8Triples));
      break;
    default:
      break;
    }
    return;
  }

  // Android targets should not use GNU/Linux tools or libraries.
  if (TargetTriple.isAndroid()) {
    static const char *const AArch64AndroidTriples[] = {
        "aarch64-linux-android"};
    static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"};
    static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
    static const char *const MIPS64ELAndroidTriples[] = {
        "mips64el-linux-android"};
    static const char *const X86AndroidTriples[] = {"i686-linux-android"};
    static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"};

    switch (TargetTriple.getArch()) {
    case llvm::Triple::aarch64:
      LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
      TripleAliases.append(begin(AArch64AndroidTriples),
                           end(AArch64AndroidTriples));
      break;
    case llvm::Triple::arm:
    case llvm::Triple::thumb:
      LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
      TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples));
      break;
    case llvm::Triple::mipsel:
      LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
      TripleAliases.append(begin(MIPSELAndroidTriples),
                           end(MIPSELAndroidTriples));
      BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
      BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
                                 end(MIPS64ELAndroidTriples));
      break;
    case llvm::Triple::mips64el:
      LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
      TripleAliases.append(begin(MIPS64ELAndroidTriples),
                           end(MIPS64ELAndroidTriples));
      BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
      BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
                                 end(MIPSELAndroidTriples));
      break;
    case llvm::Triple::x86_64:
      LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
      TripleAliases.append(begin(X86_64AndroidTriples),
                           end(X86_64AndroidTriples));
      BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
      BiarchTripleAliases.append(begin(X86AndroidTriples),
                                 end(X86AndroidTriples));
      break;
    case llvm::Triple::x86:
      LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
      TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples));
      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
      BiarchTripleAliases.append(begin(X86_64AndroidTriples),
                                 end(X86_64AndroidTriples));
      break;
    default:
      break;
    }

    return;
  }

  switch (TargetTriple.getArch()) {
  case llvm::Triple::aarch64:
    LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
    TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
    BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
    BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
    break;
  case llvm::Triple::aarch64_be:
    LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
    TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
    BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
    BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
    break;
  case llvm::Triple::arm:
  case llvm::Triple::thumb:
    LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
      TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
    } else {
      TripleAliases.append(begin(ARMTriples), end(ARMTriples));
    }
    break;
  case llvm::Triple::armeb:
  case llvm::Triple::thumbeb:
    LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
      TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
    } else {
      TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
    }
    break;
  case llvm::Triple::avr:
    LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs));
    TripleAliases.append(begin(AVRTriples), end(AVRTriples));
    break;
  case llvm::Triple::x86_64:
    if (TargetTriple.isX32()) {
      LibDirs.append(begin(X32LibDirs), end(X32LibDirs));
      TripleAliases.append(begin(X32Triples), end(X32Triples));
      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
    } else {
      LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
      TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
      BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
      BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));
    }
    BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
    BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
    break;
  case llvm::Triple::x86:
    LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
    // MCU toolchain is 32 bit only and its triple alias is TargetTriple
    // itself, which will be appended below.
    if (!TargetTriple.isOSIAMCU()) {
      TripleAliases.append(begin(X86Triples), end(X86Triples));
      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
      BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
      BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));
    }
    break;
  case llvm::Triple::m68k:
    LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs));
    TripleAliases.append(begin(M68kTriples), end(M68kTriples));
    break;
  case llvm::Triple::mips:
    LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
    BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
    BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
    BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));
    BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));
    break;
  case llvm::Triple::mipsel:
    LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
    TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
    BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
    BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
    BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));
    BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));
    break;
  case llvm::Triple::mips64:
    LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
    TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
    BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
    BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));
    BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));
    break;
  case llvm::Triple::mips64el:
    LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
    TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
    BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
    BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
    BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));
    BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));
    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
    break;
  case llvm::Triple::msp430:
    LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs));
    TripleAliases.append(begin(MSP430Triples), end(MSP430Triples));
    break;
  case llvm::Triple::ppc:
    LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
    TripleAliases.append(begin(PPCTriples), end(PPCTriples));
    BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
    BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
    break;
  case llvm::Triple::ppcle:
    LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));
    TripleAliases.append(begin(PPCLETriples), end(PPCLETriples));
    BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
    BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
    break;
  case llvm::Triple::ppc64:
    LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
    TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
    BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
    BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
    break;
  case llvm::Triple::ppc64le:
    LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
    TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
    BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));
    BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples));
    break;
  case llvm::Triple::riscv32:
    LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
    TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));
    BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));
    BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));
    break;
  case llvm::Triple::riscv64:
    LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));
    TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));
    BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
    BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));
    break;
  case llvm::Triple::sparc:
  case llvm::Triple::sparcel:
    LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
    TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
    BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
    BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
    break;
  case llvm::Triple::sparcv9:
    LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
    TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
    BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
    BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
    break;
  case llvm::Triple::systemz:
    LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
    TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
    break;
  default:
    // By default, just rely on the standard lib directories and the original
    // triple.
    break;
  }

  // Always append the drivers target triple to the end, in case it doesn't
  // match any of our aliases.
  TripleAliases.push_back(TargetTriple.str());

  // Also include the multiarch variant if it's different.
  if (TargetTriple.str() != BiarchTriple.str())
    BiarchTripleAliases.push_back(BiarchTriple.str());
}

bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
    const llvm::Triple &TargetTriple, const ArgList &Args,
    StringRef Path, bool NeedsBiarchSuffix) {
  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
  DetectedMultilibs Detected;

  // Android standalone toolchain could have multilibs for ARM and Thumb.
  // Debian mips multilibs behave more like the rest of the biarch ones,
  // so handle them there
  if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
    // It should also work without multilibs in a simplified toolchain.
    findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected);
  } else if (TargetTriple.isMIPS()) {
    if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected))
      return false;
  } else if (TargetTriple.isRISCV()) {
    findRISCVMultilibs(D, TargetTriple, Path, Args, Detected);
  } else if (isMSP430(TargetArch)) {
    findMSP430Multilibs(D, TargetTriple, Path, Args, Detected);
  } else if (TargetArch == llvm::Triple::avr) {
    // AVR has no multilibs.
  } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,
                                  NeedsBiarchSuffix, Detected)) {
    return false;
  }

  Multilibs = Detected.Multilibs;
  SelectedMultilib = Detected.SelectedMultilib;
  BiarchSibling = Detected.BiarchSibling;

  return true;
}

void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
    const llvm::Triple &TargetTriple, const ArgList &Args,
    const std::string &LibDir, StringRef CandidateTriple,
    bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) {
  // Locations relative to the system lib directory where GCC's triple-specific
  // directories might reside.
  struct GCCLibSuffix {
    // Path from system lib directory to GCC triple-specific directory.
    std::string LibSuffix;
    // Path from GCC triple-specific directory back to system lib directory.
    // This is one '..' component per component in LibSuffix.
    StringRef ReversePath;
    // Whether this library suffix is relevant for the triple.
    bool Active;
  } Suffixes[] = {
      // This is the normal place.
      {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists},

      // Debian puts cross-compilers in gcc-cross.
      {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists},

      // The Freescale PPC SDK has the gcc libraries in
      // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do
      // this on Freescale triples, though, since some systems put a *lot* of
      // files in that location, not just GCC installation data.
      {CandidateTriple.str(), "..",
       TargetTriple.getVendor() == llvm::Triple::Freescale ||
           TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};

  for (auto &Suffix : Suffixes) {
    if (!Suffix.Active)
      continue;

    StringRef LibSuffix = Suffix.LibSuffix;
    std::error_code EC;
    for (llvm::vfs::directory_iterator
             LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),
             LE;
         !EC && LI != LE; LI = LI.increment(EC)) {
      StringRef VersionText = llvm::sys::path::filename(LI->path());
      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
      if (CandidateVersion.Major != -1) // Filter obviously bad entries.
        if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second)
          continue; // Saw this path before; no need to look at it again.
      if (CandidateVersion.isOlderThan(4, 1, 1))
        continue;
      if (CandidateVersion <= Version)
        continue;

      if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),
                               NeedsBiarchSuffix))
        continue;

      Version = CandidateVersion;
      GCCTriple.setTriple(CandidateTriple);
      // FIXME: We hack together the directory name here instead of
      // using LI to ensure stable path separators across Windows and
      // Linux.
      GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
      GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
      IsValid = true;
    }
  }
}

bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(
    const llvm::Triple &TargetTriple, const ArgList &Args,
    const SmallVectorImpl<StringRef> &CandidateTriples,
    const SmallVectorImpl<StringRef> &CandidateBiarchTriples) {
  if (!D.getVFS().exists(D.SysRoot + GentooConfigDir))
    return false;

  for (StringRef CandidateTriple : CandidateTriples) {
    if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))
      return true;
  }

  for (StringRef CandidateTriple : CandidateBiarchTriples) {
    if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))
      return true;
  }
  return false;
}

bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
    const llvm::Triple &TargetTriple, const ArgList &Args,
    StringRef CandidateTriple, bool NeedsBiarchSuffix) {
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
      D.getVFS().getBufferForFile(D.SysRoot + GentooConfigDir + "/config-" +
                                  CandidateTriple.str());
  if (File) {
    SmallVector<StringRef, 2> Lines;
    File.get()->getBuffer().split(Lines, "\n");
    for (StringRef Line : Lines) {
      Line = Line.trim();
      // CURRENT=triple-version
      if (!Line.consume_front("CURRENT="))
        continue;
      // Process the config file pointed to by CURRENT.
      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile =
          D.getVFS().getBufferForFile(D.SysRoot + GentooConfigDir + "/" +
                                      Line.str());
      std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-');
      // List of paths to scan for libraries.
      SmallVector<StringRef, 4> GentooScanPaths;
      // Scan the Config file to find installed GCC libraries path.
      // Typical content of the GCC config file:
      // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/
      // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32"
      // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man"
      // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info"
      // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4"
      // We are looking for the paths listed in LDPATH=... .
      if (ConfigFile) {
        SmallVector<StringRef, 2> ConfigLines;
        ConfigFile.get()->getBuffer().split(ConfigLines, "\n");
        for (StringRef ConfLine : ConfigLines) {
          ConfLine = ConfLine.trim();
          if (ConfLine.consume_front("LDPATH=")) {
            // Drop '"' from front and back if present.
            ConfLine.consume_back("\"");
            ConfLine.consume_front("\"");
            // Get all paths sperated by ':'
            ConfLine.split(GentooScanPaths, ':', -1, /*AllowEmpty*/ false);
          }
        }
      }
      // Test the path based on the version in /etc/env.d/gcc/config-{tuple}.
      std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/"
          + ActiveVersion.second.str();
      GentooScanPaths.push_back(StringRef(basePath));

      // Scan all paths for GCC libraries.
      for (const auto &GentooScanPath : GentooScanPaths) {
        std::string GentooPath = D.SysRoot + std::string(GentooScanPath);
        if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {
          if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,
                                   NeedsBiarchSuffix))
            continue;

          Version = GCCVersion::Parse(ActiveVersion.second);
          GCCInstallPath = GentooPath;
          GCCParentLibPath = GentooPath + std::string("/../../..");
          GCCTriple.setTriple(ActiveVersion.first);
          IsValid = true;
          return true;
        }
      }
    }
  }

  return false;
}

Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
                         const ArgList &Args)
    : ToolChain(D, Triple, Args), GCCInstallation(D),
      CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {
  getProgramPaths().push_back(getDriver().getInstalledDir());
  if (getDriver().getInstalledDir() != getDriver().Dir)
    getProgramPaths().push_back(getDriver().Dir);
}

Generic_GCC::~Generic_GCC() {}

Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
  switch (AC) {
  case Action::PreprocessJobClass:
    if (!Preprocess)
      Preprocess.reset(new clang::driver::tools::gcc::Preprocessor(*this));
    return Preprocess.get();
  case Action::CompileJobClass:
    if (!Compile)
      Compile.reset(new tools::gcc::Compiler(*this));
    return Compile.get();
  default:
    return ToolChain::getTool(AC);
  }
}

Tool *Generic_GCC::buildAssembler() const {
  return new tools::gnutools::Assembler(*this);
}

Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }

void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
  // Print the information about how we detected the GCC installation.
  GCCInstallation.print(OS);
  CudaInstallation.print(OS);
  RocmInstallation.print(OS);
}

bool Generic_GCC::IsUnwindTablesDefault(const ArgList &Args) const {
  switch (getArch()) {
  case llvm::Triple::aarch64:
  case llvm::Triple::ppc:
  case llvm::Triple::ppcle:
  case llvm::Triple::ppc64:
  case llvm::Triple::ppc64le:
  case llvm::Triple::x86_64:
    return true;
  default:
    return false;
  }
}

bool Generic_GCC::isPICDefault() const {
  switch (getArch()) {
  case llvm::Triple::x86_64:
    return getTriple().isOSWindows();
  case llvm::Triple::mips64:
  case llvm::Triple::mips64el:
    return true;
  default:
    return false;
  }
}

bool Generic_GCC::isPIEDefault() const { return false; }

bool Generic_GCC::isPICDefaultForced() const {
  return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
}

bool Generic_GCC::IsIntegratedAssemblerDefault() const {
  switch (getTriple().getArch()) {
  case llvm::Triple::x86:
  case llvm::Triple::x86_64:
  case llvm::Triple::aarch64:
  case llvm::Triple::aarch64_be:
  case llvm::Triple::arm:
  case llvm::Triple::armeb:
  case llvm::Triple::avr:
  case llvm::Triple::bpfel:
  case llvm::Triple::bpfeb:
  case llvm::Triple::thumb:
  case llvm::Triple::thumbeb:
  case llvm::Triple::ppc:
  case llvm::Triple::ppcle:
  case llvm::Triple::ppc64:
  case llvm::Triple::ppc64le:
  case llvm::Triple::riscv32:
  case llvm::Triple::riscv64:
  case llvm::Triple::systemz:
  case llvm::Triple::mips:
  case llvm::Triple::mipsel:
  case llvm::Triple::mips64:
  case llvm::Triple::mips64el:
  case llvm::Triple::msp430:
  case llvm::Triple::m68k:
    return true;
  case llvm::Triple::sparc:
  case llvm::Triple::sparcel:
  case llvm::Triple::sparcv9:
    if (getTriple().isOSFreeBSD() || getTriple().isOSOpenBSD() ||
        getTriple().isOSSolaris())
      return true;
    return false;
  default:
    return false;
  }
}

void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) {
  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
  // least) put various tools in a triple-prefixed directory off of the parent
  // of the GCC installation. We use the GCC triple here to ensure that we end
  // up with tools that support the same amount of cross compiling as the
  // detected GCC installation. For example, if we find a GCC installation
  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
  // used to target i386.
  if (GCCInstallation.isValid()) {
    PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
                           GCCInstallation.getTriple().str() + "/bin")
                         .str());
  }
}

void Generic_GCC::AddMultilibPaths(const Driver &D,
                                   const std::string &SysRoot,
                                   const std::string &OSLibDir,
                                   const std::string &MultiarchTriple,
                                   path_list &Paths) {
  // Add the multilib suffixed paths where they are available.
  if (GCCInstallation.isValid()) {
    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
    const std::string &LibPath =
        std::string(GCCInstallation.getParentLibPath());

    // Sourcery CodeBench MIPS toolchain holds some libraries under
    // a biarch-like suffix of the GCC installation.
    if (const auto &PathsCallback = Multilibs.filePathsCallback())
      for (const auto &Path : PathsCallback(SelectedMultilib))
        addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths);

    // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
    addPathIfExists(
        D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(),
        Paths);

    // GCC cross compiling toolchains will install target libraries which ship
    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
    // any part of the GCC installation in
    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
    // debatable, but is the reality today. We need to search this tree even
    // when we have a sysroot somewhere else. It is the responsibility of
    // whomever is doing the cross build targeting a sysroot using a GCC
    // installation that is *not* within the system root to ensure two things:
    //
    //  1) Any DSOs that are linked in from this tree or from the install path
    //     above must be present on the system root and found via an
    //     appropriate rpath.
    //  2) There must not be libraries installed into
    //     <prefix>/<triple>/<libdir> unless they should be preferred over
    //     those within the system root.
    //
    // Note that this matches the GCC behavior. See the below comment for where
    // Clang diverges from GCC's behavior.
    addPathIfExists(D,
                    LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
                        SelectedMultilib.osSuffix(),
                    Paths);

    // If the GCC installation we found is inside of the sysroot, we want to
    // prefer libraries installed in the parent prefix of the GCC installation.
    // It is important to *not* use these paths when the GCC installation is
    // outside of the system root as that can pick up unintended libraries.
    // This usually happens when there is an external cross compiler on the
    // host system, and a more minimal sysroot available that is the target of
    // the cross. Note that GCC does include some of these directories in some
    // configurations but this seems somewhere between questionable and simply
    // a bug.
    if (StringRef(LibPath).startswith(SysRoot))
      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
  }
}

void Generic_GCC::AddMultiarchPaths(const Driver &D,
                                    const std::string &SysRoot,
                                    const std::string &OSLibDir,
                                    path_list &Paths) {
  if (GCCInstallation.isValid()) {
    const std::string &LibPath =
        std::string(GCCInstallation.getParentLibPath());
    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
    const Multilib &Multilib = GCCInstallation.getMultilib();
    addPathIfExists(
        D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(),
                    Paths);
  }
}

void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs,
                                         ArgStringList &CC1Args) const {
  // Add include directories specific to the selected multilib set and multilib.
  if (!GCCInstallation.isValid())
    return;
  // gcc TOOL_INCLUDE_DIR.
  const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
  std::string LibPath(GCCInstallation.getParentLibPath());
  addSystemInclude(DriverArgs, CC1Args,
                   Twine(LibPath) + "/../" + GCCTriple.str() + "/include");

  const auto &Callback = Multilibs.includeDirsCallback();
  if (Callback) {
    for (const auto &Path : Callback(GCCInstallation.getMultilib()))
      addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
                                      GCCInstallation.getInstallPath() + Path);
  }
}

void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                               ArgStringList &CC1Args) const {
  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,
                        options::OPT_nostdlibinc))
    return;

  switch (GetCXXStdlibType(DriverArgs)) {
  case ToolChain::CST_Libcxx:
    addLibCxxIncludePaths(DriverArgs, CC1Args);
    break;

  case ToolChain::CST_Libstdcxx:
    addLibStdCxxIncludePaths(DriverArgs, CC1Args);
    break;
  }
}

void
Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
                                   llvm::opt::ArgStringList &CC1Args) const {
  const Driver &D = getDriver();
  std::string SysRoot = computeSysRoot();
  std::string Target = getTripleString();

  auto AddIncludePath = [&](std::string Path) {
    std::string Version = detectLibcxxVersion(Path);
    if (Version.empty())
      return false;

    // First add the per-target include path if it exists.
    std::string TargetDir = Path + "/" + Target + "/c++/" + Version;
    if (D.getVFS().exists(TargetDir))
      addSystemInclude(DriverArgs, CC1Args, TargetDir);

    // Second add the generic one.
    addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
    return true;
  };

  // Android never uses the libc++ headers installed alongside the toolchain,
  // which are generally incompatible with the NDK libraries anyway.
  if (!getTriple().isAndroid())
    if (AddIncludePath(getDriver().Dir + "/../include"))
      return;
  // If this is a development, non-installed, clang, libcxx will
  // not be found at ../include/c++ but it likely to be found at
  // one of the following two locations:
  if (AddIncludePath(SysRoot + "/usr/local/include"))
    return;
  if (AddIncludePath(SysRoot + "/usr/include"))
    return;
}

bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
                                           Twine IncludeSuffix,
                                           const llvm::opt::ArgList &DriverArgs,
                                           llvm::opt::ArgStringList &CC1Args,
                                           bool DetectDebian) const {
  if (!getVFS().exists(IncludeDir))
    return false;

  // Debian native gcc uses g++-multiarch-incdir.diff which uses
  // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of
  // include/c++/10/x86_64-linux-gnu$IncludeSuffix.
  std::string Dir = IncludeDir.str();
  StringRef Include =
      llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir));
  std::string Path =
      (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix)
          .str();
  if (DetectDebian && !getVFS().exists(Path))
    return false;

  // GPLUSPLUS_INCLUDE_DIR
  addSystemInclude(DriverArgs, CC1Args, IncludeDir);
  // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent
  // include directory.
  if (DetectDebian)
    addSystemInclude(DriverArgs, CC1Args, Path);
  else if (!Triple.empty())
    addSystemInclude(DriverArgs, CC1Args,
                     IncludeDir + "/" + Triple + IncludeSuffix);
  // GPLUSPLUS_BACKWARD_INCLUDE_DIR
  addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");
  return true;
}

bool Generic_GCC::addGCCLibStdCxxIncludePaths(
    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
    StringRef DebianMultiarch) const {
  assert(GCCInstallation.isValid());

  // By default, look for the C++ headers in an include directory adjacent to
  // the lib directory of the GCC installation. Note that this is expect to be
  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
  StringRef LibDir = GCCInstallation.getParentLibPath();
  StringRef InstallDir = GCCInstallation.getInstallPath();
  StringRef TripleStr = GCCInstallation.getTriple().str();
  const Multilib &Multilib = GCCInstallation.getMultilib();
  const GCCVersion &Version = GCCInstallation.getVersion();

  // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty).
  if (addLibStdCXXIncludePaths(
          LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,
          TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args))
    return true;

  // Detect Debian g++-multiarch-incdir.diff.
  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text,
                               DebianMultiarch, Multilib.includeSuffix(),
                               DriverArgs, CC1Args, /*Debian=*/true))
    return true;

  // Try /../include/c++/$version (gcc --print-multiarch is empty).
  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text,
                               TripleStr, Multilib.includeSuffix(), DriverArgs,
                               CC1Args))
    return true;

  // Otherwise, fall back on a bunch of options which don't use multiarch
  // layouts for simplicity.
  const std::string LibStdCXXIncludePathCandidates[] = {
      // Gentoo is weird and places its headers inside the GCC install,
      // so if the first attempt to find the headers fails, try these patterns.
      InstallDir.str() + "/include/g++-v" + Version.Text,
      InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
          Version.MinorStr,
      InstallDir.str() + "/include/g++-v" + Version.MajorStr,
  };

  for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
    if (addLibStdCXXIncludePaths(IncludePath, TripleStr,
                                 Multilib.includeSuffix(), DriverArgs, CC1Args))
      return true;
  }
  return false;
}

void
Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
                                      llvm::opt::ArgStringList &CC1Args) const {
  if (GCCInstallation.isValid()) {
    addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
                                GCCInstallation.getTriple().str());
  }
}

llvm::opt::DerivedArgList *
Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef,
                           Action::OffloadKind DeviceOffloadKind) const {

  // If this tool chain is used for an OpenMP offloading device we have to make
  // sure we always generate a shared library regardless of the commands the
  // user passed to the host. This is required because the runtime library
  // is required to load the device image dynamically at run time.
  if (DeviceOffloadKind == Action::OFK_OpenMP) {
    DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
    const OptTable &Opts = getDriver().getOpts();

    // Request the shared library. Given that these options are decided
    // implicitly, they do not refer to any base argument.
    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared));
    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC));

    // Filter all the arguments we don't care passing to the offloading
    // toolchain as they can mess up with the creation of a shared library.
    for (auto *A : Args) {
      switch ((options::ID)A->getOption().getID()) {
      default:
        DAL->append(A);
        break;
      case options::OPT_shared:
      case options::OPT_dynamic:
      case options::OPT_static:
      case options::OPT_fPIC:
      case options::OPT_fno_PIC:
      case options::OPT_fpic:
      case options::OPT_fno_pic:
      case options::OPT_fPIE:
      case options::OPT_fno_PIE:
      case options::OPT_fpie:
      case options::OPT_fno_pie:
        break;
      }
    }
    return DAL;
  }
  return nullptr;
}

void Generic_ELF::anchor() {}

void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
                                        ArgStringList &CC1Args,
                                        Action::OffloadKind) const {
  if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
                          options::OPT_fno_use_init_array, true))
    CC1Args.push_back("-fno-use-init-array");
}
