brintos

brintos / llvm-project-archived public Read only

0
0
Text · 137.0 KiB · 1bfcd1f Raw
3467 lines · cpp
1//===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Gnu.h"10#include "Arch/ARM.h"11#include "Arch/CSKY.h"12#include "Arch/LoongArch.h"13#include "Arch/Mips.h"14#include "Arch/PPC.h"15#include "Arch/RISCV.h"16#include "Arch/Sparc.h"17#include "Arch/SystemZ.h"18#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX19#include "clang/Driver/CommonArgs.h"20#include "clang/Driver/Compilation.h"21#include "clang/Driver/Driver.h"22#include "clang/Driver/MultilibBuilder.h"23#include "clang/Driver/Tool.h"24#include "clang/Driver/ToolChain.h"25#include "clang/Options/Options.h"26#include "llvm/ADT/StringSet.h"27#include "llvm/ADT/Twine.h"28#include "llvm/Option/ArgList.h"29#include "llvm/Support/CodeGen.h"30#include "llvm/Support/Path.h"31#include "llvm/Support/VirtualFileSystem.h"32#include "llvm/TargetParser/RISCVISAInfo.h"33#include "llvm/TargetParser/TargetParser.h"34#include <system_error>35 36using namespace clang::driver;37using namespace clang::driver::toolchains;38using namespace clang;39using namespace llvm::opt;40 41using tools::addMultilibFlag;42using tools::addPathIfExists;43 44static bool forwardToGCC(const Option &O) {45  // LinkerInput options have been forwarded. Don't duplicate.46  if (O.hasFlag(options::LinkerInput))47    return false;48  return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption);49}50 51// Switch CPU names not recognized by GNU assembler to a close CPU that it does52// recognize, instead of a lower march from being picked in the absence of a cpu53// flag.54static void normalizeCPUNamesForAssembler(const ArgList &Args,55                                          ArgStringList &CmdArgs) {56  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {57    StringRef CPUArg(A->getValue());58    if (CPUArg.equals_insensitive("krait"))59      CmdArgs.push_back("-mcpu=cortex-a15");60    else if (CPUArg.equals_insensitive("kryo"))61      CmdArgs.push_back("-mcpu=cortex-a57");62    else63      Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);64  }65}66 67void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,68                                      const InputInfo &Output,69                                      const InputInfoList &Inputs,70                                      const ArgList &Args,71                                      const char *LinkingOutput) const {72  const Driver &D = getToolChain().getDriver();73  ArgStringList CmdArgs;74 75  for (const auto &A : Args) {76    if (forwardToGCC(A->getOption())) {77      // It is unfortunate that we have to claim here, as this means78      // we will basically never report anything interesting for79      // platforms using a generic gcc, even if we are just using gcc80      // to get to the assembler.81      A->claim();82 83      A->render(Args, CmdArgs);84    }85  }86 87  RenderExtraToolArgs(JA, CmdArgs);88 89  // If using a driver, force the arch.90  if (getToolChain().getTriple().isOSDarwin()) {91    CmdArgs.push_back("-arch");92    CmdArgs.push_back(93        Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));94  }95 96  // Try to force gcc to match the tool chain we want, if we recognize97  // the arch.98  //99  // FIXME: The triple class should directly provide the information we want100  // here.101  switch (getToolChain().getArch()) {102  default:103    break;104  case llvm::Triple::x86:105  case llvm::Triple::ppc:106  case llvm::Triple::ppcle:107    CmdArgs.push_back("-m32");108    break;109  case llvm::Triple::x86_64:110  case llvm::Triple::ppc64:111  case llvm::Triple::ppc64le:112    CmdArgs.push_back("-m64");113    break;114  case llvm::Triple::sparcel:115    CmdArgs.push_back("-EL");116    break;117  }118 119  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");120  if (Output.isFilename()) {121    CmdArgs.push_back("-o");122    CmdArgs.push_back(Output.getFilename());123  } else {124    CmdArgs.push_back("-fsyntax-only");125  }126 127  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);128 129  // Only pass -x if gcc will understand it; otherwise hope gcc130  // understands the suffix correctly. The main use case this would go131  // wrong in is for linker inputs if they happened to have an odd132  // suffix; really the only way to get this to happen is a command133  // like '-x foobar a.c' which will treat a.c like a linker input.134  //135  // FIXME: For the linker case specifically, can we safely convert136  // inputs into '-Wl,' options?137  for (const auto &II : Inputs) {138    // Don't try to pass LLVM or AST inputs to a generic gcc.139    if (types::isLLVMIR(II.getType()))140      D.Diag(clang::diag::err_drv_no_linker_llvm_support)141          << getToolChain().getTripleString();142    else if (II.getType() == types::TY_AST)143      D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString();144    else if (II.getType() == types::TY_ModuleFile)145      D.Diag(diag::err_drv_no_module_support)146          << getToolChain().getTripleString();147 148    if (types::canTypeBeUserSpecified(II.getType())) {149      CmdArgs.push_back("-x");150      CmdArgs.push_back(types::getTypeName(II.getType()));151    }152 153    if (II.isFilename())154      CmdArgs.push_back(II.getFilename());155    else {156      const Arg &A = II.getInputArg();157 158      // Reverse translate some rewritten options.159      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {160        CmdArgs.push_back("-lstdc++");161        continue;162      }163 164      // Don't render as input, we need gcc to do the translations.165      A.render(Args, CmdArgs);166    }167  }168 169  const std::string &customGCCName = D.getCCCGenericGCCName();170  const char *GCCName;171  if (!customGCCName.empty())172    GCCName = customGCCName.c_str();173  else if (D.CCCIsCXX()) {174    GCCName = "g++";175  } else176    GCCName = "gcc";177 178  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));179  C.addCommand(std::make_unique<Command>(JA, *this,180                                         ResponseFileSupport::AtFileCurCP(),181                                         Exec, CmdArgs, Inputs, Output));182}183 184void tools::gcc::Preprocessor::RenderExtraToolArgs(185    const JobAction &JA, ArgStringList &CmdArgs) const {186  CmdArgs.push_back("-E");187}188 189void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,190                                               ArgStringList &CmdArgs) const {191  const Driver &D = getToolChain().getDriver();192 193  switch (JA.getType()) {194  // If -flto, etc. are present then make sure not to force assembly output.195  case types::TY_LLVM_IR:196  case types::TY_LTO_IR:197  case types::TY_LLVM_BC:198  case types::TY_LTO_BC:199    CmdArgs.push_back("-c");200    break;201  // We assume we've got an "integrated" assembler in that gcc will produce an202  // object file itself.203  case types::TY_Object:204    CmdArgs.push_back("-c");205    break;206  case types::TY_PP_Asm:207    CmdArgs.push_back("-S");208    break;209  case types::TY_Nothing:210    CmdArgs.push_back("-fsyntax-only");211    break;212  default:213    D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());214  }215}216 217void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,218                                             ArgStringList &CmdArgs) const {219  // The types are (hopefully) good enough.220}221 222static bool getStatic(const ArgList &Args) {223  return Args.hasArg(options::OPT_static) &&224      !Args.hasArg(options::OPT_static_pie);225}226 227void tools::gnutools::StaticLibTool::ConstructJob(228    Compilation &C, const JobAction &JA, const InputInfo &Output,229    const InputInfoList &Inputs, const ArgList &Args,230    const char *LinkingOutput) const {231  const Driver &D = getToolChain().getDriver();232 233  // Silence warning for "clang -g foo.o -o foo"234  Args.ClaimAllArgs(options::OPT_g_Group);235  // and "clang -emit-llvm foo.o -o foo"236  Args.ClaimAllArgs(options::OPT_emit_llvm);237  // and for "clang -w foo.o -o foo". Other warning options are already238  // handled somewhere else.239  Args.ClaimAllArgs(options::OPT_w);240  // Silence warnings when linking C code with a C++ '-stdlib' argument.241  Args.ClaimAllArgs(options::OPT_stdlib_EQ);242 243  // ar tool command "llvm-ar <options> <output_file> <input_files>".244  ArgStringList CmdArgs;245  // Create and insert file members with a deterministic index.246  CmdArgs.push_back("rcsD");247  CmdArgs.push_back(Output.getFilename());248 249  for (const auto &II : Inputs) {250    if (II.isFilename()) {251       CmdArgs.push_back(II.getFilename());252    }253  }254 255  // Delete old output archive file if it already exists before generating a new256  // archive file.257  auto OutputFileName = Output.getFilename();258  if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {259    if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {260      D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();261      return;262    }263  }264 265  const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());266  C.addCommand(std::make_unique<Command>(JA, *this,267                                         ResponseFileSupport::AtFileCurCP(),268                                         Exec, CmdArgs, Inputs, Output));269}270 271void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,272                                           const InputInfo &Output,273                                           const InputInfoList &Inputs,274                                           const ArgList &Args,275                                           const char *LinkingOutput) const {276  // FIXME: The Linker class constructor takes a ToolChain and not a277  // Generic_ELF, so the static_cast might return a reference to a invalid278  // instance (see PR45061). Ideally, the Linker constructor needs to take a279  // Generic_ELF instead.280  const auto &ToolChain = static_cast<const Generic_ELF &>(getToolChain());281  const Driver &D = ToolChain.getDriver();282 283  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();284 285  const llvm::Triple::ArchType Arch = ToolChain.getArch();286  const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily();287  const bool isAndroid = ToolChain.getTriple().isAndroid();288  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();289  const bool IsVE = ToolChain.getTriple().isVE();290  const bool IsStaticPIE = getStaticPIE(Args, ToolChain);291  const bool IsStatic = getStatic(Args);292  const bool HasCRTBeginEndFiles =293      ToolChain.getTriple().hasEnvironment() ||294      (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);295 296  ArgStringList CmdArgs;297 298  // Silence warning for "clang -g foo.o -o foo"299  Args.ClaimAllArgs(options::OPT_g_Group);300  // and "clang -emit-llvm foo.o -o foo"301  Args.ClaimAllArgs(options::OPT_emit_llvm);302  // and for "clang -w foo.o -o foo". Other warning options are already303  // handled somewhere else.304  Args.ClaimAllArgs(options::OPT_w);305 306  if (!D.SysRoot.empty())307    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));308 309  if (Args.hasArg(options::OPT_s))310    CmdArgs.push_back("-s");311 312  if (Triple.isARM() || Triple.isThumb()) {313    bool IsBigEndian = arm::isARMBigEndian(Triple, Args);314    if (IsBigEndian)315      arm::appendBE8LinkFlag(Args, CmdArgs, Triple);316    CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");317  } else if (Triple.isAArch64()) {318    CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");319  }320 321  // Most Android ARM64 targets should enable the linker fix for erratum322  // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.323  if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily) &&324      Args.hasFlag(options::OPT_mfix_cortex_a53_843419,325                   options::OPT_mno_fix_cortex_a53_843419, true)) {326    std::string CPU = getCPUName(D, Args, Triple);327    if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")328      CmdArgs.push_back("--fix-cortex-a53-843419");329  }330 331  ToolChain.addExtraOpts(CmdArgs);332 333  CmdArgs.push_back("--eh-frame-hdr");334 335  if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) {336    CmdArgs.push_back("-m");337    CmdArgs.push_back(LDMOption);338  } else {339    D.Diag(diag::err_target_unknown_triple) << Triple.str();340    return;341  }342 343  if (Triple.isLoongArch() || Triple.isRISCV()) {344    CmdArgs.push_back("-X");345    if (Args.hasArg(options::OPT_mno_relax))346      CmdArgs.push_back("--no-relax");347  }348 349  const bool IsShared = Args.hasArg(options::OPT_shared);350  if (IsShared)351    CmdArgs.push_back("-shared");352  bool IsPIE = false;353  if (IsStaticPIE) {354    CmdArgs.push_back("-static");355    CmdArgs.push_back("-pie");356    CmdArgs.push_back("--no-dynamic-linker");357    CmdArgs.push_back("-z");358    CmdArgs.push_back("text");359  } else if (IsStatic) {360    CmdArgs.push_back("-static");361  } else if (!Args.hasArg(options::OPT_r)) {362    if (Args.hasArg(options::OPT_rdynamic))363      CmdArgs.push_back("-export-dynamic");364    if (!IsShared) {365      IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,366                           ToolChain.isPIEDefault(Args));367      if (IsPIE)368        CmdArgs.push_back("-pie");369      CmdArgs.push_back("-dynamic-linker");370      CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +371                                           ToolChain.getDynamicLinker(Args)));372    }373  }374 375  CmdArgs.push_back("-o");376  CmdArgs.push_back(Output.getFilename());377 378  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,379                   options::OPT_r)) {380    if (!isAndroid && !IsIAMCU) {381      const char *crt1 = nullptr;382      if (!Args.hasArg(options::OPT_shared)) {383        if (Args.hasArg(options::OPT_pg))384          crt1 = "gcrt1.o";385        else if (IsPIE)386          crt1 = "Scrt1.o";387        else if (IsStaticPIE)388          crt1 = "rcrt1.o";389        else390          crt1 = "crt1.o";391      }392      if (crt1)393        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));394 395      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));396    }397 398    if (IsVE) {399      CmdArgs.push_back("-z");400      CmdArgs.push_back("max-page-size=0x4000000");401    }402 403    if (IsIAMCU)404      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));405    else if (HasCRTBeginEndFiles) {406      std::string P;407      if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&408          !isAndroid) {409        std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin",410                                                       ToolChain::FT_Object);411        if (ToolChain.getVFS().exists(crtbegin))412          P = crtbegin;413      }414      if (P.empty()) {415        const char *crtbegin;416        if (Args.hasArg(options::OPT_shared))417          crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";418        else if (IsStatic)419          crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";420        else if (IsPIE || IsStaticPIE)421          crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";422        else423          crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";424        P = ToolChain.GetFilePath(crtbegin);425      }426      CmdArgs.push_back(Args.MakeArgString(P));427    }428 429    // Add crtfastmath.o if available and fast math is enabled.430    ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs);431 432    if (isAndroid && Args.hasFlag(options::OPT_fandroid_pad_segment,433                                  options::OPT_fno_android_pad_segment, false))434      CmdArgs.push_back(435          Args.MakeArgString(ToolChain.GetFilePath("crt_pad_segment.o")));436  }437 438  Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});439 440  ToolChain.AddFilePathLibArgs(Args, CmdArgs);441 442  if (D.isUsingLTO())443    addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs,444                  D.getLTOMode() == LTOK_Thin);445 446  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))447    CmdArgs.push_back("--no-demangle");448 449  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);450  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);451  addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);452  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);453 454  addHIPRuntimeLibArgs(ToolChain, C, Args, CmdArgs);455 456  // The profile runtime also needs access to system libraries.457  getToolChain().addProfileRTLibs(Args, CmdArgs);458 459  if (D.CCCIsCXX() &&460      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,461                   options::OPT_r)) {462    if (ToolChain.ShouldLinkCXXStdlib(Args)) {463      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&464                                 !Args.hasArg(options::OPT_static);465      if (OnlyLibstdcxxStatic)466        CmdArgs.push_back("-Bstatic");467      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);468      if (OnlyLibstdcxxStatic)469        CmdArgs.push_back("-Bdynamic");470    }471    CmdArgs.push_back("-lm");472  }473 474  // Silence warnings when linking C code with a C++ '-stdlib' argument.475  Args.ClaimAllArgs(options::OPT_stdlib_EQ);476 477  // Additional linker set-up and flags for Fortran. This is required in order478  // to generate executables. As Fortran runtime depends on the C runtime,479  // these dependencies need to be listed before the C runtime below (i.e.480  // AddRunTimeLibs).481  if (D.IsFlangMode() &&482      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {483    ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);484    ToolChain.addFortranRuntimeLibs(Args, CmdArgs);485    CmdArgs.push_back("-lm");486  }487 488  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) {489    if (!Args.hasArg(options::OPT_nodefaultlibs)) {490      if (IsStatic || IsStaticPIE)491        CmdArgs.push_back("--start-group");492 493      if (NeedsSanitizerDeps)494        linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs);495 496      if (NeedsXRayDeps)497        linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);498 499      bool WantPthread = Args.hasArg(options::OPT_pthread) ||500                         Args.hasArg(options::OPT_pthreads);501 502      // Use the static OpenMP runtime with -static-openmp503      bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&504                          !Args.hasArg(options::OPT_static);505 506      // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that507      // require librt. Most modern Linux platforms do, but some may not.508      if (addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP,509                           JA.isHostOffloading(Action::OFK_OpenMP),510                           /* GompNeedsRT= */ true))511        // OpenMP runtimes implies pthreads when using the GNU toolchain.512        // FIXME: Does this really make sense for all GNU toolchains?513        WantPthread = true;514 515      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);516 517      // LLVM support for atomics on 32-bit SPARC V8+ is incomplete, so518      // forcibly link with libatomic as a workaround.519      // TODO: Issue #41880 and D118021.520      if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) {521        CmdArgs.push_back("--push-state");522        CmdArgs.push_back("--as-needed");523        CmdArgs.push_back("-latomic");524        CmdArgs.push_back("--pop-state");525      }526 527      // We don't need libpthread neither for bionic (Android) nor for musl,528      // (used by OHOS as runtime library).529      if (WantPthread && !isAndroid && !isOHOSFamily)530        CmdArgs.push_back("-lpthread");531 532      if (Args.hasArg(options::OPT_fsplit_stack))533        CmdArgs.push_back("--wrap=pthread_create");534 535      if (!Args.hasArg(options::OPT_nolibc))536        CmdArgs.push_back("-lc");537 538      // Add IAMCU specific libs, if needed.539      if (IsIAMCU)540        CmdArgs.push_back("-lgloss");541 542      if (IsStatic || IsStaticPIE)543        CmdArgs.push_back("--end-group");544      else545        AddRunTimeLibs(ToolChain, D, CmdArgs, Args);546 547      // Add IAMCU specific libs (outside the group), if needed.548      if (IsIAMCU) {549        CmdArgs.push_back("--as-needed");550        CmdArgs.push_back("-lsoftfp");551        CmdArgs.push_back("--no-as-needed");552      }553    }554 555    if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {556      if (HasCRTBeginEndFiles) {557        std::string P;558        if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&559            !isAndroid) {560          std::string crtend = ToolChain.getCompilerRT(Args, "crtend",561                                                       ToolChain::FT_Object);562          if (ToolChain.getVFS().exists(crtend))563            P = crtend;564        }565        if (P.empty()) {566          const char *crtend;567          if (Args.hasArg(options::OPT_shared))568            crtend = isAndroid ? "crtend_so.o" : "crtendS.o";569          else if (IsPIE || IsStaticPIE)570            crtend = isAndroid ? "crtend_android.o" : "crtendS.o";571          else572            crtend = isAndroid ? "crtend_android.o" : "crtend.o";573          P = ToolChain.GetFilePath(crtend);574        }575        CmdArgs.push_back(Args.MakeArgString(P));576      }577      if (!isAndroid)578        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));579    }580  }581 582  Args.addAllArgs(CmdArgs, {options::OPT_T, options::OPT_t});583 584  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());585  C.addCommand(std::make_unique<Command>(JA, *this,586                                         ResponseFileSupport::AtFileCurCP(),587                                         Exec, CmdArgs, Inputs, Output));588}589 590void tools::gnutools::Assembler::ConstructJob(Compilation &C,591                                              const JobAction &JA,592                                              const InputInfo &Output,593                                              const InputInfoList &Inputs,594                                              const ArgList &Args,595                                              const char *LinkingOutput) const {596  const auto &D = getToolChain().getDriver();597 598  claimNoWarnArgs(Args);599 600  ArgStringList CmdArgs;601 602  llvm::Reloc::Model RelocationModel;603  unsigned PICLevel;604  bool IsPIE;605  const char *DefaultAssembler = "as";606  // Enforce GNU as on Solaris; the native assembler's input syntax isn't fully607  // compatible.608  if (getToolChain().getTriple().isOSSolaris())609    DefaultAssembler = "gas";610  std::tie(RelocationModel, PICLevel, IsPIE) =611      ParsePICArgs(getToolChain(), Args);612 613  if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) {614    if (A->getOption().getID() == options::OPT_gz) {615      CmdArgs.push_back("--compress-debug-sections");616    } else {617      StringRef Value = A->getValue();618      if (Value == "none" || Value == "zlib" || Value == "zstd") {619        CmdArgs.push_back(620            Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));621      } else {622        D.Diag(diag::err_drv_unsupported_option_argument)623            << A->getSpelling() << Value;624      }625    }626  }627 628  switch (getToolChain().getArch()) {629  default:630    break;631  // Add --32/--64 to make sure we get the format we want.632  // This is incomplete633  case llvm::Triple::x86:634    CmdArgs.push_back("--32");635    break;636  case llvm::Triple::x86_64:637    if (getToolChain().getTriple().isX32())638      CmdArgs.push_back("--x32");639    else640      CmdArgs.push_back("--64");641    break;642  case llvm::Triple::ppc: {643    CmdArgs.push_back("-a32");644    CmdArgs.push_back("-mppc");645    CmdArgs.push_back("-mbig-endian");646    CmdArgs.push_back(ppc::getPPCAsmModeForCPU(647        getCPUName(D, Args, getToolChain().getTriple())));648    break;649  }650  case llvm::Triple::ppcle: {651    CmdArgs.push_back("-a32");652    CmdArgs.push_back("-mppc");653    CmdArgs.push_back("-mlittle-endian");654    CmdArgs.push_back(ppc::getPPCAsmModeForCPU(655        getCPUName(D, Args, getToolChain().getTriple())));656    break;657  }658  case llvm::Triple::ppc64: {659    CmdArgs.push_back("-a64");660    CmdArgs.push_back("-mppc64");661    CmdArgs.push_back("-mbig-endian");662    CmdArgs.push_back(ppc::getPPCAsmModeForCPU(663        getCPUName(D, Args, getToolChain().getTriple())));664    break;665  }666  case llvm::Triple::ppc64le: {667    CmdArgs.push_back("-a64");668    CmdArgs.push_back("-mppc64");669    CmdArgs.push_back("-mlittle-endian");670    CmdArgs.push_back(ppc::getPPCAsmModeForCPU(671        getCPUName(D, Args, getToolChain().getTriple())));672    break;673  }674  case llvm::Triple::riscv32:675  case llvm::Triple::riscv64: {676    StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());677    CmdArgs.push_back("-mabi");678    CmdArgs.push_back(ABIName.data());679    std::string MArchName =680        riscv::getRISCVArch(Args, getToolChain().getTriple());681    CmdArgs.push_back("-march");682    CmdArgs.push_back(Args.MakeArgString(MArchName));683    if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))684      Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);685    break;686  }687  case llvm::Triple::sparc:688  case llvm::Triple::sparcel: {689    CmdArgs.push_back("-32");690    std::string CPU = getCPUName(D, Args, getToolChain().getTriple());691    CmdArgs.push_back(692        sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));693    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);694    break;695  }696  case llvm::Triple::sparcv9: {697    CmdArgs.push_back("-64");698    std::string CPU = getCPUName(D, Args, getToolChain().getTriple());699    CmdArgs.push_back(700        sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));701    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);702    break;703  }704  case llvm::Triple::arm:705  case llvm::Triple::armeb:706  case llvm::Triple::thumb:707  case llvm::Triple::thumbeb: {708    const llvm::Triple &Triple2 = getToolChain().getTriple();709    CmdArgs.push_back(arm::isARMBigEndian(Triple2, Args) ? "-EB" : "-EL");710    switch (Triple2.getSubArch()) {711    case llvm::Triple::ARMSubArch_v7:712      CmdArgs.push_back("-mfpu=neon");713      break;714    case llvm::Triple::ARMSubArch_v8:715      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");716      break;717    default:718      break;719    }720 721    switch (arm::getARMFloatABI(getToolChain(), Args)) {722    case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");723    case arm::FloatABI::Soft:724      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));725      break;726    case arm::FloatABI::SoftFP:727      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));728      break;729    case arm::FloatABI::Hard:730      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));731      break;732    }733 734    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);735    normalizeCPUNamesForAssembler(Args, CmdArgs);736 737    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);738    // The integrated assembler doesn't implement e_flags setting behavior for739    // -meabi=gnu (gcc -mabi={apcs-gnu,atpcs} passes -meabi=gnu to gas). For740    // compatibility we accept but warn.741    if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))742      A->ignoreTargetSpecific();743    break;744  }745  case llvm::Triple::aarch64:746  case llvm::Triple::aarch64_be: {747    CmdArgs.push_back(748        getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL");749    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);750    normalizeCPUNamesForAssembler(Args, CmdArgs);751 752    break;753  }754  // TODO: handle loongarch32.755  case llvm::Triple::loongarch64: {756    StringRef ABIName =757        loongarch::getLoongArchABI(D, Args, getToolChain().getTriple());758    CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName));759    break;760  }761  case llvm::Triple::mips:762  case llvm::Triple::mipsel:763  case llvm::Triple::mips64:764  case llvm::Triple::mips64el: {765    StringRef CPUName;766    StringRef ABIName;767    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);768    ABIName = mips::getGnuCompatibleMipsABIName(ABIName);769 770    CmdArgs.push_back("-march");771    CmdArgs.push_back(CPUName.data());772 773    CmdArgs.push_back("-mabi");774    CmdArgs.push_back(ABIName.data());775 776    // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,777    // or -mshared (not implemented) is in effect.778    if (RelocationModel == llvm::Reloc::Static)779      CmdArgs.push_back("-mno-shared");780 781    // LLVM doesn't support -mplt yet and acts as if it is always given.782    // However, -mplt has no effect with the N64 ABI.783    if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls))784      CmdArgs.push_back("-call_nonpic");785 786    if (getToolChain().getTriple().isLittleEndian())787      CmdArgs.push_back("-EL");788    else789      CmdArgs.push_back("-EB");790 791    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {792      if (StringRef(A->getValue()) == "2008")793        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));794    }795 796    // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.797    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,798                                 options::OPT_mfp64)) {799      A->claim();800      A->render(Args, CmdArgs);801    } else if (mips::shouldUseFPXX(802                   Args, getToolChain().getTriple(), CPUName, ABIName,803                   mips::getMipsFloatABI(getToolChain().getDriver(), Args,804                                         getToolChain().getTriple())))805      CmdArgs.push_back("-mfpxx");806 807    // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of808    // -mno-mips16 is actually -no-mips16.809    if (Arg *A =810            Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {811      if (A->getOption().matches(options::OPT_mips16)) {812        A->claim();813        A->render(Args, CmdArgs);814      } else {815        A->claim();816        CmdArgs.push_back("-no-mips16");817      }818    }819 820    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,821                    options::OPT_mno_micromips);822    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);823    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);824 825    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {826      // Do not use AddLastArg because not all versions of MIPS assembler827      // support -mmsa / -mno-msa options.828      if (A->getOption().matches(options::OPT_mmsa))829        CmdArgs.push_back(Args.MakeArgString("-mmsa"));830    }831 832    Args.AddLastArg(CmdArgs, options::OPT_mhard_float,833                    options::OPT_msoft_float);834 835    Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,836                    options::OPT_msingle_float);837 838    Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,839                    options::OPT_mno_odd_spreg);840 841    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);842    break;843  }844  case llvm::Triple::systemz: {845    // Always pass an -march option, since our default of z10 is later846    // than the GNU assembler's default.847    std::string CPUName =848        systemz::getSystemZTargetCPU(Args, getToolChain().getTriple());849    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));850    break;851  }852  case llvm::Triple::ve:853    DefaultAssembler = "nas";854  }855 856  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,857                                    options::OPT_fdebug_prefix_map_EQ)) {858    StringRef Map = A->getValue();859    if (!Map.contains('='))860      D.Diag(diag::err_drv_invalid_argument_to_option)861          << Map << A->getOption().getName();862    else {863      CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map"));864      CmdArgs.push_back(Args.MakeArgString(Map));865    }866    A->claim();867  }868 869  Args.AddAllArgs(CmdArgs, options::OPT_I);870  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);871 872  CmdArgs.push_back("-o");873  CmdArgs.push_back(Output.getFilename());874 875  for (const auto &II : Inputs)876    CmdArgs.push_back(II.getFilename());877 878  if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group,879                               options::OPT_gdwarf_2, options::OPT_gdwarf_3,880                               options::OPT_gdwarf_4, options::OPT_gdwarf_5,881                               options::OPT_gdwarf))882    if (!A->getOption().matches(options::OPT_g0)) {883      Args.AddLastArg(CmdArgs, options::OPT_g_Flag);884 885      unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args);886      CmdArgs.push_back(Args.MakeArgString("-gdwarf-" + Twine(DwarfVersion)));887    }888 889  const char *Exec =890      Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));891  C.addCommand(std::make_unique<Command>(JA, *this,892                                         ResponseFileSupport::AtFileCurCP(),893                                         Exec, CmdArgs, Inputs, Output));894 895  // Handle the debug info splitting at object creation time if we're896  // creating an object.897  // TODO: Currently only works on linux with newer objcopy.898  if (Args.hasArg(options::OPT_gsplit_dwarf) &&899      getToolChain().getTriple().isOSLinux())900    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,901                   SplitDebugName(JA, Args, Inputs[0], Output));902}903 904namespace {905// Filter to remove Multilibs that don't exist as a suffix to Path906class FilterNonExistent {907  StringRef Base, File;908  llvm::vfs::FileSystem &VFS;909 910public:911  FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS)912      : Base(Base), File(File), VFS(VFS) {}913  bool operator()(const Multilib &M) {914    return !VFS.exists(Base + M.gccSuffix() + File);915  }916};917} // end anonymous namespace918 919static bool isSoftFloatABI(const ArgList &Args) {920  Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,921                           options::OPT_mfloat_abi_EQ);922  if (!A)923    return false;924 925  return A->getOption().matches(options::OPT_msoft_float) ||926         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&927          A->getValue() == StringRef("soft"));928}929 930static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {931  return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;932}933 934static bool isMipsEL(llvm::Triple::ArchType Arch) {935  return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;936}937 938static bool isMips16(const ArgList &Args) {939  Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);940  return A && A->getOption().matches(options::OPT_mips16);941}942 943static bool isMicroMips(const ArgList &Args) {944  Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);945  return A && A->getOption().matches(options::OPT_mmicromips);946}947 948static bool isMSP430(llvm::Triple::ArchType Arch) {949  return Arch == llvm::Triple::msp430;950}951 952static bool findMipsCsMultilibs(const Driver &D,953                                const Multilib::flags_list &Flags,954                                FilterNonExistent &NonExistent,955                                DetectedMultilibs &Result) {956  // Check for Code Sourcery toolchain multilibs957  MultilibSet CSMipsMultilibs;958  {959    auto MArchMips16 = MultilibBuilder("/mips16").flag("-m32").flag("-mips16");960 961    auto MArchMicroMips =962        MultilibBuilder("/micromips").flag("-m32").flag("-mmicromips");963 964    auto MArchDefault = MultilibBuilder("")965                            .flag("-mips16", /*Disallow=*/true)966                            .flag("-mmicromips", /*Disallow=*/true);967 968    auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc");969 970    auto SoftFloat = MultilibBuilder("/soft-float").flag("-msoft-float");971 972    auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008");973 974    auto DefaultFloat = MultilibBuilder("")975                            .flag("-msoft-float", /*Disallow=*/true)976                            .flag("-mnan=2008", /*Disallow=*/true);977 978    auto BigEndian =979        MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true);980 981    auto LittleEndian =982        MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true);983 984    // Note that this one's osSuffix is ""985    auto MAbi64 = MultilibBuilder("")986                      .gccSuffix("/64")987                      .includeSuffix("/64")988                      .flag("-mabi=n64")989                      .flag("-mabi=n32", /*Disallow=*/true)990                      .flag("-m32", /*Disallow=*/true);991 992    CSMipsMultilibs =993        MultilibSetBuilder()994            .Either(MArchMips16, MArchMicroMips, MArchDefault)995            .Maybe(UCLibc)996            .Either(SoftFloat, Nan2008, DefaultFloat)997            .FilterOut("/micromips/nan2008")998            .FilterOut("/mips16/nan2008")999            .Either(BigEndian, LittleEndian)1000            .Maybe(MAbi64)1001            .FilterOut("/mips16.*/64")1002            .FilterOut("/micromips.*/64")1003            .makeMultilibSet()1004            .FilterOut(NonExistent)1005            .setIncludeDirsCallback([](const Multilib &M) {1006              std::vector<std::string> Dirs({"/include"});1007              if (StringRef(M.includeSuffix()).starts_with("/uclibc"))1008                Dirs.push_back(1009                    "/../../../../mips-linux-gnu/libc/uclibc/usr/include");1010              else1011                Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");1012              return Dirs;1013            });1014  }1015 1016  MultilibSet DebianMipsMultilibs;1017  {1018    MultilibBuilder MAbiN32 =1019        MultilibBuilder().gccSuffix("/n32").includeSuffix("/n32").flag(1020            "-mabi=n32");1021 1022    MultilibBuilder M64 = MultilibBuilder()1023                              .gccSuffix("/64")1024                              .includeSuffix("/64")1025                              .flag("-m64")1026                              .flag("-m32", /*Disallow=*/true)1027                              .flag("-mabi=n32", /*Disallow=*/true);1028 1029    MultilibBuilder M32 = MultilibBuilder()1030                              .gccSuffix("/32")1031                              .flag("-m64", /*Disallow=*/true)1032                              .flag("-m32")1033                              .flag("-mabi=n32", /*Disallow=*/true);1034 1035    DebianMipsMultilibs = MultilibSetBuilder()1036                              .Either(M32, M64, MAbiN32)1037                              .makeMultilibSet()1038                              .FilterOut(NonExistent);1039  }1040 1041  // Sort candidates. Toolchain that best meets the directories tree goes first.1042  // Then select the first toolchains matches command line flags.1043  MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};1044  if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())1045    std::iter_swap(Candidates, Candidates + 1);1046  for (const MultilibSet *Candidate : Candidates) {1047    if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {1048      if (Candidate == &DebianMipsMultilibs)1049        Result.BiarchSibling = Multilib();1050      Result.Multilibs = *Candidate;1051      return true;1052    }1053  }1054  return false;1055}1056 1057static bool findMipsMuslMultilibs(const Driver &D,1058                                  const Multilib::flags_list &Flags,1059                                  FilterNonExistent &NonExistent,1060                                  DetectedMultilibs &Result) {1061  // Musl toolchain multilibs1062  MultilibSet MuslMipsMultilibs;1063  {1064    auto MArchMipsR2 = MultilibBuilder("")1065                           .osSuffix("/mips-r2-hard-musl")1066                           .flag("-EB")1067                           .flag("-EL", /*Disallow=*/true)1068                           .flag("-march=mips32r2");1069 1070    auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl")1071                             .flag("-EB", /*Disallow=*/true)1072                             .flag("-EL")1073                             .flag("-march=mips32r2");1074 1075    MuslMipsMultilibs = MultilibSetBuilder()1076                            .Either(MArchMipsR2, MArchMipselR2)1077                            .makeMultilibSet();1078 1079    // Specify the callback that computes the include directories.1080    MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {1081      return std::vector<std::string>(1082          {"/../sysroot" + M.osSuffix() + "/usr/include"});1083    });1084  }1085  if (MuslMipsMultilibs.select(D, Flags, Result.SelectedMultilibs)) {1086    Result.Multilibs = MuslMipsMultilibs;1087    return true;1088  }1089  return false;1090}1091 1092static bool findMipsMtiMultilibs(const Driver &D,1093                                 const Multilib::flags_list &Flags,1094                                 FilterNonExistent &NonExistent,1095                                 DetectedMultilibs &Result) {1096  // CodeScape MTI toolchain v1.2 and early.1097  MultilibSet MtiMipsMultilibsV1;1098  {1099    auto MArchMips32 = MultilibBuilder("/mips32")1100                           .flag("-m32")1101                           .flag("-m64", /*Disallow=*/true)1102                           .flag("-mmicromips", /*Disallow=*/true)1103                           .flag("-march=mips32");1104 1105    auto MArchMicroMips = MultilibBuilder("/micromips")1106                              .flag("-m32")1107                              .flag("-m64", /*Disallow=*/true)1108                              .flag("-mmicromips");1109 1110    auto MArchMips64r2 = MultilibBuilder("/mips64r2")1111                             .flag("-m32", /*Disallow=*/true)1112                             .flag("-m64")1113                             .flag("-march=mips64r2");1114 1115    auto MArchMips64 = MultilibBuilder("/mips64")1116                           .flag("-m32", /*Disallow=*/true)1117                           .flag("-m64")1118                           .flag("-march=mips64r2", /*Disallow=*/true);1119 1120    auto MArchDefault = MultilibBuilder("")1121                            .flag("-m32")1122                            .flag("-m64", /*Disallow=*/true)1123                            .flag("-mmicromips", /*Disallow=*/true)1124                            .flag("-march=mips32r2");1125 1126    auto Mips16 = MultilibBuilder("/mips16").flag("-mips16");1127 1128    auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc");1129 1130    auto MAbi64 = MultilibBuilder("/64")1131                      .flag("-mabi=n64")1132                      .flag("-mabi=n32", /*Disallow=*/true)1133                      .flag("-m32", /*Disallow=*/true);1134 1135    auto BigEndian =1136        MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true);1137 1138    auto LittleEndian =1139        MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true);1140 1141    auto SoftFloat = MultilibBuilder("/sof").flag("-msoft-float");1142 1143    auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008");1144 1145    MtiMipsMultilibsV1 =1146        MultilibSetBuilder()1147            .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,1148                    MArchDefault)1149            .Maybe(UCLibc)1150            .Maybe(Mips16)1151            .FilterOut("/mips64/mips16")1152            .FilterOut("/mips64r2/mips16")1153            .FilterOut("/micromips/mips16")1154            .Maybe(MAbi64)1155            .FilterOut("/micromips/64")1156            .FilterOut("/mips32/64")1157            .FilterOut("^/64")1158            .FilterOut("/mips16/64")1159            .Either(BigEndian, LittleEndian)1160            .Maybe(SoftFloat)1161            .Maybe(Nan2008)1162            .FilterOut(".*sof/nan2008")1163            .makeMultilibSet()1164            .FilterOut(NonExistent)1165            .setIncludeDirsCallback([](const Multilib &M) {1166              std::vector<std::string> Dirs({"/include"});1167              if (StringRef(M.includeSuffix()).starts_with("/uclibc"))1168                Dirs.push_back("/../../../../sysroot/uclibc/usr/include");1169              else1170                Dirs.push_back("/../../../../sysroot/usr/include");1171              return Dirs;1172            });1173  }1174 1175  // CodeScape IMG toolchain starting from v1.3.1176  MultilibSet MtiMipsMultilibsV2;1177  {1178    auto BeHard = MultilibBuilder("/mips-r2-hard")1179                      .flag("-EB")1180                      .flag("-msoft-float", /*Disallow=*/true)1181                      .flag("-mnan=2008", /*Disallow=*/true)1182                      .flag("-muclibc", /*Disallow=*/true);1183    auto BeSoft = MultilibBuilder("/mips-r2-soft")1184                      .flag("-EB")1185                      .flag("-msoft-float")1186                      .flag("-mnan=2008", /*Disallow=*/true);1187    auto ElHard = MultilibBuilder("/mipsel-r2-hard")1188                      .flag("-EL")1189                      .flag("-msoft-float", /*Disallow=*/true)1190                      .flag("-mnan=2008", /*Disallow=*/true)1191                      .flag("-muclibc", /*Disallow=*/true);1192    auto ElSoft = MultilibBuilder("/mipsel-r2-soft")1193                      .flag("-EL")1194                      .flag("-msoft-float")1195                      .flag("-mnan=2008", /*Disallow=*/true)1196                      .flag("-mmicromips", /*Disallow=*/true);1197    auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008")1198                         .flag("-EB")1199                         .flag("-msoft-float", /*Disallow=*/true)1200                         .flag("-mnan=2008")1201                         .flag("-muclibc", /*Disallow=*/true);1202    auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008")1203                         .flag("-EL")1204                         .flag("-msoft-float", /*Disallow=*/true)1205                         .flag("-mnan=2008")1206                         .flag("-muclibc", /*Disallow=*/true)1207                         .flag("-mmicromips", /*Disallow=*/true);1208    auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc")1209                               .flag("-EB")1210                               .flag("-msoft-float", /*Disallow=*/true)1211                               .flag("-mnan=2008")1212                               .flag("-muclibc");1213    auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc")1214                               .flag("-EL")1215                               .flag("-msoft-float", /*Disallow=*/true)1216                               .flag("-mnan=2008")1217                               .flag("-muclibc");1218    auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc")1219                            .flag("-EB")1220                            .flag("-msoft-float", /*Disallow=*/true)1221                            .flag("-mnan=2008", /*Disallow=*/true)1222                            .flag("-muclibc");1223    auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc")1224                            .flag("-EL")1225                            .flag("-msoft-float", /*Disallow=*/true)1226                            .flag("-mnan=2008", /*Disallow=*/true)1227                            .flag("-muclibc");1228    auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008")1229                              .flag("-EL")1230                              .flag("-msoft-float", /*Disallow=*/true)1231                              .flag("-mnan=2008")1232                              .flag("-mmicromips");1233    auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft")1234                           .flag("-EL")1235                           .flag("-msoft-float")1236                           .flag("-mnan=2008", /*Disallow=*/true)1237                           .flag("-mmicromips");1238 1239    auto O32 = MultilibBuilder("/lib")1240                   .osSuffix("")1241                   .flag("-mabi=n32", /*Disallow=*/true)1242                   .flag("-mabi=n64", /*Disallow=*/true);1243    auto N32 = MultilibBuilder("/lib32")1244                   .osSuffix("")1245                   .flag("-mabi=n32")1246                   .flag("-mabi=n64", /*Disallow=*/true);1247    auto N64 = MultilibBuilder("/lib64")1248                   .osSuffix("")1249                   .flag("-mabi=n32", /*Disallow=*/true)1250                   .flag("-mabi=n64");1251 1252    MtiMipsMultilibsV2 =1253        MultilibSetBuilder()1254            .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,1255                     BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,1256                     ElHardUclibc, ElMicroHardNan, ElMicroSoft})1257            .Either(O32, N32, N64)1258            .makeMultilibSet()1259            .FilterOut(NonExistent)1260            .setIncludeDirsCallback([](const Multilib &M) {1261              return std::vector<std::string>({"/../../../../sysroot" +1262                                               M.includeSuffix() +1263                                               "/../usr/include"});1264            })1265            .setFilePathsCallback([](const Multilib &M) {1266              return std::vector<std::string>(1267                  {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});1268            });1269  }1270  for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {1271    if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {1272      Result.Multilibs = *Candidate;1273      return true;1274    }1275  }1276  return false;1277}1278 1279static bool findMipsImgMultilibs(const Driver &D,1280                                 const Multilib::flags_list &Flags,1281                                 FilterNonExistent &NonExistent,1282                                 DetectedMultilibs &Result) {1283  // CodeScape IMG toolchain v1.2 and early.1284  MultilibSet ImgMultilibsV1;1285  {1286    auto Mips64r6 = MultilibBuilder("/mips64r6")1287                        .flag("-m64")1288                        .flag("-m32", /*Disallow=*/true);1289 1290    auto LittleEndian =1291        MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true);1292 1293    auto MAbi64 = MultilibBuilder("/64")1294                      .flag("-mabi=n64")1295                      .flag("-mabi=n32", /*Disallow=*/true)1296                      .flag("-m32", /*Disallow=*/true);1297 1298    ImgMultilibsV1 =1299        MultilibSetBuilder()1300            .Maybe(Mips64r6)1301            .Maybe(MAbi64)1302            .Maybe(LittleEndian)1303            .makeMultilibSet()1304            .FilterOut(NonExistent)1305            .setIncludeDirsCallback([](const Multilib &M) {1306              return std::vector<std::string>(1307                  {"/include", "/../../../../sysroot/usr/include"});1308            });1309  }1310 1311  // CodeScape IMG toolchain starting from v1.3.1312  MultilibSet ImgMultilibsV2;1313  {1314    auto BeHard = MultilibBuilder("/mips-r6-hard")1315                      .flag("-EB")1316                      .flag("-msoft-float", /*Disallow=*/true)1317                      .flag("-mmicromips", /*Disallow=*/true);1318    auto BeSoft = MultilibBuilder("/mips-r6-soft")1319                      .flag("-EB")1320                      .flag("-msoft-float")1321                      .flag("-mmicromips", /*Disallow=*/true);1322    auto ElHard = MultilibBuilder("/mipsel-r6-hard")1323                      .flag("-EL")1324                      .flag("-msoft-float", /*Disallow=*/true)1325                      .flag("-mmicromips", /*Disallow=*/true);1326    auto ElSoft = MultilibBuilder("/mipsel-r6-soft")1327                      .flag("-EL")1328                      .flag("-msoft-float")1329                      .flag("-mmicromips", /*Disallow=*/true);1330    auto BeMicroHard = MultilibBuilder("/micromips-r6-hard")1331                           .flag("-EB")1332                           .flag("-msoft-float", /*Disallow=*/true)1333                           .flag("-mmicromips");1334    auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft")1335                           .flag("-EB")1336                           .flag("-msoft-float")1337                           .flag("-mmicromips");1338    auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard")1339                           .flag("-EL")1340                           .flag("-msoft-float", /*Disallow=*/true)1341                           .flag("-mmicromips");1342    auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft")1343                           .flag("-EL")1344                           .flag("-msoft-float")1345                           .flag("-mmicromips");1346 1347    auto O32 = MultilibBuilder("/lib")1348                   .osSuffix("")1349                   .flag("-mabi=n32", /*Disallow=*/true)1350                   .flag("-mabi=n64", /*Disallow=*/true);1351    auto N32 = MultilibBuilder("/lib32")1352                   .osSuffix("")1353                   .flag("-mabi=n32")1354                   .flag("-mabi=n64", /*Disallow=*/true);1355    auto N64 = MultilibBuilder("/lib64")1356                   .osSuffix("")1357                   .flag("-mabi=n32", /*Disallow=*/true)1358                   .flag("-mabi=n64");1359 1360    ImgMultilibsV2 =1361        MultilibSetBuilder()1362            .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,1363                     ElMicroHard, ElMicroSoft})1364            .Either(O32, N32, N64)1365            .makeMultilibSet()1366            .FilterOut(NonExistent)1367            .setIncludeDirsCallback([](const Multilib &M) {1368              return std::vector<std::string>({"/../../../../sysroot" +1369                                               M.includeSuffix() +1370                                               "/../usr/include"});1371            })1372            .setFilePathsCallback([](const Multilib &M) {1373              return std::vector<std::string>(1374                  {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});1375            });1376  }1377  for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {1378    if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {1379      Result.Multilibs = *Candidate;1380      return true;1381    }1382  }1383  return false;1384}1385 1386bool clang::driver::findMIPSMultilibs(const Driver &D,1387                                      const llvm::Triple &TargetTriple,1388                                      StringRef Path, const ArgList &Args,1389                                      DetectedMultilibs &Result) {1390  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1391 1392  StringRef CPUName;1393  StringRef ABIName;1394  tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);1395 1396  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();1397 1398  Multilib::flags_list Flags;1399  addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags);1400  addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags);1401  addMultilibFlag(isMips16(Args), "-mips16", Flags);1402  addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags);1403  addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||1404                      CPUName == "mips32r5" || CPUName == "p5600",1405                  "-march=mips32r2", Flags);1406  addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags);1407  addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags);1408  addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||1409                      CPUName == "mips64r5" || CPUName == "octeon" ||1410                      CPUName == "octeon+",1411                  "-march=mips64r2", Flags);1412  addMultilibFlag(CPUName == "mips64r6" || CPUName == "i6400" ||1413                      CPUName == "i6500",1414                  "-march=mips64r6", Flags);1415  addMultilibFlag(isMicroMips(Args), "-mmicromips", Flags);1416  addMultilibFlag(tools::mips::isUCLibc(Args), "-muclibc", Flags);1417  addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "-mnan=2008",1418                  Flags);1419  addMultilibFlag(ABIName == "n32", "-mabi=n32", Flags);1420  addMultilibFlag(ABIName == "n64", "-mabi=n64", Flags);1421  addMultilibFlag(isSoftFloatABI(Args), "-msoft-float", Flags);1422  addMultilibFlag(!isSoftFloatABI(Args), "-mhard-float", Flags);1423  addMultilibFlag(isMipsEL(TargetArch), "-EL", Flags);1424  addMultilibFlag(!isMipsEL(TargetArch), "-EB", Flags);1425 1426  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&1427      TargetTriple.getOS() == llvm::Triple::Linux &&1428      TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)1429    return findMipsMuslMultilibs(D, Flags, NonExistent, Result);1430 1431  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&1432      TargetTriple.getOS() == llvm::Triple::Linux &&1433      TargetTriple.isGNUEnvironment())1434    return findMipsMtiMultilibs(D, Flags, NonExistent, Result);1435 1436  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&1437      TargetTriple.getOS() == llvm::Triple::Linux &&1438      TargetTriple.isGNUEnvironment())1439    return findMipsImgMultilibs(D, Flags, NonExistent, Result);1440 1441  if (findMipsCsMultilibs(D, Flags, NonExistent, Result))1442    return true;1443 1444  // Fallback to the regular toolchain-tree structure.1445  Multilib Default;1446  Result.Multilibs.push_back(Default);1447  Result.Multilibs.FilterOut(NonExistent);1448 1449  if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs)) {1450    Result.BiarchSibling = Multilib();1451    return true;1452  }1453 1454  return false;1455}1456 1457static void findAndroidArmMultilibs(const Driver &D,1458                                    const llvm::Triple &TargetTriple,1459                                    StringRef Path, const ArgList &Args,1460                                    DetectedMultilibs &Result) {1461  // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.1462  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1463  MultilibBuilder ArmV7Multilib = MultilibBuilder("/armv7-a")1464                                      .flag("-march=armv7-a")1465                                      .flag("-mthumb", /*Disallow=*/true);1466  MultilibBuilder ThumbMultilib = MultilibBuilder("/thumb")1467                                      .flag("-march=armv7-a", /*Disallow=*/true)1468                                      .flag("-mthumb");1469  MultilibBuilder ArmV7ThumbMultilib =1470      MultilibBuilder("/armv7-a/thumb").flag("-march=armv7-a").flag("-mthumb");1471  MultilibBuilder DefaultMultilib =1472      MultilibBuilder("")1473          .flag("-march=armv7-a", /*Disallow=*/true)1474          .flag("-mthumb", /*Disallow=*/true);1475  MultilibSet AndroidArmMultilibs =1476      MultilibSetBuilder()1477          .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib,1478                  DefaultMultilib)1479          .makeMultilibSet()1480          .FilterOut(NonExistent);1481 1482  Multilib::flags_list Flags;1483  llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);1484  bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;1485  bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;1486  bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;1487  bool IsThumbMode = IsThumbArch ||1488      Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||1489      (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB);1490  bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&1491      (llvm::ARM::parseArchVersion(Arch) == 7 ||1492       (IsArmArch && Arch == "" && IsV7SubArch));1493  addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);1494  addMultilibFlag(IsThumbMode, "-mthumb", Flags);1495 1496  if (AndroidArmMultilibs.select(D, Flags, Result.SelectedMultilibs))1497    Result.Multilibs = AndroidArmMultilibs;1498}1499 1500static bool findMSP430Multilibs(const Driver &D,1501                                const llvm::Triple &TargetTriple,1502                                StringRef Path, const ArgList &Args,1503                                DetectedMultilibs &Result) {1504  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1505  MultilibBuilder WithoutExceptions =1506      MultilibBuilder("/430").flag("-exceptions", /*Disallow=*/true);1507  MultilibBuilder WithExceptions =1508      MultilibBuilder("/430/exceptions").flag("-exceptions");1509 1510  // FIXME: when clang starts to support msp430x ISA additional logic1511  // to select between multilib must be implemented1512  // MultilibBuilder MSP430xMultilib = MultilibBuilder("/large");1513 1514  Result.Multilibs.push_back(WithoutExceptions.makeMultilib());1515  Result.Multilibs.push_back(WithExceptions.makeMultilib());1516  Result.Multilibs.FilterOut(NonExistent);1517 1518  Multilib::flags_list Flags;1519  addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,1520                               options::OPT_fno_exceptions, false),1521                  "-exceptions", Flags);1522  if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))1523    return true;1524 1525  return false;1526}1527 1528static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,1529                              StringRef Path, const ArgList &Args,1530                              DetectedMultilibs &Result) {1531  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1532 1533  tools::csky::FloatABI TheFloatABI = tools::csky::getCSKYFloatABI(D, Args);1534  std::optional<llvm::StringRef> Res =1535      tools::csky::getCSKYArchName(D, Args, TargetTriple);1536 1537  if (!Res)1538    return;1539  auto ARCHName = *Res;1540 1541  Multilib::flags_list Flags;1542  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "-hard-fp",1543                  Flags);1544  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "-soft-fp",1545                  Flags);1546  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "-soft", Flags);1547  addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags);1548  addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags);1549  addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags);1550  addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags);1551  addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags);1552  addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags);1553  addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags);1554  addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags);1555  addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags);1556  addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags);1557 1558  bool isBigEndian = false;1559  if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,1560                               options::OPT_mbig_endian))1561    isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);1562  addMultilibFlag(isBigEndian, "-EB", Flags);1563 1564  auto HardFloat = MultilibBuilder("/hard-fp").flag("-hard-fp");1565  auto SoftFpFloat = MultilibBuilder("/soft-fp").flag("-soft-fp");1566  auto SoftFloat = MultilibBuilder("").flag("-soft");1567  auto Arch801 = MultilibBuilder("/ck801").flag("-march=ck801");1568  auto Arch802 = MultilibBuilder("/ck802").flag("-march=ck802");1569  auto Arch803 = MultilibBuilder("/ck803").flag("-march=ck803");1570  // CK804 use the same library as CK8031571  auto Arch804 = MultilibBuilder("/ck803").flag("-march=ck804");1572  auto Arch805 = MultilibBuilder("/ck805").flag("-march=ck805");1573  auto Arch807 = MultilibBuilder("/ck807").flag("-march=ck807");1574  auto Arch810 = MultilibBuilder("").flag("-march=ck810");1575  auto Arch810v = MultilibBuilder("/ck810v").flag("-march=ck810v");1576  auto Arch860 = MultilibBuilder("/ck860").flag("-march=ck860");1577  auto Arch860v = MultilibBuilder("/ck860v").flag("-march=ck860v");1578  auto BigEndian = MultilibBuilder("/big").flag("-EB");1579 1580  MultilibSet CSKYMultilibs =1581      MultilibSetBuilder()1582          .Maybe(BigEndian)1583          .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807,1584                   Arch810, Arch810v, Arch860, Arch860v})1585          .Either(HardFloat, SoftFpFloat, SoftFloat)1586          .makeMultilibSet()1587          .FilterOut(NonExistent);1588 1589  if (CSKYMultilibs.select(D, Flags, Result.SelectedMultilibs))1590    Result.Multilibs = CSKYMultilibs;1591}1592 1593/// Extend the multi-lib re-use selection mechanism for RISC-V.1594/// This function will try to re-use multi-lib if they are compatible.1595/// Definition of compatible:1596///   - ABI must be the same.1597///   - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im1598///     is a subset of march=rv32imc.1599///   - march that contains atomic extension can't reuse multi-lib that1600///     doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and1601///     march=rv32ima are not compatible, because software and hardware1602///     atomic operation can't work together correctly.1603static bool1604selectRISCVMultilib(const Driver &D, const MultilibSet &RISCVMultilibSet,1605                    StringRef Arch, const Multilib::flags_list &Flags,1606                    llvm::SmallVectorImpl<Multilib> &SelectedMultilibs) {1607  // Try to find the perfect matching multi-lib first.1608  if (RISCVMultilibSet.select(D, Flags, SelectedMultilibs))1609    return true;1610 1611  Multilib::flags_list NewFlags;1612  std::vector<MultilibBuilder> NewMultilibs;1613 1614  llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> ParseResult =1615      llvm::RISCVISAInfo::parseArchString(1616          Arch, /*EnableExperimentalExtension=*/true,1617          /*ExperimentalExtensionVersionCheck=*/false);1618  // Ignore any error here, we assume it will be handled in another place.1619  if (llvm::errorToBool(ParseResult.takeError()))1620    return false;1621 1622  auto &ISAInfo = *ParseResult;1623 1624  addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);1625  addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);1626 1627  // Collect all flags except march=*1628  for (StringRef Flag : Flags) {1629    if (Flag.starts_with("!march=") || Flag.starts_with("-march="))1630      continue;1631 1632    NewFlags.push_back(Flag.str());1633  }1634 1635  llvm::StringSet<> AllArchExts;1636  // Reconstruct multi-lib list, and break march option into separated1637  // extension. e.g. march=rv32im -> +i +m1638  for (const auto &M : RISCVMultilibSet) {1639    bool Skip = false;1640 1641    MultilibBuilder NewMultilib =1642        MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());1643    for (StringRef Flag : M.flags()) {1644      // Add back all flags except -march.1645      if (!Flag.consume_front("-march=")) {1646        NewMultilib.flag(Flag);1647        continue;1648      }1649 1650      // Break down -march into individual extension.1651      llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> MLConfigParseResult =1652          llvm::RISCVISAInfo::parseArchString(1653              Flag, /*EnableExperimentalExtension=*/true,1654              /*ExperimentalExtensionVersionCheck=*/false);1655      // Ignore any error here, we assume it will handled in another place.1656      if (llvm::errorToBool(MLConfigParseResult.takeError())) {1657        // We might get a parsing error if rv32e in the list, we could just skip1658        // that and process the rest of multi-lib configs.1659        Skip = true;1660        continue;1661      }1662      auto &MLConfigISAInfo = *MLConfigParseResult;1663 1664      for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) {1665        auto ExtName = MLConfigArchExt.first;1666        NewMultilib.flag(Twine("-", ExtName).str());1667 1668        if (AllArchExts.insert(ExtName).second) {1669          addMultilibFlag(ISAInfo->hasExtension(ExtName),1670                          Twine("-", ExtName).str(), NewFlags);1671        }1672      }1673 1674      // Check the XLEN explicitly.1675      if (MLConfigISAInfo->getXLen() == 32) {1676        NewMultilib.flag("-m32");1677        NewMultilib.flag("-m64", /*Disallow*/ true);1678      } else {1679        NewMultilib.flag("-m32", /*Disallow*/ true);1680        NewMultilib.flag("-m64");1681      }1682 1683      // Atomic extension must be explicitly checked, soft and hard atomic1684      // operation never co-work correctly.1685      if (!MLConfigISAInfo->hasExtension("a"))1686        NewMultilib.flag("-a", /*Disallow*/ true);1687    }1688 1689    if (Skip)1690      continue;1691 1692    NewMultilibs.emplace_back(NewMultilib);1693  }1694 1695  // Build an internal used only multi-lib list, used for checking any1696  // compatible multi-lib.1697  MultilibSet NewRISCVMultilibs =1698      MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet();1699 1700  if (NewRISCVMultilibs.select(D, NewFlags, SelectedMultilibs))1701    for (const Multilib &NewSelectedM : SelectedMultilibs)1702      for (const auto &M : RISCVMultilibSet)1703        // Look up the corresponding multi-lib entry in original multi-lib set.1704        if (M.gccSuffix() == NewSelectedM.gccSuffix())1705          return true;1706 1707  return false;1708}1709 1710static void findRISCVBareMetalMultilibs(const Driver &D,1711                                        const llvm::Triple &TargetTriple,1712                                        StringRef Path, const ArgList &Args,1713                                        DetectedMultilibs &Result) {1714  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1715  struct RiscvMultilib {1716    StringRef march;1717    StringRef mabi;1718  };1719  // currently only support the set of multilibs like riscv-gnu-toolchain does.1720  // TODO: support MULTILIB_REUSE1721  constexpr RiscvMultilib RISCVMultilibSet[] = {1722      {"rv32i", "ilp32"},     {"rv32im", "ilp32"},     {"rv32iac", "ilp32"},1723      {"rv32imac", "ilp32"},  {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},1724      {"rv64imafdc", "lp64d"}};1725 1726  std::vector<MultilibBuilder> Ms;1727  for (auto Element : RISCVMultilibSet) {1728    // multilib path rule is ${march}/${mabi}1729    Ms.emplace_back(1730        MultilibBuilder(1731            (Twine(Element.march) + "/" + Twine(Element.mabi)).str())1732            .flag(Twine("-march=", Element.march).str())1733            .flag(Twine("-mabi=", Element.mabi).str()));1734  }1735  MultilibSet RISCVMultilibs =1736      MultilibSetBuilder()1737          .Either(Ms)1738          .makeMultilibSet()1739          .FilterOut(NonExistent)1740          .setFilePathsCallback([](const Multilib &M) {1741            return std::vector<std::string>(1742                {M.gccSuffix(),1743                 "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),1744                 "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});1745          });1746 1747  Multilib::flags_list Flags;1748  llvm::StringSet<> Added_ABIs;1749  StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);1750  std::string MArch = tools::riscv::getRISCVArch(Args, TargetTriple);1751  for (auto Element : RISCVMultilibSet) {1752    addMultilibFlag(MArch == Element.march,1753                    Twine("-march=", Element.march).str(), Flags);1754    if (!Added_ABIs.count(Element.mabi)) {1755      Added_ABIs.insert(Element.mabi);1756      addMultilibFlag(ABIName == Element.mabi,1757                      Twine("-mabi=", Element.mabi).str(), Flags);1758    }1759  }1760 1761  if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,1762                          Result.SelectedMultilibs))1763    Result.Multilibs = RISCVMultilibs;1764}1765 1766static void findRISCVMultilibs(const Driver &D,1767                               const llvm::Triple &TargetTriple, StringRef Path,1768                               const ArgList &Args, DetectedMultilibs &Result) {1769  if (TargetTriple.getOS() == llvm::Triple::UnknownOS)1770    return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result);1771 1772  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());1773  MultilibBuilder Ilp32 =1774      MultilibBuilder("lib32/ilp32").flag("-m32").flag("-mabi=ilp32");1775  MultilibBuilder Ilp32f =1776      MultilibBuilder("lib32/ilp32f").flag("-m32").flag("-mabi=ilp32f");1777  MultilibBuilder Ilp32d =1778      MultilibBuilder("lib32/ilp32d").flag("-m32").flag("-mabi=ilp32d");1779  MultilibBuilder Lp64 =1780      MultilibBuilder("lib64/lp64").flag("-m64").flag("-mabi=lp64");1781  MultilibBuilder Lp64f =1782      MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f");1783  MultilibBuilder Lp64d =1784      MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d");1785  MultilibSet RISCVMultilibs =1786      MultilibSetBuilder()1787          .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})1788          .makeMultilibSet()1789          .FilterOut(NonExistent);1790 1791  Multilib::flags_list Flags;1792  bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;1793  StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);1794 1795  addMultilibFlag(!IsRV64, "-m32", Flags);1796  addMultilibFlag(IsRV64, "-m64", Flags);1797  addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags);1798  addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags);1799  addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags);1800  addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);1801  addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);1802  addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);1803 1804  if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))1805    Result.Multilibs = RISCVMultilibs;1806}1807 1808static bool findBiarchMultilibs(const Driver &D,1809                                const llvm::Triple &TargetTriple,1810                                StringRef Path, const ArgList &Args,1811                                bool NeedsBiarchSuffix,1812                                DetectedMultilibs &Result) {1813  MultilibBuilder DefaultBuilder;1814 1815  // Some versions of SUSE and Fedora on ppc64 put 32-bit libs1816  // in what would normally be GCCInstallPath and put the 64-bit1817  // libs in a subdirectory named 64. The simple logic we follow is that1818  // *if* there is a subdirectory of the right name with crtbegin.o in it,1819  // we use that. If not, and if not a biarch triple alias, we look for1820  // crtbegin.o without the subdirectory.1821 1822  StringRef Suff64 = "/64";1823  // Solaris uses platform-specific suffixes instead of /64.1824  if (TargetTriple.isOSSolaris()) {1825    switch (TargetTriple.getArch()) {1826    case llvm::Triple::x86:1827    case llvm::Triple::x86_64:1828      Suff64 = "/amd64";1829      break;1830    case llvm::Triple::sparc:1831    case llvm::Triple::sparcv9:1832      Suff64 = "/sparcv9";1833      break;1834    default:1835      break;1836    }1837  }1838 1839  Multilib Alt64 = MultilibBuilder()1840                       .gccSuffix(Suff64)1841                       .includeSuffix(Suff64)1842                       .flag("-m32", /*Disallow=*/true)1843                       .flag("-m64")1844                       .flag("-mx32", /*Disallow=*/true)1845                       .makeMultilib();1846  Multilib Alt32 = MultilibBuilder()1847                       .gccSuffix("/32")1848                       .includeSuffix("/32")1849                       .flag("-m32")1850                       .flag("-m64", /*Disallow=*/true)1851                       .flag("-mx32", /*Disallow=*/true)1852                       .makeMultilib();1853  Multilib Altx32 = MultilibBuilder()1854                        .gccSuffix("/x32")1855                        .includeSuffix("/x32")1856                        .flag("-m32", /*Disallow=*/true)1857                        .flag("-m64", /*Disallow=*/true)1858                        .flag("-mx32")1859                        .makeMultilib();1860  Multilib Alt32sparc = MultilibBuilder()1861                            .gccSuffix("/sparcv8plus")1862                            .includeSuffix("/sparcv8plus")1863                            .flag("-m32")1864                            .flag("-m64", /*Disallow=*/true)1865                            .makeMultilib();1866 1867  // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.1868  FilterNonExistent NonExistent(1869      Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());1870 1871  // Determine default multilib from: 32, 64, x321872  // Also handle cases such as 64 on 32, 32 on 64, etc.1873  enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;1874  const bool IsX32 = TargetTriple.isX32();1875  if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))1876    Want = WANT64;1877  if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc))1878    Want = WANT64;1879  else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))1880    Want = WANT64;1881  else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))1882    Want = WANT32;1883  else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc))1884    Want = WANT64;1885  else {1886    if (TargetTriple.isArch32Bit())1887      Want = NeedsBiarchSuffix ? WANT64 : WANT32;1888    else if (IsX32)1889      Want = NeedsBiarchSuffix ? WANT64 : WANTX32;1890    else1891      Want = NeedsBiarchSuffix ? WANT32 : WANT64;1892  }1893 1894  if (Want == WANT32)1895    DefaultBuilder.flag("-m32")1896        .flag("-m64", /*Disallow=*/true)1897        .flag("-mx32", /*Disallow=*/true);1898  else if (Want == WANT64)1899    DefaultBuilder.flag("-m32", /*Disallow=*/true)1900        .flag("-m64")1901        .flag("-mx32", /*Disallow=*/true);1902  else if (Want == WANTX32)1903    DefaultBuilder.flag("-m32", /*Disallow=*/true)1904        .flag("-m64", /*Disallow=*/true)1905        .flag("-mx32");1906  else1907    return false;1908 1909  Multilib Default = DefaultBuilder.makeMultilib();1910 1911  Result.Multilibs.push_back(Default);1912  Result.Multilibs.push_back(Alt64);1913  Result.Multilibs.push_back(Alt32);1914  Result.Multilibs.push_back(Altx32);1915  Result.Multilibs.push_back(Alt32sparc);1916 1917  Result.Multilibs.FilterOut(NonExistent);1918 1919  Multilib::flags_list Flags;1920  addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "-m64", Flags);1921  addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);1922  addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);1923 1924  if (!Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))1925    return false;1926 1927  if (Result.SelectedMultilibs.back() == Alt64 ||1928      Result.SelectedMultilibs.back() == Alt32 ||1929      Result.SelectedMultilibs.back() == Altx32 ||1930      Result.SelectedMultilibs.back() == Alt32sparc)1931    Result.BiarchSibling = Default;1932 1933  return true;1934}1935 1936/// Generic_GCC - A tool chain using the 'gcc' command to perform1937/// all subcommands; this relies on gcc translating the majority of1938/// command line options.1939 1940/// Less-than for GCCVersion, implementing a Strict Weak Ordering.1941bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,1942                                          int RHSPatch,1943                                          StringRef RHSPatchSuffix) const {1944  if (Major != RHSMajor)1945    return Major < RHSMajor;1946  if (Minor != RHSMinor) {1947    // Note that versions without a specified minor sort higher than those with1948    // a minor.1949    if (RHSMinor == -1)1950      return true;1951    if (Minor == -1)1952      return false;1953    return Minor < RHSMinor;1954  }1955  if (Patch != RHSPatch) {1956    // Note that versions without a specified patch sort higher than those with1957    // a patch.1958    if (RHSPatch == -1)1959      return true;1960    if (Patch == -1)1961      return false;1962 1963    // Otherwise just sort on the patch itself.1964    return Patch < RHSPatch;1965  }1966  if (PatchSuffix != RHSPatchSuffix) {1967    // Sort empty suffixes higher.1968    if (RHSPatchSuffix.empty())1969      return true;1970    if (PatchSuffix.empty())1971      return false;1972 1973    // Provide a lexicographic sort to make this a total ordering.1974    return PatchSuffix < RHSPatchSuffix;1975  }1976 1977  // The versions are equal.1978  return false;1979}1980 1981/// Parse a GCCVersion object out of a string of text.1982///1983/// This is the primary means of forming GCCVersion objects.1984/*static*/1985Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) {1986  const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};1987  std::pair<StringRef, StringRef> First = VersionText.split('.');1988  std::pair<StringRef, StringRef> Second = First.second.split('.');1989 1990  StringRef MajorStr = First.first;1991  StringRef MinorStr = Second.first;1992  StringRef PatchStr = Second.second;1993 1994  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};1995 1996  // Parse version number strings such as:1997  //   51998  //   4.41999  //   4.4-patched2000  //   4.4.02001  //   4.4.x2002  //   4.4.2-rc42003  //   4.4.x-patched2004  //   10-win322005  // Split on '.', handle 1, 2 or 3 such segments. Each segment must contain2006  // purely a number, except for the last one, where a non-number suffix2007  // is stored in PatchSuffix. The third segment is allowed to not contain2008  // a number at all.2009 2010  auto TryParseLastNumber = [&](StringRef Segment, int &Number,2011                                std::string &OutStr) -> bool {2012    // Look for a number prefix and parse that, and split out any trailing2013    // string into GoodVersion.PatchSuffix.2014 2015    if (size_t EndNumber = Segment.find_first_not_of("0123456789")) {2016      StringRef NumberStr = Segment.slice(0, EndNumber);2017      if (NumberStr.getAsInteger(10, Number) || Number < 0)2018        return false;2019      OutStr = NumberStr;2020      GoodVersion.PatchSuffix = Segment.substr(EndNumber);2021      return true;2022    }2023    return false;2024  };2025  auto TryParseNumber = [](StringRef Segment, int &Number) -> bool {2026    if (Segment.getAsInteger(10, Number) || Number < 0)2027      return false;2028    return true;2029  };2030 2031  if (MinorStr.empty()) {2032    // If no minor string, major is the last segment2033    if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr))2034      return BadVersion;2035    return GoodVersion;2036  }2037 2038  if (!TryParseNumber(MajorStr, GoodVersion.Major))2039    return BadVersion;2040  GoodVersion.MajorStr = MajorStr;2041 2042  if (PatchStr.empty()) {2043    // If no patch string, minor is the last segment2044    if (!TryParseLastNumber(MinorStr, GoodVersion.Minor, GoodVersion.MinorStr))2045      return BadVersion;2046    return GoodVersion;2047  }2048 2049  if (!TryParseNumber(MinorStr, GoodVersion.Minor))2050    return BadVersion;2051  GoodVersion.MinorStr = MinorStr;2052 2053  // For the last segment, tolerate a missing number.2054  std::string DummyStr;2055  TryParseLastNumber(PatchStr, GoodVersion.Patch, DummyStr);2056  return GoodVersion;2057}2058 2059static llvm::StringRef getGCCToolchainDir(const ArgList &Args,2060                                          llvm::StringRef SysRoot) {2061  const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);2062  if (A)2063    return A->getValue();2064 2065  // If we have a SysRoot, ignore GCC_INSTALL_PREFIX.2066  // GCC_INSTALL_PREFIX specifies the gcc installation for the default2067  // sysroot and is likely not valid with a different sysroot.2068  if (!SysRoot.empty())2069    return "";2070 2071  return GCC_INSTALL_PREFIX;2072}2073 2074/// Initialize a GCCInstallationDetector from the driver.2075///2076/// This performs all of the autodetection and sets up the various paths.2077/// Once constructed, a GCCInstallationDetector is essentially immutable.2078///2079/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and2080/// should instead pull the target out of the driver. This is currently2081/// necessary because the driver doesn't store the final version of the target2082/// triple.2083void Generic_GCC::GCCInstallationDetector::init(2084    const llvm::Triple &TargetTriple, const ArgList &Args) {2085  llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()2086                                         ? TargetTriple.get64BitArchVariant()2087                                         : TargetTriple.get32BitArchVariant();2088  // The library directories which may contain GCC installations.2089  SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;2090  // The compatible GCC triples for this particular architecture.2091  SmallVector<StringRef, 16> CandidateTripleAliases;2092  SmallVector<StringRef, 16> CandidateBiarchTripleAliases;2093  // Add some triples that we want to check first.2094  CandidateTripleAliases.push_back(TargetTriple.str());2095  std::string TripleNoVendor, BiarchTripleNoVendor;2096  if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) {2097    StringRef OSEnv = TargetTriple.getOSAndEnvironmentName();2098    if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32)2099      OSEnv = "linux-gnu";2100    TripleNoVendor = (TargetTriple.getArchName().str() + '-' + OSEnv).str();2101    CandidateTripleAliases.push_back(TripleNoVendor);2102    if (BiarchVariantTriple.getArch() != llvm::Triple::UnknownArch) {2103      BiarchTripleNoVendor =2104          (BiarchVariantTriple.getArchName().str() + '-' + OSEnv).str();2105      CandidateBiarchTripleAliases.push_back(BiarchTripleNoVendor);2106    }2107  }2108 2109  CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,2110                           CandidateTripleAliases, CandidateBiarchLibDirs,2111                           CandidateBiarchTripleAliases);2112 2113  // If --gcc-install-dir= is specified, skip filesystem detection.2114  if (const Arg *A = Args.getLastArg(options::OPT_gcc_install_dir_EQ);2115      A && A->getValue()[0]) {2116    StringRef InstallDir = A->getValue();2117    if (!ScanGCCForMultilibs(TargetTriple, Args, InstallDir, false)) {2118      D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir;2119    } else {2120      (void)InstallDir.consume_back("/");2121      StringRef VersionText = llvm::sys::path::filename(InstallDir);2122      StringRef TripleText =2123          llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir));2124 2125      SelectedInstallation.Version = GCCVersion::Parse(VersionText);2126      SelectedInstallation.GCCTriple.setTriple(TripleText);2127      SelectedInstallation.GCCInstallPath = std::string(InstallDir);2128      SelectedInstallation.GCCParentLibPath =2129          SelectedInstallation.GCCInstallPath + "/../../..";2130      IsValid = true;2131    }2132    return;2133  }2134 2135  // If --gcc-triple is specified use this instead of trying to2136  // auto-detect a triple.2137  if (const Arg *A = Args.getLastArg(options::OPT_gcc_triple_EQ)) {2138    StringRef GCCTriple = A->getValue();2139    CandidateTripleAliases.clear();2140    CandidateTripleAliases.push_back(GCCTriple);2141  }2142 2143  // Compute the set of prefixes for our search.2144  SmallVector<std::string, 8> Prefixes;2145  StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot);2146  if (GCCToolchainDir != "") {2147    if (GCCToolchainDir.back() == '/')2148      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /2149 2150    Prefixes.push_back(std::string(GCCToolchainDir));2151  } else {2152    // If we have a SysRoot, try that first.2153    if (!D.SysRoot.empty()) {2154      Prefixes.push_back(D.SysRoot);2155      AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);2156    }2157 2158    // Then look for gcc installed alongside clang.2159    Prefixes.push_back(D.Dir + "/..");2160 2161    // Next, look for prefix(es) that correspond to distribution-supplied gcc2162    // installations.2163    if (D.SysRoot.empty()) {2164      // Typically /usr.2165      AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);2166    }2167 2168    // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided.2169    // This avoids accidentally enforcing the system GCC version when using a2170    // custom toolchain.2171    SmallVector<StringRef, 16> GentooTestTriples;2172    // Try to match an exact triple as target triple first.2173    // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for2174    // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu"2175    // may pick the libraries for x86_64-pc-linux-gnu even when exact matching2176    // triple x86_64-gentoo-linux-gnu is present.2177    GentooTestTriples.push_back(TargetTriple.str());2178    GentooTestTriples.append(CandidateTripleAliases.begin(),2179                             CandidateTripleAliases.end());2180    if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples,2181                          CandidateBiarchTripleAliases))2182      return;2183  }2184 2185  // Loop over the various components which exist and select the best GCC2186  // installation available. GCC installs are ranked by version number.2187  const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");2188  SelectedInstallation.Version = VersionZero;2189  for (const std::string &Prefix : Prefixes) {2190    auto &VFS = D.getVFS();2191    if (!VFS.exists(Prefix))2192      continue;2193    for (StringRef Suffix : CandidateLibDirs) {2194      const std::string LibDir = concat(Prefix, Suffix);2195      if (!VFS.exists(LibDir))2196        continue;2197      // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross.2198      bool GCCDirExists = VFS.exists(LibDir + "/gcc");2199      bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");2200      for (StringRef Candidate : CandidateTripleAliases)2201        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,2202                               GCCDirExists, GCCCrossDirExists);2203    }2204    for (StringRef Suffix : CandidateBiarchLibDirs) {2205      const std::string LibDir = Prefix + Suffix.str();2206      if (!VFS.exists(LibDir))2207        continue;2208      bool GCCDirExists = VFS.exists(LibDir + "/gcc");2209      bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");2210      for (StringRef Candidate : CandidateBiarchTripleAliases)2211        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true,2212                               GCCDirExists, GCCCrossDirExists);2213    }2214 2215    // Skip other prefixes once a GCC installation is found.2216    if (SelectedInstallation.Version > VersionZero)2217      break;2218  }2219}2220 2221void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {2222  for (const auto &InstallPath : CandidateGCCInstallPaths)2223    OS << "Found candidate GCC installation: " << InstallPath << "\n";2224 2225  if (!SelectedInstallation.GCCInstallPath.empty())2226    OS << "Selected GCC installation: " << SelectedInstallation.GCCInstallPath2227       << "\n";2228 2229  for (const auto &Multilib : Multilibs)2230    OS << "Candidate multilib: " << Multilib << "\n";2231 2232  if (Multilibs.size() != 0 ||2233      !SelectedInstallation.SelectedMultilib.isDefault())2234    OS << "Selected multilib: " << SelectedInstallation.SelectedMultilib2235       << "\n";2236}2237 2238bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {2239  if (BiarchSibling) {2240    M = *BiarchSibling;2241    return true;2242  }2243  return false;2244}2245 2246void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(2247    const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes,2248    StringRef SysRoot) {2249 2250  if (TargetTriple.isOSHaiku()) {2251    Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools"));2252    return;2253  }2254 2255  if (TargetTriple.isOSSolaris()) {2256    // Solaris is a special case.2257    // The GCC installation is under2258    //   /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/2259    // so we need to find those /usr/gcc/*/lib/gcc libdirs and go with2260    // /usr/gcc/<version> as a prefix.2261 2262    SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes;2263    std::string PrefixDir = concat(SysRoot, "/usr/gcc");2264    std::error_code EC;2265    for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),2266                                       LE;2267         !EC && LI != LE; LI = LI.increment(EC)) {2268      StringRef VersionText = llvm::sys::path::filename(LI->path());2269      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);2270 2271      // Filter out obviously bad entries.2272      if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1))2273        continue;2274 2275      std::string CandidatePrefix = PrefixDir + "/" + VersionText.str();2276      std::string CandidateLibPath = CandidatePrefix + "/lib/gcc";2277      if (!D.getVFS().exists(CandidateLibPath))2278        continue;2279 2280      SolarisPrefixes.emplace_back(2281          std::make_pair(CandidateVersion, CandidatePrefix));2282    }2283    // Sort in reverse order so GCCInstallationDetector::init picks the latest.2284    std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend());2285    for (auto p : SolarisPrefixes)2286      Prefixes.emplace_back(p.second);2287    return;2288  }2289 2290  // For Linux, if --sysroot is not specified, look for RHEL/CentOS devtoolsets2291  // and gcc-toolsets.2292  if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&2293      D.getVFS().exists("/opt/rh")) {2294    // TODO: We may want to remove this, since the functionality2295    //   can be achieved using config files.2296    Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr");2297    Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");2298    Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");2299    Prefixes.push_back("/opt/rh/devtoolset-12/root/usr");2300    Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");2301    Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");2302    Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");2303    Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");2304    Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");2305    Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");2306    Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");2307    Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");2308    Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");2309  }2310 2311  // Fall back to /usr which is used by most non-Solaris systems.2312  Prefixes.push_back(concat(SysRoot, "/usr"));2313}2314 2315/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(2316    const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,2317    SmallVectorImpl<StringRef> &LibDirs,2318    SmallVectorImpl<StringRef> &TripleAliases,2319    SmallVectorImpl<StringRef> &BiarchLibDirs,2320    SmallVectorImpl<StringRef> &BiarchTripleAliases) {2321  // Declare a bunch of static data sets that we'll select between below. These2322  // are specifically designed to always refer to string literals to avoid any2323  // lifetime or initialization issues.2324  //2325  // The *Triples variables hard code some triples so that, for example,2326  // --target=aarch64 (incomplete triple) can detect lib/aarch64-linux-gnu.2327  // They are not needed when the user has correct LLVM_DEFAULT_TARGET_TRIPLE2328  // and always uses the full --target (e.g. --target=aarch64-linux-gnu).  The2329  // lists should shrink over time. Please don't add more elements to *Triples.2330  static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};2331  static const char *const AArch64Triples[] = {2332      "aarch64-none-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux"};2333  static const char *const AArch64beLibDirs[] = {"/lib"};2334  static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu"};2335 2336  static const char *const ARMLibDirs[] = {"/lib"};2337  static const char *const ARMTriples[] = {"arm-linux-gnueabi"};2338  static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",2339                                             "armv7hl-redhat-linux-gnueabi",2340                                             "armv6hl-suse-linux-gnueabi",2341                                             "armv7hl-suse-linux-gnueabi"};2342  static const char *const ARMebLibDirs[] = {"/lib"};2343  static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"};2344  static const char *const ARMebHFTriples[] = {2345      "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};2346 2347  static const char *const AVRLibDirs[] = {"/lib"};2348  static const char *const AVRTriples[] = {"avr"};2349 2350  static const char *const CSKYLibDirs[] = {"/lib"};2351  static const char *const CSKYTriples[] = {2352      "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"};2353 2354  static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};2355  static const char *const X86_64Triples[] = {2356      "x86_64-linux-gnu",       "x86_64-unknown-linux-gnu",2357      "x86_64-pc-linux-gnu",    "x86_64-redhat-linux6E",2358      "x86_64-redhat-linux",    "x86_64-suse-linux",2359      "x86_64-manbo-linux-gnu", "x86_64-slackware-linux",2360      "x86_64-unknown-linux",   "x86_64-amazon-linux"};2361  static const char *const X32Triples[] = {"x86_64-linux-gnux32",2362                                           "x86_64-pc-linux-gnux32"};2363  static const char *const X32LibDirs[] = {"/libx32", "/lib"};2364  static const char *const X86LibDirs[] = {"/lib32", "/lib"};2365  static const char *const X86Triples[] = {2366      "i586-linux-gnu",      "i686-linux-gnu",        "i686-pc-linux-gnu",2367      "i386-redhat-linux6E", "i686-redhat-linux",     "i386-redhat-linux",2368      "i586-suse-linux",     "i686-montavista-linux",2369  };2370 2371  static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"};2372  static const char *const LoongArch64Triples[] = {2373      "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"};2374 2375  static const char *const M68kLibDirs[] = {"/lib"};2376  static const char *const M68kTriples[] = {"m68k-unknown-linux-gnu",2377                                            "m68k-suse-linux"};2378 2379  static const char *const MIPSLibDirs[] = {"/libo32", "/lib"};2380  static const char *const MIPSTriples[] = {2381      "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu",2382      "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"};2383  static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"};2384  static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",2385                                              "mips-img-linux-gnu"};2386 2387  static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};2388  static const char *const MIPS64Triples[] = {2389      "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64-linux-gnuabi64",2390      "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"};2391  static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};2392  static const char *const MIPS64ELTriples[] = {2393      "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64el-linux-gnuabi64",2394      "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"};2395 2396  static const char *const MIPSN32LibDirs[] = {"/lib32"};2397  static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32",2398                                               "mipsisa64r6-linux-gnuabin32"};2399  static const char *const MIPSN32ELLibDirs[] = {"/lib32"};2400  static const char *const MIPSN32ELTriples[] = {2401      "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};2402 2403  static const char *const MSP430LibDirs[] = {"/lib"};2404  static const char *const MSP430Triples[] = {"msp430-elf"};2405 2406  static const char *const PPCLibDirs[] = {"/lib32", "/lib"};2407  static const char *const PPCTriples[] = {2408      "powerpc-unknown-linux-gnu",2409      // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a2410      // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".2411      "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};2412  static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};2413  static const char *const PPCLETriples[] = {"powerpcle-unknown-linux-gnu",2414                                             "powerpcle-linux-musl"};2415 2416  static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};2417  static const char *const PPC64Triples[] = {"powerpc64-unknown-linux-gnu",2418                                             "powerpc64-suse-linux",2419                                             "ppc64-redhat-linux"};2420  static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};2421  static const char *const PPC64LETriples[] = {2422      "powerpc64le-unknown-linux-gnu", "powerpc64le-none-linux-gnu",2423      "powerpc64le-suse-linux", "ppc64le-redhat-linux"};2424 2425  static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};2426  static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",2427                                               "riscv32-unknown-elf"};2428  static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};2429  static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",2430                                               "riscv64-unknown-elf"};2431 2432  static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};2433  static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",2434                                               "sparcv8-linux-gnu"};2435  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};2436  static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",2437                                               "sparcv9-linux-gnu"};2438 2439  static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};2440  static const char *const SystemZTriples[] = {2441      "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", "s390x-suse-linux",2442      "s390x-redhat-linux"};2443 2444  using std::begin;2445  using std::end;2446 2447  if (TargetTriple.isOSSolaris()) {2448    static const char *const SolarisLibDirs[] = {"/lib"};2449    static const char *const SolarisSparcV8Triples[] = {2450        "sparc-sun-solaris2.11"};2451    static const char *const SolarisSparcV9Triples[] = {2452        "sparcv9-sun-solaris2.11"};2453    static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"};2454    static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"};2455    LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));2456    BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));2457    switch (TargetTriple.getArch()) {2458    case llvm::Triple::x86:2459      TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples));2460      BiarchTripleAliases.append(begin(SolarisX86_64Triples),2461                                 end(SolarisX86_64Triples));2462      break;2463    case llvm::Triple::x86_64:2464      TripleAliases.append(begin(SolarisX86_64Triples),2465                           end(SolarisX86_64Triples));2466      BiarchTripleAliases.append(begin(SolarisX86Triples),2467                                 end(SolarisX86Triples));2468      break;2469    case llvm::Triple::sparc:2470      TripleAliases.append(begin(SolarisSparcV8Triples),2471                           end(SolarisSparcV8Triples));2472      BiarchTripleAliases.append(begin(SolarisSparcV9Triples),2473                                 end(SolarisSparcV9Triples));2474      break;2475    case llvm::Triple::sparcv9:2476      TripleAliases.append(begin(SolarisSparcV9Triples),2477                           end(SolarisSparcV9Triples));2478      BiarchTripleAliases.append(begin(SolarisSparcV8Triples),2479                                 end(SolarisSparcV8Triples));2480      break;2481    default:2482      break;2483    }2484    return;2485  }2486 2487  // Android targets should not use GNU/Linux tools or libraries.2488  if (TargetTriple.isAndroid()) {2489    static const char *const AArch64AndroidTriples[] = {2490        "aarch64-linux-android"};2491    static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"};2492    static const char *const X86AndroidTriples[] = {"i686-linux-android"};2493    static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"};2494 2495    switch (TargetTriple.getArch()) {2496    case llvm::Triple::aarch64:2497      LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));2498      TripleAliases.append(begin(AArch64AndroidTriples),2499                           end(AArch64AndroidTriples));2500      break;2501    case llvm::Triple::arm:2502    case llvm::Triple::thumb:2503      LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));2504      TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples));2505      break;2506    case llvm::Triple::x86_64:2507      LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2508      TripleAliases.append(begin(X86_64AndroidTriples),2509                           end(X86_64AndroidTriples));2510      BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));2511      BiarchTripleAliases.append(begin(X86AndroidTriples),2512                                 end(X86AndroidTriples));2513      break;2514    case llvm::Triple::x86:2515      LibDirs.append(begin(X86LibDirs), end(X86LibDirs));2516      TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples));2517      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2518      BiarchTripleAliases.append(begin(X86_64AndroidTriples),2519                                 end(X86_64AndroidTriples));2520      break;2521    default:2522      break;2523    }2524 2525    return;2526  }2527 2528  if (TargetTriple.isOSHurd()) {2529    switch (TargetTriple.getArch()) {2530    case llvm::Triple::aarch64:2531      LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));2532      TripleAliases.push_back("aarch64-gnu");2533      break;2534    case llvm::Triple::riscv64:2535      LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));2536      TripleAliases.push_back("riscv64-gnu");2537      break;2538    case llvm::Triple::x86_64:2539      LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2540      TripleAliases.push_back("x86_64-gnu");2541      break;2542    case llvm::Triple::x86:2543      LibDirs.append(begin(X86LibDirs), end(X86LibDirs));2544      TripleAliases.push_back("i686-gnu");2545      break;2546    default:2547      break;2548    }2549 2550    return;2551  }2552 2553  if (TargetTriple.isWindowsCygwinEnvironment()) {2554    LibDirs.push_back("/lib");2555    switch (TargetTriple.getArch()) {2556    case llvm::Triple::x86_64:2557      TripleAliases.append({"x86_64-pc-cygwin", "x86_64-pc-msys"});2558      break;2559    case llvm::Triple::x86:2560      TripleAliases.append({"i686-pc-cygwin", "i686-pc-msys"});2561      break;2562    default:2563      break;2564    }2565 2566    return;2567  }2568 2569  switch (TargetTriple.getArch()) {2570  case llvm::Triple::aarch64:2571    LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));2572    TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));2573    BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));2574    BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));2575    break;2576  case llvm::Triple::aarch64_be:2577    LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));2578    TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));2579    BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));2580    BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));2581    break;2582  case llvm::Triple::arm:2583  case llvm::Triple::thumb:2584    LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));2585    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||2586        TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||2587        TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||2588        TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {2589      TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));2590    } else {2591      TripleAliases.append(begin(ARMTriples), end(ARMTriples));2592    }2593    break;2594  case llvm::Triple::armeb:2595  case llvm::Triple::thumbeb:2596    LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));2597    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||2598        TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||2599        TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||2600        TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {2601      TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));2602    } else {2603      TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));2604    }2605    break;2606  case llvm::Triple::avr:2607    LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs));2608    TripleAliases.append(begin(AVRTriples), end(AVRTriples));2609    break;2610  case llvm::Triple::csky:2611    LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs));2612    TripleAliases.append(begin(CSKYTriples), end(CSKYTriples));2613    break;2614  case llvm::Triple::x86_64:2615    if (TargetTriple.isX32()) {2616      LibDirs.append(begin(X32LibDirs), end(X32LibDirs));2617      TripleAliases.append(begin(X32Triples), end(X32Triples));2618      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2619      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));2620    } else {2621      LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2622      TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));2623      BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));2624      BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));2625    }2626    BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));2627    BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));2628    break;2629  case llvm::Triple::x86:2630    LibDirs.append(begin(X86LibDirs), end(X86LibDirs));2631    // MCU toolchain is 32 bit only and its triple alias is TargetTriple2632    // itself, which will be appended below.2633    if (!TargetTriple.isOSIAMCU()) {2634      TripleAliases.append(begin(X86Triples), end(X86Triples));2635      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));2636      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));2637      BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));2638      BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));2639    }2640    break;2641  // TODO: Handle loongarch32.2642  case llvm::Triple::loongarch64:2643    LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs));2644    TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples));2645    break;2646  case llvm::Triple::m68k:2647    LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs));2648    TripleAliases.append(begin(M68kTriples), end(M68kTriples));2649    break;2650  case llvm::Triple::mips:2651    LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));2652    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));2653    BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));2654    BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));2655    BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));2656    BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));2657    break;2658  case llvm::Triple::mipsel:2659    LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));2660    TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));2661    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));2662    BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));2663    BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));2664    BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));2665    BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));2666    break;2667  case llvm::Triple::mips64:2668    LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));2669    TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));2670    BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));2671    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));2672    BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));2673    BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));2674    break;2675  case llvm::Triple::mips64el:2676    LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));2677    TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));2678    BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));2679    BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));2680    BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));2681    BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));2682    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));2683    break;2684  case llvm::Triple::msp430:2685    LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs));2686    TripleAliases.append(begin(MSP430Triples), end(MSP430Triples));2687    break;2688  case llvm::Triple::ppc:2689    LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));2690    TripleAliases.append(begin(PPCTriples), end(PPCTriples));2691    BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));2692    BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));2693    break;2694  case llvm::Triple::ppcle:2695    LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));2696    TripleAliases.append(begin(PPCLETriples), end(PPCLETriples));2697    BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));2698    BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));2699    break;2700  case llvm::Triple::ppc64:2701    LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));2702    TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));2703    BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));2704    BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));2705    break;2706  case llvm::Triple::ppc64le:2707    LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));2708    TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));2709    BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));2710    BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples));2711    break;2712  case llvm::Triple::riscv32:2713    LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));2714    TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));2715    BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));2716    BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));2717    break;2718  case llvm::Triple::riscv64:2719    LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));2720    TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));2721    BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));2722    BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));2723    break;2724  case llvm::Triple::sparc:2725  case llvm::Triple::sparcel:2726    LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));2727    TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));2728    BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));2729    BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));2730    break;2731  case llvm::Triple::sparcv9:2732    LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));2733    TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));2734    BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));2735    BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));2736    break;2737  case llvm::Triple::systemz:2738    LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));2739    TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));2740    break;2741  default:2742    // By default, just rely on the standard lib directories and the original2743    // triple.2744    break;2745  }2746 2747  // Also include the multiarch variant if it's different.2748  if (TargetTriple.str() != BiarchTriple.str())2749    BiarchTripleAliases.push_back(BiarchTriple.str());2750}2751 2752bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(2753    const llvm::Triple &TargetTriple, const ArgList &Args,2754    StringRef Path, bool NeedsBiarchSuffix) {2755  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();2756  DetectedMultilibs Detected;2757 2758  // Android standalone toolchain could have multilibs for ARM and Thumb.2759  // Debian mips multilibs behave more like the rest of the biarch ones,2760  // so handle them there2761  if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {2762    // It should also work without multilibs in a simplified toolchain.2763    findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected);2764  } else if (TargetTriple.isCSKY()) {2765    findCSKYMultilibs(D, TargetTriple, Path, Args, Detected);2766  } else if (TargetTriple.isMIPS()) {2767    if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected))2768      return false;2769  } else if (TargetTriple.isRISCV()) {2770    findRISCVMultilibs(D, TargetTriple, Path, Args, Detected);2771  } else if (isMSP430(TargetArch)) {2772    findMSP430Multilibs(D, TargetTriple, Path, Args, Detected);2773  } else if (TargetArch == llvm::Triple::avr) {2774    // AVR has no multilibs.2775  } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,2776                                  NeedsBiarchSuffix, Detected)) {2777    return false;2778  }2779 2780  Multilibs = Detected.Multilibs;2781  SelectedInstallation.SelectedMultilib =2782      Detected.SelectedMultilibs.empty() ? Multilib()2783                                         : Detected.SelectedMultilibs.back();2784  BiarchSibling = Detected.BiarchSibling;2785 2786  return true;2787}2788 2789bool Generic_GCC::GCCInstallationDetector::SelectGCCInstallationDirectory(2790    const SmallVector<Generic_GCC::GCCInstallCandidate, 3> &Installations,2791    const ArgList &Args,2792    Generic_GCC::GCCInstallCandidate &SelectedInstallation) const {2793  if (Installations.empty())2794    return false;2795 2796  SelectedInstallation =2797      *max_element(Installations, [](const auto &Max, const auto &I) {2798        return I.Version > Max.Version;2799      });2800 2801  // FIXME Start selecting installation with libstdc++ in clang 22,2802  // using the current way of selecting the installation as a fallback2803  // only.  For now, warn if the installation with libstdc++ differs2804  // from SelectedInstallation.2805  const GCCInstallCandidate *InstallWithIncludes = nullptr;2806  for (const auto &I : Installations) {2807    if ((!InstallWithIncludes || I.Version > InstallWithIncludes->Version) &&2808        GCCInstallationHasLibStdcxxIncludePaths(I, Args))2809      InstallWithIncludes = &I;2810  }2811 2812  if (InstallWithIncludes && SelectedInstallation.GCCInstallPath !=2813                                 InstallWithIncludes->GCCInstallPath)2814    D.Diag(diag::warn_drv_gcc_install_dir_libstdcxx)2815        << InstallWithIncludes->GCCInstallPath2816        << SelectedInstallation.GCCInstallPath;2817 2818  // TODO Warn if SelectedInstallation does not contain libstdc++ includes2819  // although compiler flags indicate that it is required (C++ compilation,2820  // libstdc++ not explicitly disabled).2821 2822  return true;2823}2824 2825void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(2826    const llvm::Triple &TargetTriple, const ArgList &Args,2827    const std::string &LibDir, StringRef CandidateTriple,2828    bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) {2829  // Locations relative to the system lib directory where GCC's triple-specific2830  // directories might reside.2831  struct GCCLibSuffix {2832    // Path from system lib directory to GCC triple-specific directory.2833    std::string LibSuffix;2834    // Path from GCC triple-specific directory back to system lib directory.2835    // This is one '..' component per component in LibSuffix.2836    StringRef ReversePath;2837    // Whether this library suffix is relevant for the triple.2838    bool Active;2839  } Suffixes[] = {2840      // This is the normal place.2841      {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists},2842 2843      // Debian puts cross-compilers in gcc-cross.2844      {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists},2845 2846      // The Freescale PPC SDK has the gcc libraries in2847      // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do2848      // this on Freescale triples, though, since some systems put a *lot* of2849      // files in that location, not just GCC installation data.2850      {CandidateTriple.str(), "..",2851       TargetTriple.getVendor() == llvm::Triple::Freescale ||2852           TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};2853 2854  SmallVector<GCCInstallCandidate, 3> Installations;2855  for (auto &Suffix : Suffixes) {2856    if (!Suffix.Active)2857      continue;2858 2859    StringRef LibSuffix = Suffix.LibSuffix;2860    std::error_code EC;2861    for (llvm::vfs::directory_iterator2862             LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),2863             LE;2864         !EC && LI != LE; LI = LI.increment(EC)) {2865      StringRef VersionText = llvm::sys::path::filename(LI->path());2866      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);2867      if (CandidateVersion.Major != -1) // Filter obviously bad entries.2868        if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second)2869          continue; // Saw this path before; no need to look at it again.2870      if (CandidateVersion.isOlderThan(4, 1, 1))2871        continue;2872      if (CandidateVersion <= SelectedInstallation.Version && IsValid)2873        continue;2874 2875      if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),2876                               NeedsBiarchSuffix))2877        continue;2878 2879      GCCInstallCandidate Installation;2880      Installation.Version = CandidateVersion;2881      Installation.GCCTriple.setTriple(CandidateTriple);2882      // FIXME: We hack together the directory name here instead of2883      // using LI to ensure stable path separators across Windows and2884      // Linux.2885      Installation.GCCInstallPath =2886          (LibDir + "/" + LibSuffix + "/" + VersionText).str();2887      Installation.GCCParentLibPath =2888          (Installation.GCCInstallPath + "/../" + Suffix.ReversePath).str();2889      Installation.SelectedMultilib = getMultilib();2890 2891      Installations.push_back(Installation);2892    }2893  }2894 2895  IsValid |=2896      SelectGCCInstallationDirectory(Installations, Args, SelectedInstallation);2897}2898 2899bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(2900    const llvm::Triple &TargetTriple, const ArgList &Args,2901    const SmallVectorImpl<StringRef> &CandidateTriples,2902    const SmallVectorImpl<StringRef> &CandidateBiarchTriples) {2903  if (!D.getVFS().exists(concat(D.SysRoot, GentooConfigDir)))2904    return false;2905 2906  for (StringRef CandidateTriple : CandidateTriples) {2907    if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))2908      return true;2909  }2910 2911  for (StringRef CandidateTriple : CandidateBiarchTriples) {2912    if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))2913      return true;2914  }2915  return false;2916}2917 2918bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(2919    const llvm::Triple &TargetTriple, const ArgList &Args,2920    StringRef CandidateTriple, bool NeedsBiarchSuffix) {2921  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =2922      D.getVFS().getBufferForFile(concat(D.SysRoot, GentooConfigDir,2923                                         "/config-" + CandidateTriple.str()));2924  if (File) {2925    SmallVector<StringRef, 2> Lines;2926    File.get()->getBuffer().split(Lines, "\n");2927    for (StringRef Line : Lines) {2928      Line = Line.trim();2929      // CURRENT=triple-version2930      if (!Line.consume_front("CURRENT="))2931        continue;2932      // Process the config file pointed to by CURRENT.2933      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile =2934          D.getVFS().getBufferForFile(2935              concat(D.SysRoot, GentooConfigDir, "/" + Line));2936      std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-');2937      // List of paths to scan for libraries.2938      SmallVector<StringRef, 4> GentooScanPaths;2939      // Scan the Config file to find installed GCC libraries path.2940      // Typical content of the GCC config file:2941      // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/2942      // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32"2943      // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man"2944      // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info"2945      // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4"2946      // We are looking for the paths listed in LDPATH=... .2947      if (ConfigFile) {2948        SmallVector<StringRef, 2> ConfigLines;2949        ConfigFile.get()->getBuffer().split(ConfigLines, "\n");2950        for (StringRef ConfLine : ConfigLines) {2951          ConfLine = ConfLine.trim();2952          if (ConfLine.consume_front("LDPATH=")) {2953            // Drop '"' from front and back if present.2954            ConfLine.consume_back("\"");2955            ConfLine.consume_front("\"");2956            // Get all paths sperated by ':'2957            ConfLine.split(GentooScanPaths, ':', -1, /*AllowEmpty*/ false);2958          }2959        }2960      }2961      // Test the path based on the version in /etc/env.d/gcc/config-{tuple}.2962      std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/"2963          + ActiveVersion.second.str();2964      GentooScanPaths.push_back(StringRef(basePath));2965 2966      // Scan all paths for GCC libraries.2967      for (const auto &GentooScanPath : GentooScanPaths) {2968        std::string GentooPath = concat(D.SysRoot, GentooScanPath);2969        if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {2970          if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,2971                                   NeedsBiarchSuffix))2972            continue;2973 2974          SelectedInstallation.Version =2975              GCCVersion::Parse(ActiveVersion.second);2976          SelectedInstallation.GCCInstallPath = GentooPath;2977          SelectedInstallation.GCCParentLibPath =2978              GentooPath + std::string("/../../..");2979          SelectedInstallation.GCCTriple.setTriple(ActiveVersion.first);2980          IsValid = true;2981          return true;2982        }2983      }2984    }2985  }2986 2987  return false;2988}2989 2990Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,2991                         const ArgList &Args)2992    : ToolChain(D, Triple, Args), GCCInstallation(D),2993      CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args),2994      SYCLInstallation(D, Triple, Args) {2995  getProgramPaths().push_back(getDriver().Dir);2996}2997 2998Generic_GCC::~Generic_GCC() {}2999 3000Tool *Generic_GCC::getTool(Action::ActionClass AC) const {3001  switch (AC) {3002  case Action::PreprocessJobClass:3003    if (!Preprocess)3004      Preprocess.reset(new clang::driver::tools::gcc::Preprocessor(*this));3005    return Preprocess.get();3006  case Action::CompileJobClass:3007    if (!Compile)3008      Compile.reset(new tools::gcc::Compiler(*this));3009    return Compile.get();3010  default:3011    return ToolChain::getTool(AC);3012  }3013}3014 3015Tool *Generic_GCC::buildAssembler() const {3016  return new tools::gnutools::Assembler(*this);3017}3018 3019Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }3020 3021void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {3022  // Print the information about how we detected the GCC installation.3023  GCCInstallation.print(OS);3024  CudaInstallation->print(OS);3025  RocmInstallation->print(OS);3026}3027 3028ToolChain::UnwindTableLevel3029Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const {3030  switch (getArch()) {3031  case llvm::Triple::aarch64:3032  case llvm::Triple::aarch64_be:3033  case llvm::Triple::ppc:3034  case llvm::Triple::ppcle:3035  case llvm::Triple::ppc64:3036  case llvm::Triple::ppc64le:3037  case llvm::Triple::riscv32:3038  case llvm::Triple::riscv64:3039  case llvm::Triple::x86:3040  case llvm::Triple::x86_64:3041    return UnwindTableLevel::Asynchronous;3042  default:3043    return UnwindTableLevel::None;3044  }3045}3046 3047bool Generic_GCC::isPICDefault() const {3048  switch (getArch()) {3049  case llvm::Triple::x86_64:3050    return getTriple().isOSWindows();3051  case llvm::Triple::mips64:3052  case llvm::Triple::mips64el:3053    return true;3054  default:3055    return false;3056  }3057}3058 3059bool Generic_GCC::isPIEDefault(const llvm::opt::ArgList &Args) const {3060  return false;3061}3062 3063bool Generic_GCC::isPICDefaultForced() const {3064  return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();3065}3066 3067bool Generic_GCC::IsIntegratedAssemblerDefault() const {3068  switch (getTriple().getArch()) {3069  case llvm::Triple::nvptx:3070  case llvm::Triple::nvptx64:3071  case llvm::Triple::xcore:3072    return false;3073  default:3074    return true;3075  }3076}3077 3078void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) {3079  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at3080  // least) put various tools in a triple-prefixed directory off of the parent3081  // of the GCC installation. We use the GCC triple here to ensure that we end3082  // up with tools that support the same amount of cross compiling as the3083  // detected GCC installation. For example, if we find a GCC installation3084  // targeting x86_64, but it is a bi-arch GCC installation, it can also be3085  // used to target i386.3086  if (GCCInstallation.isValid()) {3087    PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +3088                           GCCInstallation.getTriple().str() + "/bin")3089                         .str());3090  }3091}3092 3093void Generic_GCC::AddMultilibPaths(const Driver &D,3094                                   const std::string &SysRoot,3095                                   const std::string &OSLibDir,3096                                   const std::string &MultiarchTriple,3097                                   path_list &Paths) {3098  // Add the multilib suffixed paths where they are available.3099  if (GCCInstallation.isValid()) {3100    assert(!SelectedMultilibs.empty());3101    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();3102    const std::string &LibPath =3103        std::string(GCCInstallation.getParentLibPath());3104 3105    // Sourcery CodeBench MIPS toolchain holds some libraries under3106    // a biarch-like suffix of the GCC installation.3107    if (const auto &PathsCallback = Multilibs.filePathsCallback())3108      for (const auto &Path : PathsCallback(SelectedMultilibs.back()))3109        addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths);3110 3111    // Add lib/gcc/$triple/$version, with an optional /multilib suffix.3112    addPathIfExists(D,3113                    GCCInstallation.getInstallPath() +3114                        SelectedMultilibs.back().gccSuffix(),3115                    Paths);3116 3117    // Add lib/gcc/$triple/$libdir3118    // For GCC built with --enable-version-specific-runtime-libs.3119    addPathIfExists(D, GCCInstallation.getInstallPath() + "/../" + OSLibDir,3120                    Paths);3121 3122    // GCC cross compiling toolchains will install target libraries which ship3123    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as3124    // any part of the GCC installation in3125    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat3126    // debatable, but is the reality today. We need to search this tree even3127    // when we have a sysroot somewhere else. It is the responsibility of3128    // whomever is doing the cross build targeting a sysroot using a GCC3129    // installation that is *not* within the system root to ensure two things:3130    //3131    //  1) Any DSOs that are linked in from this tree or from the install path3132    //     above must be present on the system root and found via an3133    //     appropriate rpath.3134    //  2) There must not be libraries installed into3135    //     <prefix>/<triple>/<libdir> unless they should be preferred over3136    //     those within the system root.3137    //3138    // Note that this matches the GCC behavior. See the below comment for where3139    // Clang diverges from GCC's behavior.3140    addPathIfExists(D,3141                    LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +3142                        SelectedMultilibs.back().osSuffix(),3143                    Paths);3144 3145    // If the GCC installation we found is inside of the sysroot, we want to3146    // prefer libraries installed in the parent prefix of the GCC installation.3147    // It is important to *not* use these paths when the GCC installation is3148    // outside of the system root as that can pick up unintended libraries.3149    // This usually happens when there is an external cross compiler on the3150    // host system, and a more minimal sysroot available that is the target of3151    // the cross. Note that GCC does include some of these directories in some3152    // configurations but this seems somewhere between questionable and simply3153    // a bug.3154    if (StringRef(LibPath).starts_with(SysRoot))3155      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);3156  }3157}3158 3159void Generic_GCC::AddMultiarchPaths(const Driver &D,3160                                    const std::string &SysRoot,3161                                    const std::string &OSLibDir,3162                                    path_list &Paths) {3163  if (GCCInstallation.isValid()) {3164    const std::string &LibPath =3165        std::string(GCCInstallation.getParentLibPath());3166    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();3167    const Multilib &Multilib = GCCInstallation.getMultilib();3168    addPathIfExists(3169        D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(),3170                    Paths);3171  }3172}3173 3174void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs,3175                                         ArgStringList &CC1Args) const {3176  // Add include directories specific to the selected multilib set and multilib.3177  if (!GCCInstallation.isValid())3178    return;3179  // gcc TOOL_INCLUDE_DIR.3180  const llvm::Triple &GCCTriple = GCCInstallation.getTriple();3181  std::string LibPath(GCCInstallation.getParentLibPath());3182  ToolChain::addSystemInclude(DriverArgs, CC1Args,3183                              Twine(LibPath) + "/../" + GCCTriple.str() +3184                                  "/include");3185 3186  const auto &Callback = Multilibs.includeDirsCallback();3187  if (Callback) {3188    for (const auto &Path : Callback(GCCInstallation.getMultilib()))3189      addExternCSystemIncludeIfExists(DriverArgs, CC1Args,3190                                      GCCInstallation.getInstallPath() + Path);3191  }3192}3193 3194void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,3195                                               ArgStringList &CC1Args) const {3196  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,3197                        options::OPT_nostdlibinc))3198    return;3199 3200  switch (GetCXXStdlibType(DriverArgs)) {3201  case ToolChain::CST_Libcxx:3202    addLibCxxIncludePaths(DriverArgs, CC1Args);3203    break;3204 3205  case ToolChain::CST_Libstdcxx:3206    addLibStdCxxIncludePaths(DriverArgs, CC1Args);3207    break;3208  }3209}3210 3211void Generic_GCC::addSYCLIncludeArgs(const ArgList &DriverArgs,3212                                     ArgStringList &CC1Args) const {3213  SYCLInstallation->addSYCLIncludeArgs(DriverArgs, CC1Args);3214}3215 3216void3217Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,3218                                   llvm::opt::ArgStringList &CC1Args) const {3219  const Driver &D = getDriver();3220  std::string SysRoot = computeSysRoot();3221  if (SysRoot.empty())3222    SysRoot = llvm::sys::path::get_separator();3223 3224  auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {3225    std::string Version = detectLibcxxVersion(Path);3226    if (Version.empty())3227      return false;3228 3229    // First add the per-target include path if it exists.3230    bool TargetDirExists = false;3231    std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(Path);3232    if (TargetIncludeDir) {3233      SmallString<128> TargetDir(*TargetIncludeDir);3234      llvm::sys::path::append(TargetDir, "c++", Version);3235      if (D.getVFS().exists(TargetDir)) {3236        addSystemInclude(DriverArgs, CC1Args, TargetDir);3237        TargetDirExists = true;3238      }3239    }3240    if (TargetDirRequired && !TargetDirExists)3241      return false;3242 3243    // Second add the generic one.3244    SmallString<128> GenericDir(Path);3245    llvm::sys::path::append(GenericDir, "c++", Version);3246    addSystemInclude(DriverArgs, CC1Args, GenericDir);3247    return true;3248  };3249 3250  // Android only uses the libc++ headers installed alongside the toolchain if3251  // they contain an Android-specific target include path, otherwise they're3252  // incompatible with the NDK libraries.3253  SmallString<128> DriverIncludeDir(getDriver().Dir);3254  llvm::sys::path::append(DriverIncludeDir, "..", "include");3255  if (AddIncludePath(DriverIncludeDir,3256                     /*TargetDirRequired=*/getTriple().isAndroid()))3257    return;3258  // If this is a development, non-installed, clang, libcxx will3259  // not be found at ../include/c++ but it likely to be found at3260  // one of the following two locations:3261  SmallString<128> UsrLocalIncludeDir(SysRoot);3262  llvm::sys::path::append(UsrLocalIncludeDir, "usr", "local", "include");3263  if (AddIncludePath(UsrLocalIncludeDir))3264    return;3265  SmallString<128> UsrIncludeDir(SysRoot);3266  llvm::sys::path::append(UsrIncludeDir, "usr", "include");3267  if (AddIncludePath(UsrIncludeDir))3268    return;3269}3270 3271static bool addLibStdCXXIncludePaths(llvm::vfs::FileSystem &vfs,3272                                     Twine IncludeDir, StringRef Triple,3273                                     Twine IncludeSuffix,3274                                     const llvm::opt::ArgList &DriverArgs,3275                                     llvm::opt::ArgStringList &CC1Args,3276                                     bool DetectDebian = false) {3277 3278  if (!vfs.exists(IncludeDir))3279    return false;3280 3281  // Debian native gcc uses g++-multiarch-incdir.diff which uses3282  // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of3283  // include/c++/10/x86_64-linux-gnu$IncludeSuffix.3284  std::string Dir = IncludeDir.str();3285  StringRef Include =3286      llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir));3287  std::string Path =3288      (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix)3289          .str();3290  if (DetectDebian && !vfs.exists(Path))3291    return false;3292 3293  // GPLUSPLUS_INCLUDE_DIR3294  ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir);3295  // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent3296  // include directory.3297  if (DetectDebian)3298    ToolChain::addSystemInclude(DriverArgs, CC1Args, Path);3299  else if (!Triple.empty())3300    ToolChain::addSystemInclude(DriverArgs, CC1Args,3301                                IncludeDir + "/" + Triple + IncludeSuffix);3302  // GPLUSPLUS_BACKWARD_INCLUDE_DIR3303  ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");3304  return true;3305}3306 3307bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,3308                                           Twine IncludeSuffix,3309                                           const llvm::opt::ArgList &DriverArgs,3310                                           llvm::opt::ArgStringList &CC1Args,3311                                           bool DetectDebian) const {3312  return ::addLibStdCXXIncludePaths(getVFS(), IncludeDir, Triple, IncludeSuffix,3313                                    DriverArgs, CC1Args, DetectDebian);3314}3315 3316bool Generic_GCC::GCCInstallCandidate::addGCCLibStdCxxIncludePaths(3317    llvm::vfs::FileSystem &vfs, const llvm::opt::ArgList &DriverArgs,3318    llvm::opt::ArgStringList &CC1Args, StringRef DebianMultiarch) const {3319 3320  // By default, look for the C++ headers in an include directory adjacent to3321  // the lib directory of the GCC installation. Note that this is expect to be3322  // equivalent to '/usr/include/c++/X.Y' in almost all cases.3323  StringRef LibDir = getParentLibPath();3324  StringRef InstallDir = getInstallPath();3325  StringRef TripleStr = getTriple().str();3326  const Multilib &Multilib = getMultilib();3327  const GCCVersion &Version = getVersion();3328 3329  // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty).3330  if (::addLibStdCXXIncludePaths(3331          vfs,3332          LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,3333          TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args))3334    return true;3335 3336  // Try /gcc/$triple/$version/include/c++/ (gcc --print-multiarch is not3337  // empty). Like above but for GCC built with3338  // --enable-version-specific-runtime-libs.3339  if (::addLibStdCXXIncludePaths(vfs,3340                                 LibDir.str() + "/gcc/" + TripleStr + "/" +3341                                     Version.Text + "/include/c++/",3342                                 TripleStr, Multilib.includeSuffix(),3343                                 DriverArgs, CC1Args))3344    return true;3345 3346  // Detect Debian g++-multiarch-incdir.diff.3347  if (::addLibStdCXXIncludePaths(3348          vfs, LibDir.str() + "/../include/c++/" + Version.Text,3349          DebianMultiarch, Multilib.includeSuffix(), DriverArgs, CC1Args,3350          /*Debian=*/true))3351    return true;3352 3353  // Try /../include/c++/$version (gcc --print-multiarch is empty).3354  if (::addLibStdCXXIncludePaths(3355          vfs, LibDir.str() + "/../include/c++/" + Version.Text, TripleStr,3356          Multilib.includeSuffix(), DriverArgs, CC1Args))3357    return true;3358 3359  // Otherwise, fall back on a bunch of options which don't use multiarch3360  // layouts for simplicity.3361  const std::string LibStdCXXIncludePathCandidates[] = {3362      // Gentoo is weird and places its headers inside the GCC install,3363      // so if the first attempt to find the headers fails, try these patterns.3364      InstallDir.str() + "/include/g++-v" + Version.Text,3365      InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +3366          Version.MinorStr,3367      InstallDir.str() + "/include/g++-v" + Version.MajorStr,3368  };3369 3370  for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {3371    if (::addLibStdCXXIncludePaths(vfs, IncludePath, TripleStr,3372                                   Multilib.includeSuffix(), DriverArgs,3373                                   CC1Args))3374      return true;3375  }3376  return false;3377}3378 3379bool Generic_GCC::GCCInstallationDetector::3380    GCCInstallationHasLibStdcxxIncludePaths(3381        const GCCInstallCandidate &GCCInstallation,3382        const llvm::opt::ArgList &DriverArgs) const {3383  StringRef DebianMultiarch =3384      TripleToDebianMultiarch(GCCInstallation.getTriple());3385 3386  // The following function checks for libstdc++ include paths and3387  // adds them to the provided argument list.  Here we just need the3388  // check.3389  llvm::opt::ArgStringList dummyCC1Args;3390  return GCCInstallation.addGCCLibStdCxxIncludePaths(3391      D.getVFS(), DriverArgs, dummyCC1Args, DebianMultiarch);3392}3393 3394bool Generic_GCC::addGCCLibStdCxxIncludePaths(3395    const llvm::opt::ArgList &DriverArgs,3396    llvm::opt::ArgStringList &CC1Args) const {3397  assert(GCCInstallation.isValid());3398 3399  // Detect Debian g++-multiarch-incdir.diff.3400  StringRef DebianMultiarch =3401      GCCInstallation.TripleToDebianMultiarch(GCCInstallation.getTriple());3402 3403  return GCCInstallation.getSelectedInstallation().addGCCLibStdCxxIncludePaths(3404      getVFS(), DriverArgs, CC1Args, DebianMultiarch);3405}3406 3407void3408Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,3409                                      llvm::opt::ArgStringList &CC1Args) const {3410  if (!GCCInstallation.isValid())3411    return;3412 3413  GCCInstallation.getSelectedInstallation().addGCCLibStdCxxIncludePaths(3414      getVFS(), DriverArgs, CC1Args, GCCInstallation.getTriple().str());3415}3416 3417llvm::opt::DerivedArgList *3418Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args,3419                           StringRef BoundArch,3420                           Action::OffloadKind DeviceOffloadKind) const {3421  if (DeviceOffloadKind != Action::OFK_SYCL &&3422      DeviceOffloadKind != Action::OFK_OpenMP)3423    return nullptr;3424 3425  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());3426 3427  // Filter all the arguments we don't care passing to the offloading3428  // toolchain as they can mess up with the creation of a shared library.3429  const llvm::DenseSet<unsigned> OpenMPFiltered{3430      options::OPT_shared, options::OPT_dynamic, options::OPT_static,3431      options::OPT_fPIE,   options::OPT_fno_PIE, options::OPT_fpie,3432      options::OPT_fno_pie};3433  for (auto *A : Args)3434    if (DeviceOffloadKind != Action::OFK_OpenMP ||3435        !OpenMPFiltered.contains(A->getOption().getID()))3436      DAL->append(A);3437 3438  // Request a shared library for CPU offloading. Given that these options3439  // are decided implicitly, they do not refer to any base argument.3440  const OptTable &Opts = getDriver().getOpts();3441  if (DeviceOffloadKind == Action::OFK_OpenMP) {3442    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared));3443    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC));3444  }3445 3446  // Add the bound architecture to the arguments list if present.3447  if (!BoundArch.empty()) {3448    options::ID Opt =3449        getTriple().isARM() || getTriple().isPPC() || getTriple().isAArch64()3450            ? options::OPT_mcpu_EQ3451            : options::OPT_march_EQ;3452    DAL->eraseArg(Opt);3453    DAL->AddJoinedArg(nullptr, Opts.getOption(Opt), BoundArch);3454  }3455  return DAL;3456}3457 3458void Generic_ELF::anchor() {}3459 3460void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,3461                                        ArgStringList &CC1Args,3462                                        Action::OffloadKind) const {3463  if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,3464                          options::OPT_fno_use_init_array, true))3465    CC1Args.push_back("-fno-use-init-array");3466}3467