clang: lib/Driver/ToolChains/Gnu.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20#include "clang/Config/config.h"

28#include "llvm/ADT/StringSet.h"

29#include "llvm/ADT/Twine.h"

30#include "llvm/Option/ArgList.h"

31#include "llvm/Support/CodeGen.h"

32#include "llvm/Support/Path.h"

33#include "llvm/Support/VirtualFileSystem.h"

34#include "llvm/TargetParser/RISCVISAInfo.h"

35#include "llvm/TargetParser/TargetParser.h"

36#include <system_error>

37

40using namespace clang;

42

45

47

49 return false;

50 return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption);

51}

52

53

54

55

57 ArgStringList &CmdArgs) {

58 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {

59 StringRef CPUArg(A->getValue());

60 if (CPUArg.equals_insensitive("krait"))

61 CmdArgs.push_back("-mcpu=cortex-a15");

62 else if (CPUArg.equals_insensitive("kryo"))

63 CmdArgs.push_back("-mcpu=cortex-a57");

64 else

65 Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);

66 }

67}

68

72 const ArgList &Args,

73 const char *LinkingOutput) const {

75 ArgStringList CmdArgs;

76

77 for (const auto &A : Args) {

79

80

81

82

83 A->claim();

84

85 A->render(Args, CmdArgs);

86 }

87 }

88

90

91

92 if (getToolChain().getTriple().isOSDarwin()) {

93 CmdArgs.push_back("-arch");

94 CmdArgs.push_back(

95 Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));

96 }

97

98

99

100

101

102

104 default:

105 break;

106 case llvm::Triple::x86:

107 case llvm::Triple::ppc:

108 case llvm::Triple::ppcle:

109 CmdArgs.push_back("-m32");

110 break;

111 case llvm::Triple::x86_64:

112 case llvm::Triple::ppc64:

113 case llvm::Triple::ppc64le:

114 CmdArgs.push_back("-m64");

115 break;

116 case llvm::Triple::sparcel:

117 CmdArgs.push_back("-EL");

118 break;

119 }

120

121 assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");

123 CmdArgs.push_back("-o");

125 } else {

126 CmdArgs.push_back("-fsyntax-only");

127 }

128

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

130

131

132

133

134

135

136

137

138

139 for (const auto &II : Inputs) {

140

142 D.Diag(clang::diag::err_drv_no_linker_llvm_support)

144 else if (II.getType() == types::TY_AST)

146 else if (II.getType() == types::TY_ModuleFile)

147 D.Diag(diag::err_drv_no_module_support)

149

151 CmdArgs.push_back("-x");

153 }

154

155 if (II.isFilename())

156 CmdArgs.push_back(II.getFilename());

157 else {

158 const Arg &A = II.getInputArg();

159

160

161 if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {

162 CmdArgs.push_back("-lstdc++");

163 continue;

164 }

165

166

167 A.render(Args, CmdArgs);

168 }

169 }

170

171 const std::string &customGCCName = D.getCCCGenericGCCName();

172 const char *GCCName;

173 if (!customGCCName.empty())

174 GCCName = customGCCName.c_str();

175 else if (D.CCCIsCXX()) {

176 GCCName = "g++";

177 } else

178 GCCName = "gcc";

179

180 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));

181 C.addCommand(std::make_unique(JA, *this,

183 Exec, CmdArgs, Inputs, Output));

184}

185

187 const JobAction &JA, ArgStringList &CmdArgs) const {

188 CmdArgs.push_back("-E");

189}

190

192 ArgStringList &CmdArgs) const {

193 const Driver &D = getToolChain().getDriver();

194

196

197 case types::TY_LLVM_IR:

198 case types::TY_LTO_IR:

199 case types::TY_LLVM_BC:

200 case types::TY_LTO_BC:

201 CmdArgs.push_back("-c");

202 break;

203

204

205 case types::TY_Object:

206 CmdArgs.push_back("-c");

207 break;

208 case types::TY_PP_Asm:

209 CmdArgs.push_back("-S");

210 break;

211 case types::TY_Nothing:

212 CmdArgs.push_back("-fsyntax-only");

213 break;

214 default:

215 D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());

216 }

217}

218

220 ArgStringList &CmdArgs) const {

221

222}

223

224static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {

225 switch (T.getArch()) {

226 case llvm::Triple::x86:

227 if (T.isOSIAMCU())

228 return "elf_iamcu";

229 return "elf_i386";

230 case llvm::Triple::aarch64:

231 return "aarch64linux";

232 case llvm::Triple::aarch64_be:

233 return "aarch64linuxb";

234 case llvm::Triple::arm:

235 case llvm::Triple::thumb:

236 case llvm::Triple::armeb:

237 case llvm::Triple::thumbeb:

239 : "armelf_linux_eabi";

240 case llvm::Triple::m68k:

241 return "m68kelf";

242 case llvm::Triple::ppc:

243 if (T.isOSLinux())

244 return "elf32ppclinux";

245 return "elf32ppc";

246 case llvm::Triple::ppcle:

247 if (T.isOSLinux())

248 return "elf32lppclinux";

249 return "elf32lppc";

250 case llvm::Triple::ppc64:

251 return "elf64ppc";

252 case llvm::Triple::ppc64le:

253 return "elf64lppc";

254 case llvm::Triple::riscv32:

255 return "elf32lriscv";

256 case llvm::Triple::riscv64:

257 return "elf64lriscv";

258 case llvm::Triple::sparc:

259 case llvm::Triple::sparcel:

260 return "elf32_sparc";

261 case llvm::Triple::sparcv9:

262 return "elf64_sparc";

263 case llvm::Triple::loongarch32:

264 return "elf32loongarch";

265 case llvm::Triple::loongarch64:

266 return "elf64loongarch";

267 case llvm::Triple::mips:

268 return "elf32btsmip";

269 case llvm::Triple::mipsel:

270 return "elf32ltsmip";

271 case llvm::Triple::mips64:

273 return "elf32btsmipn32";

274 return "elf64btsmip";

275 case llvm::Triple::mips64el:

277 return "elf32ltsmipn32";

278 return "elf64ltsmip";

279 case llvm::Triple::systemz:

280 return "elf64_s390";

281 case llvm::Triple::x86_64:

282 if (T.isX32())

283 return "elf32_x86_64";

284 return "elf_x86_64";

285 case llvm::Triple::ve:

286 return "elf64ve";

287 case llvm::Triple::csky:

288 return "cskyelf_linux";

289 default:

290 return nullptr;

291 }

292}

293

295 bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);

296 if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {

298 const llvm::opt::OptTable &Opts = D.getOpts();

299 StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie);

300 StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie);

301 D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;

302 }

303 return HasStaticPIE;

304}

305

307 return Args.hasArg(options::OPT_static) &&

308 !Args.hasArg(options::OPT_static_pie);

309}

310

313 const InputInfoList &Inputs, const ArgList &Args,

314 const char *LinkingOutput) const {

315 const Driver &D = getToolChain().getDriver();

316

317

318 Args.ClaimAllArgs(options::OPT_g_Group);

319

320 Args.ClaimAllArgs(options::OPT_emit_llvm);

321

322

323 Args.ClaimAllArgs(options::OPT_w);

324

325 Args.ClaimAllArgs(options::OPT_stdlib_EQ);

326

327

328 ArgStringList CmdArgs;

329

330 CmdArgs.push_back("rcsD");

332

333 for (const auto &II : Inputs) {

334 if (II.isFilename()) {

335 CmdArgs.push_back(II.getFilename());

336 }

337 }

338

339

340

341 auto OutputFileName = Output.getFilename();

342 if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {

343 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {

344 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();

345 return;

346 }

347 }

348

349 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());

350 C.addCommand(std::make_unique(JA, *this,

352 Exec, CmdArgs, Inputs, Output));

353}

354

358 const ArgList &Args,

359 const char *LinkingOutput) const {

360

361

362

363

366

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

368

376 const bool HasCRTBeginEndFiles =

378 (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);

379

380 ArgStringList CmdArgs;

381

382

383 Args.ClaimAllArgs(options::OPT_g_Group);

384

385 Args.ClaimAllArgs(options::OPT_emit_llvm);

386

387

388 Args.ClaimAllArgs(options::OPT_w);

389

390 if (D.SysRoot.empty())

391 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));

392

393 if (Args.hasArg(options::OPT_s))

394 CmdArgs.push_back("-s");

395

396 if (Triple.isARM() || Triple.isThumb()) {

398 if (IsBigEndian)

400 CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");

401 } else if (Triple.isAArch64()) {

402 CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");

403 }

404

405

406

407 if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {

408 std::string CPU = getCPUName(D, Args, Triple);

409 if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")

410 CmdArgs.push_back("--fix-cortex-a53-843419");

411 }

412

414

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

416

418 CmdArgs.push_back("-m");

419 CmdArgs.push_back(LDMOption);

420 } else {

421 D.Diag(diag::err_target_unknown_triple) << Triple.str();

422 return;

423 }

424

425 if (Triple.isLoongArch() || Triple.isRISCV()) {

426 CmdArgs.push_back("-X");

427 if (Args.hasArg(options::OPT_mno_relax))

428 CmdArgs.push_back("--no-relax");

429 }

430

431 const bool IsShared = Args.hasArg(options::OPT_shared);

432 if (IsShared)

433 CmdArgs.push_back("-shared");

434 bool IsPIE = false;

435 if (IsStaticPIE) {

436 CmdArgs.push_back("-static");

437 CmdArgs.push_back("-pie");

438 CmdArgs.push_back("--no-dynamic-linker");

439 CmdArgs.push_back("-z");

440 CmdArgs.push_back("text");

442 CmdArgs.push_back("-static");

443 } else if (!Args.hasArg(options::OPT_r)) {

444 if (Args.hasArg(options::OPT_rdynamic))

445 CmdArgs.push_back("-export-dynamic");

446 if (!IsShared) {

447 IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,

449 if (IsPIE)

450 CmdArgs.push_back("-pie");

451 CmdArgs.push_back("-dynamic-linker");

452 CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +

453 ToolChain.getDynamicLinker(Args)));

454 }

455 }

456

457 CmdArgs.push_back("-o");

459

460 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,

461 options::OPT_r)) {

462 if (!isAndroid && !IsIAMCU) {

463 const char *crt1 = nullptr;

464 if (!Args.hasArg(options::OPT_shared)) {

465 if (Args.hasArg(options::OPT_pg))

466 crt1 = "gcrt1.o";

467 else if (IsPIE)

468 crt1 = "Scrt1.o";

469 else if (IsStaticPIE)

470 crt1 = "rcrt1.o";

471 else

472 crt1 = "crt1.o";

473 }

474 if (crt1)

476

478 }

479

480 if (IsVE) {

481 CmdArgs.push_back("-z");

482 CmdArgs.push_back("max-page-size=0x4000000");

483 }

484

485 if (IsIAMCU)

487 else if (HasCRTBeginEndFiles) {

488 std::string P;

490 !isAndroid) {

494 P = crtbegin;

495 }

496 if (P.empty()) {

497 const char *crtbegin;

498 if (Args.hasArg(options::OPT_shared))

499 crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";

501 crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";

502 else if (IsPIE || IsStaticPIE)

503 crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";

504 else

505 crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";

507 }

508 CmdArgs.push_back(Args.MakeArgString(P));

509 }

510

511

513

514 if (isAndroid && Args.hasFlag(options::OPT_fandroid_pad_segment,

515 options::OPT_fno_android_pad_segment, false))

516 CmdArgs.push_back(

518 }

519

520 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});

521

523

524 if (D.isUsingLTO()) {

525 assert(!Inputs.empty() && "Must have at least one input.");

526

527 auto Input = llvm::find_if(

529 if (Input == Inputs.end())

530

531

532 Input = Inputs.begin();

533

536 }

537

538 if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))

539 CmdArgs.push_back("--no-demangle");

540

545

547

548

549 getToolChain().addProfileRTLibs(Args, CmdArgs);

550

551 if (D.CCCIsCXX() &&

552 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,

553 options::OPT_r)) {

555 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&

556 !Args.hasArg(options::OPT_static);

557 if (OnlyLibstdcxxStatic)

558 CmdArgs.push_back("-Bstatic");

560 if (OnlyLibstdcxxStatic)

561 CmdArgs.push_back("-Bdynamic");

562 }

563 CmdArgs.push_back("-lm");

564 }

565

566

567 Args.ClaimAllArgs(options::OPT_stdlib_EQ);

568

569

570

571

572

573 if (D.IsFlangMode() &&

574 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {

577 CmdArgs.push_back("-lm");

578 }

579

580 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) {

581 if (!Args.hasArg(options::OPT_nodefaultlibs)) {

583 CmdArgs.push_back("--start-group");

584

585 if (NeedsSanitizerDeps)

587

588 if (NeedsXRayDeps)

590

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

592 Args.hasArg(options::OPT_pthreads);

593

594

595 bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&

596 !Args.hasArg(options::OPT_static);

597

598

599

602 true))

603

604

605 WantPthread = true;

606

608

609

610

611

612 if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) {

613 CmdArgs.push_back("--push-state");

614 CmdArgs.push_back("--as-needed");

615 CmdArgs.push_back("-latomic");

616 CmdArgs.push_back("--pop-state");

617 }

618

619

620

621 if (WantPthread && !isAndroid && !isOHOSFamily)

622 CmdArgs.push_back("-lpthread");

623

624 if (Args.hasArg(options::OPT_fsplit_stack))

625 CmdArgs.push_back("--wrap=pthread_create");

626

627 if (!Args.hasArg(options::OPT_nolibc))

628 CmdArgs.push_back("-lc");

629

630

631 if (IsIAMCU)

632 CmdArgs.push_back("-lgloss");

633

635 CmdArgs.push_back("--end-group");

636 else

638

639

640 if (IsIAMCU) {

641 CmdArgs.push_back("--as-needed");

642 CmdArgs.push_back("-lsoftfp");

643 CmdArgs.push_back("--no-as-needed");

644 }

645 }

646

647 if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {

648 if (HasCRTBeginEndFiles) {

649 std::string P;

651 !isAndroid) {

655 P = crtend;

656 }

657 if (P.empty()) {

658 const char *crtend;

659 if (Args.hasArg(options::OPT_shared))

660 crtend = isAndroid ? "crtend_so.o" : "crtendS.o";

661 else if (IsPIE || IsStaticPIE)

662 crtend = isAndroid ? "crtend_android.o" : "crtendS.o";

663 else

664 crtend = isAndroid ? "crtend_android.o" : "crtend.o";

666 }

667 CmdArgs.push_back(Args.MakeArgString(P));

668 }

669 if (!isAndroid)

671 }

672 }

673

674 Args.addAllArgs(CmdArgs, {options::OPT_T, options::OPT_t});

675

677 C.addCommand(std::make_unique(JA, *this,

679 Exec, CmdArgs, Inputs, Output));

680}

681

686 const ArgList &Args,

687 const char *LinkingOutput) const {

688 const auto &D = getToolChain().getDriver();

689

691

692 ArgStringList CmdArgs;

693

694 llvm::Reloc::Model RelocationModel;

695 unsigned PICLevel;

696 bool IsPIE;

697 const char *DefaultAssembler = "as";

698

699

700 if (getToolChain().getTriple().isOSSolaris())

701 DefaultAssembler = "gas";

702 std::tie(RelocationModel, PICLevel, IsPIE) =

704

705 if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) {

706 if (A->getOption().getID() == options::OPT_gz) {

707 CmdArgs.push_back("--compress-debug-sections");

708 } else {

709 StringRef Value = A->getValue();

710 if (Value == "none" || Value == "zlib" || Value == "zstd") {

711 CmdArgs.push_back(

712 Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));

713 } else {

714 D.Diag(diag::err_drv_unsupported_option_argument)

715 << A->getSpelling() << Value;

716 }

717 }

718 }

719

720 switch (getToolChain().getArch()) {

721 default:

722 break;

723

724

725 case llvm::Triple::x86:

726 CmdArgs.push_back("--32");

727 break;

728 case llvm::Triple::x86_64:

729 if (getToolChain().getTriple().isX32())

730 CmdArgs.push_back("--x32");

731 else

732 CmdArgs.push_back("--64");

733 break;

734 case llvm::Triple::ppc: {

735 CmdArgs.push_back("-a32");

736 CmdArgs.push_back("-mppc");

737 CmdArgs.push_back("-mbig-endian");

739 getCPUName(D, Args, getToolChain().getTriple())));

740 break;

741 }

742 case llvm::Triple::ppcle: {

743 CmdArgs.push_back("-a32");

744 CmdArgs.push_back("-mppc");

745 CmdArgs.push_back("-mlittle-endian");

747 getCPUName(D, Args, getToolChain().getTriple())));

748 break;

749 }

750 case llvm::Triple::ppc64: {

751 CmdArgs.push_back("-a64");

752 CmdArgs.push_back("-mppc64");

753 CmdArgs.push_back("-mbig-endian");

755 getCPUName(D, Args, getToolChain().getTriple())));

756 break;

757 }

758 case llvm::Triple::ppc64le: {

759 CmdArgs.push_back("-a64");

760 CmdArgs.push_back("-mppc64");

761 CmdArgs.push_back("-mlittle-endian");

763 getCPUName(D, Args, getToolChain().getTriple())));

764 break;

765 }

766 case llvm::Triple::riscv32:

767 case llvm::Triple::riscv64: {

768 StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());

769 CmdArgs.push_back("-mabi");

770 CmdArgs.push_back(ABIName.data());

771 std::string MArchName =

773 CmdArgs.push_back("-march");

774 CmdArgs.push_back(Args.MakeArgString(MArchName));

775 if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))

776 Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);

777 break;

778 }

779 case llvm::Triple::sparc:

780 case llvm::Triple::sparcel: {

781 CmdArgs.push_back("-32");

782 std::string CPU = getCPUName(D, Args, getToolChain().getTriple());

783 CmdArgs.push_back(

786 break;

787 }

788 case llvm::Triple::sparcv9: {

789 CmdArgs.push_back("-64");

790 std::string CPU = getCPUName(D, Args, getToolChain().getTriple());

791 CmdArgs.push_back(

794 break;

795 }

796 case llvm::Triple::arm:

797 case llvm::Triple::armeb:

798 case llvm::Triple::thumb:

799 case llvm::Triple::thumbeb: {

800 const llvm::Triple &Triple2 = getToolChain().getTriple();

802 switch (Triple2.getSubArch()) {

803 case llvm::Triple::ARMSubArch_v7:

804 CmdArgs.push_back("-mfpu=neon");

805 break;

806 case llvm::Triple::ARMSubArch_v8:

807 CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");

808 break;

809 default:

810 break;

811 }

812

816 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));

817 break;

819 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));

820 break;

822 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));

823 break;

824 }

825

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

828

829 Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);

830

831

832

833 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))

834 A->ignoreTargetSpecific();

835 break;

836 }

837 case llvm::Triple::aarch64:

838 case llvm::Triple::aarch64_be: {

839 CmdArgs.push_back(

840 getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL");

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

843

844 break;

845 }

846

847 case llvm::Triple::loongarch64: {

848 StringRef ABIName =

850 CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName));

851 break;

852 }

853 case llvm::Triple::mips:

854 case llvm::Triple::mipsel:

855 case llvm::Triple::mips64:

856 case llvm::Triple::mips64el: {

857 StringRef CPUName;

858 StringRef ABIName;

861

862 CmdArgs.push_back("-march");

863 CmdArgs.push_back(CPUName.data());

864

865 CmdArgs.push_back("-mabi");

866 CmdArgs.push_back(ABIName.data());

867

868

869

870 if (RelocationModel == llvm::Reloc::Static)

871 CmdArgs.push_back("-mno-shared");

872

873

874

875 if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls))

876 CmdArgs.push_back("-call_nonpic");

877

878 if (getToolChain().getTriple().isLittleEndian())

879 CmdArgs.push_back("-EL");

880 else

881 CmdArgs.push_back("-EB");

882

883 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {

884 if (StringRef(A->getValue()) == "2008")

885 CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));

886 }

887

888

889 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,

890 options::OPT_mfp64)) {

891 A->claim();

892 A->render(Args, CmdArgs);

894 Args, getToolChain().getTriple(), CPUName, ABIName,

896 getToolChain().getTriple())))

897 CmdArgs.push_back("-mfpxx");

898

899

900

901 if (Arg *A =

902 Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {

903 if (A->getOption().matches(options::OPT_mips16)) {

904 A->claim();

905 A->render(Args, CmdArgs);

906 } else {

907 A->claim();

908 CmdArgs.push_back("-no-mips16");

909 }

910 }

911

912 Args.AddLastArg(CmdArgs, options::OPT_mmicromips,

913 options::OPT_mno_micromips);

914 Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);

915 Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);

916

917 if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {

918

919

920 if (A->getOption().matches(options::OPT_mmsa))

921 CmdArgs.push_back(Args.MakeArgString("-mmsa"));

922 }

923

924 Args.AddLastArg(CmdArgs, options::OPT_mhard_float,

925 options::OPT_msoft_float);

926

927 Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,

928 options::OPT_msingle_float);

929

930 Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,

931 options::OPT_mno_odd_spreg);

932

934 break;

935 }

936 case llvm::Triple::systemz: {

937

938

939 std::string CPUName =

941 CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));

942 break;

943 }

944 case llvm::Triple::ve:

945 DefaultAssembler = "nas";

946 }

947

948 for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,

949 options::OPT_fdebug_prefix_map_EQ)) {

950 StringRef Map = A->getValue();

951 if (!Map.contains('='))

952 D.Diag(diag::err_drv_invalid_argument_to_option)

953 << Map << A->getOption().getName();

954 else {

955 CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map"));

956 CmdArgs.push_back(Args.MakeArgString(Map));

957 }

958 A->claim();

959 }

960

961 Args.AddAllArgs(CmdArgs, options::OPT_I);

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

963

964 CmdArgs.push_back("-o");

966

967 for (const auto &II : Inputs)

968 CmdArgs.push_back(II.getFilename());

969

970 if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group,

971 options::OPT_gdwarf_2, options::OPT_gdwarf_3,

972 options::OPT_gdwarf_4, options::OPT_gdwarf_5,

973 options::OPT_gdwarf))

974 if (!A->getOption().matches(options::OPT_g0)) {

975 Args.AddLastArg(CmdArgs, options::OPT_g_Flag);

976

977 unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args);

978 CmdArgs.push_back(Args.MakeArgString("-gdwarf-" + Twine(DwarfVersion)));

979 }

980

981 const char *Exec =

982 Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));

983 C.addCommand(std::make_unique(JA, *this,

985 Exec, CmdArgs, Inputs, Output));

986

987

988

989

990 if (Args.hasArg(options::OPT_gsplit_dwarf) &&

991 getToolChain().getTriple().isOSLinux())

992 SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,

994}

995

996namespace {

997

998class FilterNonExistent {

1000 llvm::vfs::FileSystem &VFS;

1001

1002public:

1003 FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS)

1005 bool operator()(const Multilib &M) {

1007 }

1008};

1009}

1010

1012 Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,

1013 options::OPT_mfloat_abi_EQ);

1014 if (!A)

1015 return false;

1016

1017 return A->getOption().matches(options::OPT_msoft_float) ||

1018 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&

1019 A->getValue() == StringRef("soft"));

1020}

1021

1023 return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;

1024}

1025

1026static bool isMipsEL(llvm::Triple::ArchType Arch) {

1027 return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;

1028}

1029

1031 Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);

1032 return A && A->getOption().matches(options::OPT_mips16);

1033}

1034

1036 Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);

1037 return A && A->getOption().matches(options::OPT_mmicromips);

1038}

1039

1040static bool isMSP430(llvm::Triple::ArchType Arch) {

1041 return Arch == llvm::Triple::msp430;

1042}

1043

1046 FilterNonExistent &NonExistent,

1048

1050 {

1052

1053 auto MArchMicroMips =

1055

1057 .flag("-mips16", true)

1058 .flag("-mmicromips", true);

1059

1061

1063

1065

1067 .flag("-msoft-float", true)

1068 .flag("-mnan=2008", true);

1069

1070 auto BigEndian =

1072

1073 auto LittleEndian =

1075

1076

1079 .includeSuffix("/64")

1080 .flag("-mabi=n64")

1081 .flag("-mabi=n32", true)

1082 .flag("-m32", true);

1083

1084 CSMipsMultilibs =

1086 .Either(MArchMips16, MArchMicroMips, MArchDefault)

1088 .Either(SoftFloat, Nan2008, DefaultFloat)

1089 .FilterOut("/micromips/nan2008")

1091 .Either(BigEndian, LittleEndian)

1098 std::vectorstd::string Dirs({"/include"});

1099 if (StringRef(M.includeSuffix()).starts_with("/uclibc"))

1100 Dirs.push_back(

1101 "/../../../../mips-linux-gnu/libc/uclibc/usr/include");

1102 else

1103 Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");

1104 return Dirs;

1105 });

1106 }

1107

1109 {

1112 "-mabi=n32");

1113

1116 .includeSuffix("/64")

1117 .flag("-m64")

1118 .flag("-m32", true)

1119 .flag("-mabi=n32", true);

1120

1123 .flag("-m64", true)

1124 .flag("-m32")

1125 .flag("-mabi=n32", true);

1126

1128 .Either(M32, M64, MAbiN32)

1131 }

1132

1133

1134

1135 MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};

1136 if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())

1137 std::iter_swap(Candidates, Candidates + 1);

1138 for (const MultilibSet *Candidate : Candidates) {

1139 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {

1140 if (Candidate == &DebianMipsMultilibs)

1142 Result.Multilibs = *Candidate;

1143 return true;

1144 }

1145 }

1146 return false;

1147}

1148

1151 FilterNonExistent &NonExistent,

1153

1155 {

1157 .osSuffix("/mips-r2-hard-musl")

1158 .flag("-EB")

1159 .flag("-EL", true)

1160 .flag("-march=mips32r2");

1161

1162 auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl")

1163 .flag("-EB", true)

1164 .flag("-EL")

1165 .flag("-march=mips32r2");

1166

1168 .Either(MArchMipsR2, MArchMipselR2)

1170

1171

1173 return std::vectorstd::string(

1174 {"/../sysroot" + M.osSuffix() + "/usr/include"});

1175 });

1176 }

1177 if (MuslMipsMultilibs.select(D, Flags, Result.SelectedMultilibs)) {

1178 Result.Multilibs = MuslMipsMultilibs;

1179 return true;

1180 }

1181 return false;

1182}

1183

1186 FilterNonExistent &NonExistent,

1188

1190 {

1192 .flag("-m32")

1193 .flag("-m64", true)

1194 .flag("-mmicromips", true)

1195 .flag("-march=mips32");

1196

1198 .flag("-m32")

1199 .flag("-m64", true)

1200 .flag("-mmicromips");

1201

1203 .flag("-m32", true)

1204 .flag("-m64")

1205 .flag("-march=mips64r2");

1206

1208 .flag("-m32", true)

1209 .flag("-m64")

1210 .flag("-march=mips64r2", true);

1211

1213 .flag("-m32")

1214 .flag("-m64", true)

1215 .flag("-mmicromips", true)

1216 .flag("-march=mips32r2");

1217

1219

1221

1223 .flag("-mabi=n64")

1224 .flag("-mabi=n32", true)

1225 .flag("-m32", true);

1226

1227 auto BigEndian =

1229

1230 auto LittleEndian =

1232

1234

1236

1237 MtiMipsMultilibsV1 =

1239 .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,

1240 MArchDefault)

1251 .Either(BigEndian, LittleEndian)

1252 .Maybe(SoftFloat)

1258 std::vectorstd::string Dirs({"/include"});

1259 if (StringRef(M.includeSuffix()).starts_with("/uclibc"))

1260 Dirs.push_back("/../../../../sysroot/uclibc/usr/include");

1261 else

1262 Dirs.push_back("/../../../../sysroot/usr/include");

1263 return Dirs;

1264 });

1265 }

1266

1267

1269 {

1271 .flag("-EB")

1272 .flag("-msoft-float", true)

1273 .flag("-mnan=2008", true)

1274 .flag("-muclibc", true);

1276 .flag("-EB")

1277 .flag("-msoft-float")

1278 .flag("-mnan=2008", true);

1280 .flag("-EL")

1281 .flag("-msoft-float", true)

1282 .flag("-mnan=2008", true)

1283 .flag("-muclibc", true);

1285 .flag("-EL")

1286 .flag("-msoft-float")

1287 .flag("-mnan=2008", true)

1288 .flag("-mmicromips", true);

1289 auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008")

1290 .flag("-EB")

1291 .flag("-msoft-float", true)

1292 .flag("-mnan=2008")

1293 .flag("-muclibc", true);

1294 auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008")

1295 .flag("-EL")

1296 .flag("-msoft-float", true)

1297 .flag("-mnan=2008")

1298 .flag("-muclibc", true)

1299 .flag("-mmicromips", true);

1300 auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc")

1301 .flag("-EB")

1302 .flag("-msoft-float", true)

1303 .flag("-mnan=2008")

1304 .flag("-muclibc");

1305 auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc")

1306 .flag("-EL")

1307 .flag("-msoft-float", true)

1308 .flag("-mnan=2008")

1309 .flag("-muclibc");

1310 auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc")

1311 .flag("-EB")

1312 .flag("-msoft-float", true)

1313 .flag("-mnan=2008", true)

1314 .flag("-muclibc");

1315 auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc")

1316 .flag("-EL")

1317 .flag("-msoft-float", true)

1318 .flag("-mnan=2008", true)

1319 .flag("-muclibc");

1320 auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008")

1321 .flag("-EL")

1322 .flag("-msoft-float", true)

1323 .flag("-mnan=2008")

1324 .flag("-mmicromips");

1325 auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft")

1326 .flag("-EL")

1327 .flag("-msoft-float")

1328 .flag("-mnan=2008", true)

1329 .flag("-mmicromips");

1330

1333 .flag("-mabi=n32", true)

1334 .flag("-mabi=n64", true);

1337 .flag("-mabi=n32")

1338 .flag("-mabi=n64", true);

1341 .flag("-mabi=n32", true)

1342 .flag("-mabi=n64");

1343

1344 MtiMipsMultilibsV2 =

1346 .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,

1347 BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,

1348 ElHardUclibc, ElMicroHardNan, ElMicroSoft})

1349 .Either(O32, N32, N64)

1353 return std::vectorstd::string({"/../../../../sysroot" +

1355 "/../usr/include"});

1356 })

1357 .setFilePathsCallback([](const Multilib &M) {

1358 return std::vectorstd::string(

1359 {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});

1360 });

1361 }

1362 for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {

1363 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {

1364 Result.Multilibs = *Candidate;

1365 return true;

1366 }

1367 }

1368 return false;

1369}

1370

1373 FilterNonExistent &NonExistent,

1375

1377 {

1379 .flag("-m64")

1380 .flag("-m32", true);

1381

1382 auto LittleEndian =

1384

1386 .flag("-mabi=n64")

1387 .flag("-mabi=n32", true)

1388 .flag("-m32", true);

1389

1390 ImgMultilibsV1 =

1392 .Maybe(Mips64r6)

1394 .Maybe(LittleEndian)

1398 return std::vectorstd::string(

1399 {"/include", "/../../../../sysroot/usr/include"});

1400 });

1401 }

1402

1403

1405 {

1407 .flag("-EB")

1408 .flag("-msoft-float", true)

1409 .flag("-mmicromips", true);

1411 .flag("-EB")

1412 .flag("-msoft-float")

1413 .flag("-mmicromips", true);

1415 .flag("-EL")

1416 .flag("-msoft-float", true)

1417 .flag("-mmicromips", true);

1419 .flag("-EL")

1420 .flag("-msoft-float")

1421 .flag("-mmicromips", true);

1422 auto BeMicroHard = MultilibBuilder("/micromips-r6-hard")

1423 .flag("-EB")

1424 .flag("-msoft-float", true)

1425 .flag("-mmicromips");

1426 auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft")

1427 .flag("-EB")

1428 .flag("-msoft-float")

1429 .flag("-mmicromips");

1430 auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard")

1431 .flag("-EL")

1432 .flag("-msoft-float", true)

1433 .flag("-mmicromips");

1434 auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft")

1435 .flag("-EL")

1436 .flag("-msoft-float")

1437 .flag("-mmicromips");

1438

1441 .flag("-mabi=n32", true)

1442 .flag("-mabi=n64", true);

1445 .flag("-mabi=n32")

1446 .flag("-mabi=n64", true);

1449 .flag("-mabi=n32", true)

1450 .flag("-mabi=n64");

1451

1452 ImgMultilibsV2 =

1454 .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,

1455 ElMicroHard, ElMicroSoft})

1456 .Either(O32, N32, N64)

1460 return std::vectorstd::string({"/../../../../sysroot" +

1462 "/../usr/include"});

1463 })

1464 .setFilePathsCallback([](const Multilib &M) {

1465 return std::vectorstd::string(

1466 {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});

1467 });

1468 }

1469 for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {

1470 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {

1471 Result.Multilibs = *Candidate;

1472 return true;

1473 }

1474 }

1475 return false;

1476}

1477

1479 const llvm::Triple &TargetTriple,

1480 StringRef Path, const ArgList &Args,

1482 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1483

1484 StringRef CPUName;

1485 StringRef ABIName;

1487

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

1489

1491 addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags);

1492 addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags);

1494 addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags);

1495 addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||

1496 CPUName == "mips32r5" || CPUName == "p5600",

1497 "-march=mips32r2", Flags);

1498 addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags);

1499 addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags);

1500 addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||

1501 CPUName == "mips64r5" || CPUName == "octeon" ||

1502 CPUName == "octeon+",

1503 "-march=mips64r2", Flags);

1504 addMultilibFlag(CPUName == "mips64r6", "-march=mips64r6", Flags);

1508 Flags);

1515

1516 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&

1517 TargetTriple.getOS() == llvm::Triple::Linux &&

1518 TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)

1520

1521 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&

1522 TargetTriple.getOS() == llvm::Triple::Linux &&

1523 TargetTriple.isGNUEnvironment())

1525

1526 if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&

1527 TargetTriple.getOS() == llvm::Triple::Linux &&

1528 TargetTriple.isGNUEnvironment())

1530

1532 return true;

1533

1534

1537 Result.Multilibs.FilterOut(NonExistent);

1538

1539 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs)) {

1541 return true;

1542 }

1543

1544 return false;

1545}

1546

1548 const llvm::Triple &TargetTriple,

1549 StringRef Path, const ArgList &Args,

1551

1552 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1554 .flag("-march=armv7-a")

1555 .flag("-mthumb", true);

1557 .flag("-march=armv7-a", true)

1558 .flag("-mthumb");

1563 .flag("-march=armv7-a", true)

1564 .flag("-mthumb", true);

1567 .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib,

1568 DefaultMultilib)

1571

1573 llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);

1574 bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;

1575 bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;

1576 bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;

1577 bool IsThumbMode = IsThumbArch ||

1578 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||

1579 (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB);

1580 bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&

1581 (llvm::ARM::parseArchVersion(Arch) == 7 ||

1582 (IsArmArch && Arch == "" && IsV7SubArch));

1583 addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);

1584 addMultilibFlag(IsThumbMode, "-mthumb", Flags);

1585

1586 if (AndroidArmMultilibs.select(D, Flags, Result.SelectedMultilibs))

1587 Result.Multilibs = AndroidArmMultilibs;

1588}

1589

1591 const llvm::Triple &TargetTriple,

1592 StringRef Path, const ArgList &Args,

1594 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1599

1600

1601

1602

1603

1606 Result.Multilibs.FilterOut(NonExistent);

1607

1609 addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,

1610 options::OPT_fno_exceptions, false),

1611 "-exceptions", Flags);

1612 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))

1613 return true;

1614

1615 return false;

1616}

1617

1619 StringRef Path, const ArgList &Args,

1621 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1622

1624 std::optionalllvm::StringRef Res =

1626

1627 if (!Res)

1628 return;

1629 auto ARCHName = *Res;

1630

1633 Flags);

1635 Flags);

1637 addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags);

1638 addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags);

1639 addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags);

1640 addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags);

1641 addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags);

1642 addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags);

1643 addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags);

1644 addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags);

1645 addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags);

1646 addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags);

1647

1648 bool isBigEndian = false;

1649 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,

1650 options::OPT_mbig_endian))

1651 isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);

1652 addMultilibFlag(isBigEndian, "-EB", Flags);

1653

1660

1669

1672 .Maybe(BigEndian)

1673 .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807,

1674 Arch810, Arch810v, Arch860, Arch860v})

1675 .Either(HardFloat, SoftFpFloat, SoftFloat)

1678

1679 if (CSKYMultilibs.select(D, Flags, Result.SelectedMultilibs))

1680 Result.Multilibs = CSKYMultilibs;

1681}

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693static bool

1697

1698 if (RISCVMultilibSet.select(D, Flags, SelectedMultilibs))

1699 return true;

1700

1702 std::vector NewMultilibs;

1703

1705 llvm::RISCVISAInfo::parseArchString(

1706 Arch, true,

1707 false);

1708

1709 if (llvm::errorToBool(ParseResult.takeError()))

1710 return false;

1711

1712 auto &ISAInfo = *ParseResult;

1713

1714 addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);

1715 addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);

1716

1717

1718 for (StringRef Flag : Flags) {

1719 if (Flag.starts_with("!march=") || Flag.starts_with("-march="))

1720 continue;

1721

1722 NewFlags.push_back(Flag.str());

1723 }

1724

1725 llvm::StringSet<> AllArchExts;

1726

1727

1728 for (const auto &M : RISCVMultilibSet) {

1729 bool Skip = false;

1730

1732 MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());

1733 for (StringRef Flag : M.flags()) {

1734

1735 if (!Flag.consume_front("-march=")) {

1736 NewMultilib.flag(Flag);

1737 continue;

1738 }

1739

1740

1742 llvm::RISCVISAInfo::parseArchString(

1743 Flag, true,

1744 false);

1745

1746 if (llvm::errorToBool(MLConfigParseResult.takeError())) {

1747

1748

1749 Skip = true;

1750 continue;

1751 }

1752 auto &MLConfigISAInfo = *MLConfigParseResult;

1753

1754 for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) {

1755 auto ExtName = MLConfigArchExt.first;

1756 NewMultilib.flag(Twine("-", ExtName).str());

1757

1758 if (AllArchExts.insert(ExtName).second) {

1759 addMultilibFlag(ISAInfo->hasExtension(ExtName),

1760 Twine("-", ExtName).str(), NewFlags);

1761 }

1762 }

1763

1764

1765 if (MLConfigISAInfo->getXLen() == 32) {

1766 NewMultilib.flag("-m32");

1767 NewMultilib.flag("-m64", true);

1768 } else {

1769 NewMultilib.flag("-m32", true);

1770 NewMultilib.flag("-m64");

1771 }

1772

1773

1774

1775 if (!MLConfigISAInfo->hasExtension("a"))

1776 NewMultilib.flag("-a", true);

1777 }

1778

1780 continue;

1781

1782 NewMultilibs.emplace_back(NewMultilib);

1783 }

1784

1785

1786

1789

1790 if (NewRISCVMultilibs.select(D, NewFlags, SelectedMultilibs))

1791 for (const Multilib &NewSelectedM : SelectedMultilibs)

1792 for (const auto &M : RISCVMultilibSet)

1793

1794 if (M.gccSuffix() == NewSelectedM.gccSuffix())

1795 return true;

1796

1797 return false;

1798}

1799

1801 const llvm::Triple &TargetTriple,

1802 StringRef Path, const ArgList &Args,

1804 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1805 struct RiscvMultilib {

1806 StringRef march;

1807 StringRef mabi;

1808 };

1809

1810

1811 constexpr RiscvMultilib RISCVMultilibSet[] = {

1812 {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"},

1813 {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},

1814 {"rv64imafdc", "lp64d"}};

1815

1816 std::vector Ms;

1817 for (auto Element : RISCVMultilibSet) {

1818

1819 Ms.emplace_back(

1821 (Twine(Element.march) + "/" + Twine(Element.mabi)).str())

1822 .flag(Twine("-march=", Element.march).str())

1823 .flag(Twine("-mabi=", Element.mabi).str()));

1824 }

1831 return std::vectorstd::string(

1833 "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),

1834 "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});

1835 });

1836

1838 llvm::StringSet<> Added_ABIs;

1841 for (auto Element : RISCVMultilibSet) {

1842 addMultilibFlag(MArch == Element.march,

1843 Twine("-march=", Element.march).str().c_str(), Flags);

1844 if (!Added_ABIs.count(Element.mabi)) {

1845 Added_ABIs.insert(Element.mabi);

1846 addMultilibFlag(ABIName == Element.mabi,

1847 Twine("-mabi=", Element.mabi).str().c_str(), Flags);

1848 }

1849 }

1850

1852 Result.SelectedMultilibs))

1853 Result.Multilibs = RISCVMultilibs;

1854}

1855

1857 const llvm::Triple &TargetTriple, StringRef Path,

1859 if (TargetTriple.getOS() == llvm::Triple::UnknownOS)

1861

1862 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1877 .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})

1878 .makeMultilibSet()

1880

1882 bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;

1884

1885 addMultilibFlag(!IsRV64, "-m32", Flags);

1886 addMultilibFlag(IsRV64, "-m64", Flags);

1887 addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags);

1888 addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags);

1889 addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags);

1890 addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);

1891 addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);

1892 addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);

1893

1894 if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))

1895 Result.Multilibs = RISCVMultilibs;

1896}

1897

1899 const llvm::Triple &TargetTriple,

1900 StringRef Path, const ArgList &Args,

1901 bool NeedsBiarchSuffix,

1904

1905

1906

1907

1908

1909

1910

1911

1912 StringRef Suff64 = "/64";

1913

1914 if (TargetTriple.isOSSolaris()) {

1915 switch (TargetTriple.getArch()) {

1916 case llvm::Triple::x86:

1917 case llvm::Triple::x86_64:

1918 Suff64 = "/amd64";

1919 break;

1920 case llvm::Triple::sparc:

1921 case llvm::Triple::sparcv9:

1922 Suff64 = "/sparcv9";

1923 break;

1924 default:

1925 break;

1926 }

1927 }

1928

1931 .includeSuffix(Suff64)

1932 .flag("-m32", true)

1933 .flag("-m64")

1934 .flag("-mx32", true)

1935 .makeMultilib();

1938 .includeSuffix("/32")

1939 .flag("-m32")

1940 .flag("-m64", true)

1941 .flag("-mx32", true)

1942 .makeMultilib();

1945 .includeSuffix("/x32")

1946 .flag("-m32", true)

1947 .flag("-m64", true)

1948 .flag("-mx32")

1949 .makeMultilib();

1952 .includeSuffix("/sparcv8plus")

1953 .flag("-m32")

1954 .flag("-m64", true)

1955 .makeMultilib();

1956

1957

1958 FilterNonExistent NonExistent(

1959 Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());

1960

1961

1962

1963 enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;

1964 const bool IsX32 = TargetTriple.isX32();

1965 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))

1966 Want = WANT64;

1967 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc))

1968 Want = WANT64;

1969 else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))

1970 Want = WANT64;

1971 else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))

1972 Want = WANT32;

1973 else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc))

1974 Want = WANT64;

1975 else {

1976 if (TargetTriple.isArch32Bit())

1977 Want = NeedsBiarchSuffix ? WANT64 : WANT32;

1978 else if (IsX32)

1979 Want = NeedsBiarchSuffix ? WANT64 : WANTX32;

1980 else

1981 Want = NeedsBiarchSuffix ? WANT32 : WANT64;

1982 }

1983

1984 if (Want == WANT32)

1985 DefaultBuilder.flag("-m32")

1986 .flag("-m64", true)

1987 .flag("-mx32", true);

1988 else if (Want == WANT64)

1989 DefaultBuilder.flag("-m32", true)

1990 .flag("-m64")

1991 .flag("-mx32", true);

1992 else if (Want == WANTX32)

1993 DefaultBuilder.flag("-m32", true)

1994 .flag("-m64", true)

1995 .flag("-mx32");

1996 else

1997 return false;

1998

2000

2002 Result.Multilibs.push_back(Alt64);

2003 Result.Multilibs.push_back(Alt32);

2004 Result.Multilibs.push_back(Altx32);

2005 Result.Multilibs.push_back(Alt32sparc);

2006

2007 Result.Multilibs.FilterOut(NonExistent);

2008

2010 addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "-m64", Flags);

2011 addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);

2012 addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);

2013

2014 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))

2015 return false;

2016

2017 if (Result.SelectedMultilibs.back() == Alt64 ||

2018 Result.SelectedMultilibs.back() == Alt32 ||

2019 Result.SelectedMultilibs.back() == Altx32 ||

2020 Result.SelectedMultilibs.back() == Alt32sparc)

2022

2023 return true;

2024}

2025

2026

2027

2028

2029

2030

2032 int RHSPatch,

2033 StringRef RHSPatchSuffix) const {

2034 if (Major != RHSMajor)

2035 return Major < RHSMajor;

2036 if (Minor != RHSMinor) {

2037

2038

2039 if (RHSMinor == -1)

2040 return true;

2041 if (Minor == -1)

2042 return false;

2043 return Minor < RHSMinor;

2044 }

2045 if (Patch != RHSPatch) {

2046

2047

2048 if (RHSPatch == -1)

2049 return true;

2050 if (Patch == -1)

2051 return false;

2052

2053

2054 return Patch < RHSPatch;

2055 }

2056 if (PatchSuffix != RHSPatchSuffix) {

2057

2058 if (RHSPatchSuffix.empty())

2059 return true;

2060 if (PatchSuffix.empty())

2061 return false;

2062

2063

2064 return PatchSuffix < RHSPatchSuffix;

2065 }

2066

2067

2068 return false;

2069}

2070

2071

2072

2073

2074

2076 const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};

2077 std::pair<StringRef, StringRef> First = VersionText.split('.');

2078 std::pair<StringRef, StringRef> Second = First.second.split('.');

2079

2080 StringRef MajorStr = First.first;

2081 StringRef MinorStr = Second.first;

2082 StringRef PatchStr = Second.second;

2083

2084 GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};

2085

2086

2087

2088

2089

2090

2091

2092

2093

2094

2095

2096

2097

2098

2099

2100 auto TryParseLastNumber = [&](StringRef Segment, int &Number,

2101 std::string &OutStr) -> bool {

2102

2103

2104

2105 if (size_t EndNumber = Segment.find_first_not_of("0123456789")) {

2106 StringRef NumberStr = Segment.slice(0, EndNumber);

2107 if (NumberStr.getAsInteger(10, Number) || Number < 0)

2108 return false;

2109 OutStr = NumberStr;

2110 GoodVersion.PatchSuffix = Segment.substr(EndNumber);

2111 return true;

2112 }

2113 return false;

2114 };

2115 auto TryParseNumber = [](StringRef Segment, int &Number) -> bool {

2116 if (Segment.getAsInteger(10, Number) || Number < 0)

2117 return false;

2118 return true;

2119 };

2120

2121 if (MinorStr.empty()) {

2122

2123 if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr))

2124 return BadVersion;

2125 return GoodVersion;

2126 }

2127

2128 if (!TryParseNumber(MajorStr, GoodVersion.Major))

2129 return BadVersion;

2130 GoodVersion.MajorStr = MajorStr;

2131

2132 if (PatchStr.empty()) {

2133

2134 if (!TryParseLastNumber(MinorStr, GoodVersion.Minor, GoodVersion.MinorStr))

2135 return BadVersion;

2136 return GoodVersion;

2137 }

2138

2139 if (!TryParseNumber(MinorStr, GoodVersion.Minor))

2140 return BadVersion;

2141 GoodVersion.MinorStr = MinorStr;

2142

2143

2144 std::string DummyStr;

2145 TryParseLastNumber(PatchStr, GoodVersion.Patch, DummyStr);

2146 return GoodVersion;

2147}

2148

2150 llvm::StringRef SysRoot) {

2151 const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain);

2152 if (A)

2153 return A->getValue();

2154

2155

2156

2157

2158 if (!SysRoot.empty())

2159 return "";

2160

2161 return GCC_INSTALL_PREFIX;

2162}

2163

2164

2165

2166

2167

2168

2169

2170

2171

2172

2174 const llvm::Triple &TargetTriple, const ArgList &Args) {

2175 llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()

2176 ? TargetTriple.get64BitArchVariant()

2177 : TargetTriple.get32BitArchVariant();

2178

2180

2183

2184 CandidateTripleAliases.push_back(TargetTriple.str());

2185 std::string TripleNoVendor, BiarchTripleNoVendor;

2186 if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) {

2187 StringRef OSEnv = TargetTriple.getOSAndEnvironmentName();

2188 if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32)

2189 OSEnv = "linux-gnu";

2190 TripleNoVendor = (TargetTriple.getArchName().str() + '-' + OSEnv).str();

2191 CandidateTripleAliases.push_back(TripleNoVendor);

2192 if (BiarchVariantTriple.getArch() != llvm::Triple::UnknownArch) {

2193 BiarchTripleNoVendor =

2194 (BiarchVariantTriple.getArchName().str() + '-' + OSEnv).str();

2195 CandidateBiarchTripleAliases.push_back(BiarchTripleNoVendor);

2196 }

2197 }

2198

2199 CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,

2200 CandidateTripleAliases, CandidateBiarchLibDirs,

2201 CandidateBiarchTripleAliases);

2202

2203

2204 if (const Arg *A =

2205 Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ);

2206 A && A->getValue()[0]) {

2207 StringRef InstallDir = A->getValue();

2208 if (!ScanGCCForMultilibs(TargetTriple, Args, InstallDir, false)) {

2209 D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir;

2210 } else {

2211 (void)InstallDir.consume_back("/");

2212 StringRef VersionText = llvm::sys::path::filename(InstallDir);

2213 StringRef TripleText =

2214 llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir));

2215

2216 Version = GCCVersion::Parse(VersionText);

2217 GCCTriple.setTriple(TripleText);

2218 GCCInstallPath = std::string(InstallDir);

2219 GCCParentLibPath = GCCInstallPath + "/../../..";

2220 IsValid = true;

2221 }

2222 return;

2223 }

2224

2225

2226

2227 if (const Arg *A =

2228 Args.getLastArg(clang::driver::options::OPT_gcc_triple_EQ)) {

2229 StringRef GCCTriple = A->getValue();

2230 CandidateTripleAliases.clear();

2231 CandidateTripleAliases.push_back(GCCTriple);

2232 }

2233

2234

2237 if (GCCToolchainDir != "") {

2238 if (GCCToolchainDir.back() == '/')

2239 GCCToolchainDir = GCCToolchainDir.drop_back();

2240

2241 Prefixes.push_back(std::string(GCCToolchainDir));

2242 } else {

2243

2244 if (D.SysRoot.empty()) {

2245 Prefixes.push_back(D.SysRoot);

2246 AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);

2247 }

2248

2249

2250 Prefixes.push_back(D.Dir + "/..");

2251

2252

2253

2254 if (D.SysRoot.empty()) {

2255

2256 AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);

2257 }

2258

2259

2260

2261

2263

2264

2265

2266

2267

2268 GentooTestTriples.push_back(TargetTriple.str());

2269 GentooTestTriples.append(CandidateTripleAliases.begin(),

2270 CandidateTripleAliases.end());

2271 if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples,

2272 CandidateBiarchTripleAliases))

2273 return;

2274 }

2275

2276

2277

2278 const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");

2279 Version = VersionZero;

2280 for (const std::string &Prefix : Prefixes) {

2281 auto &VFS = D.getVFS();

2282 if (!VFS.exists(Prefix))

2283 continue;

2284 for (StringRef Suffix : CandidateLibDirs) {

2285 const std::string LibDir = concat(Prefix, Suffix);

2286 if (!VFS.exists(LibDir))

2287 continue;

2288

2289 bool GCCDirExists = VFS.exists(LibDir + "/gcc");

2290 bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");

2291 for (StringRef Candidate : CandidateTripleAliases)

2292 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,

2293 GCCDirExists, GCCCrossDirExists);

2294 }

2295 for (StringRef Suffix : CandidateBiarchLibDirs) {

2296 const std::string LibDir = Prefix + Suffix.str();

2297 if (!VFS.exists(LibDir))

2298 continue;

2299 bool GCCDirExists = VFS.exists(LibDir + "/gcc");

2300 bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");

2301 for (StringRef Candidate : CandidateBiarchTripleAliases)

2302 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true,

2303 GCCDirExists, GCCCrossDirExists);

2304 }

2305

2306

2307 if (Version > VersionZero)

2308 break;

2309 }

2310}

2311

2313 for (const auto &InstallPath : CandidateGCCInstallPaths)

2314 OS << "Found candidate GCC installation: " << InstallPath << "\n";

2315

2316 if (!GCCInstallPath.empty())

2317 OS << "Selected GCC installation: " << GCCInstallPath << "\n";

2318

2319 for (const auto &Multilib : Multilibs)

2320 OS << "Candidate multilib: " << Multilib << "\n";

2321

2322 if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())

2323 OS << "Selected multilib: " << SelectedMultilib << "\n";

2324}

2325

2327 if (BiarchSibling) {

2328 M = *BiarchSibling;

2329 return true;

2330 }

2331 return false;

2332}

2333

2334void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(

2336 StringRef SysRoot) {

2337

2338 if (TargetTriple.isOSHaiku()) {

2339 Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools"));

2340 return;

2341 }

2342

2343 if (TargetTriple.isOSSolaris()) {

2344

2345

2346

2347

2348

2349

2351 std::string PrefixDir = concat(SysRoot, "/usr/gcc");

2352 std::error_code EC;

2353 for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),

2354 LE;

2355 !EC && LI != LE; LI = LI.increment(EC)) {

2356 StringRef VersionText = llvm::sys::path::filename(LI->path());

2357 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);

2358

2359

2360 if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1))

2361 continue;

2362

2363 std::string CandidatePrefix = PrefixDir + "/" + VersionText.str();

2364 std::string CandidateLibPath = CandidatePrefix + "/lib/gcc";

2365 if (D.getVFS().exists(CandidateLibPath))

2366 continue;

2367

2368 SolarisPrefixes.emplace_back(

2369 std::make_pair(CandidateVersion, CandidatePrefix));

2370 }

2371

2372 std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend());

2373 for (auto p : SolarisPrefixes)

2374 Prefixes.emplace_back(p.second);

2375 return;

2376 }

2377

2378

2379

2380 if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&

2381 D.getVFS().exists("/opt/rh")) {

2382

2383

2384 Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr");

2385 Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");

2386 Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");

2387 Prefixes.push_back("/opt/rh/devtoolset-12/root/usr");

2388 Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");

2389 Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");

2390 Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");

2391 Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");

2392 Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");

2393 Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");

2394 Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");

2395 Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");

2396 Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");

2397 }

2398

2399

2400 Prefixes.push_back(concat(SysRoot, "/usr"));

2401}

2402

2403 void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(

2404 const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,

2409

2410

2411

2412

2413

2414

2415

2416

2417

2418 static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};

2419 static const char *const AArch64Triples[] = {

2420 "aarch64-none-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux"};

2421 static const char *const AArch64beLibDirs[] = {"/lib"};

2422 static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu"};

2423

2424 static const char *const ARMLibDirs[] = {"/lib"};

2425 static const char *const ARMTriples[] = {"arm-linux-gnueabi"};

2426 static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",

2427 "armv7hl-redhat-linux-gnueabi",

2428 "armv6hl-suse-linux-gnueabi",

2429 "armv7hl-suse-linux-gnueabi"};

2430 static const char *const ARMebLibDirs[] = {"/lib"};

2431 static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"};

2432 static const char *const ARMebHFTriples[] = {

2433 "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};

2434

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

2436 static const char *const AVRTriples[] = {"avr"};

2437

2438 static const char *const CSKYLibDirs[] = {"/lib"};

2439 static const char *const CSKYTriples[] = {

2440 "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"};

2441

2442 static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};

2443 static const char *const X86_64Triples[] = {

2444 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",

2445 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",

2446 "x86_64-redhat-linux", "x86_64-suse-linux",

2447 "x86_64-manbo-linux-gnu", "x86_64-slackware-linux",

2448 "x86_64-unknown-linux", "x86_64-amazon-linux"};

2449 static const char *const X32Triples[] = {"x86_64-linux-gnux32",

2450 "x86_64-pc-linux-gnux32"};

2451 static const char *const X32LibDirs[] = {"/libx32", "/lib"};

2452 static const char *const X86LibDirs[] = {"/lib32", "/lib"};

2453 static const char *const X86Triples[] = {

2454 "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",

2455 "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",

2456 "i586-suse-linux", "i686-montavista-linux",

2457 };

2458

2459 static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"};

2460 static const char *const LoongArch64Triples[] = {

2461 "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"};

2462

2463 static const char *const M68kLibDirs[] = {"/lib"};

2464 static const char *const M68kTriples[] = {"m68k-unknown-linux-gnu",

2465 "m68k-suse-linux"};

2466

2467 static const char *const MIPSLibDirs[] = {"/libo32", "/lib"};

2468 static const char *const MIPSTriples[] = {

2469 "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu",

2470 "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"};

2471 static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"};

2472 static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",

2473 "mips-img-linux-gnu"};

2474

2475 static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};

2476 static const char *const MIPS64Triples[] = {

2477 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64-linux-gnuabi64",

2478 "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"};

2479 static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};

2480 static const char *const MIPS64ELTriples[] = {

2481 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64el-linux-gnuabi64",

2482 "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"};

2483

2484 static const char *const MIPSN32LibDirs[] = {"/lib32"};

2485 static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32",

2486 "mipsisa64r6-linux-gnuabin32"};

2487 static const char *const MIPSN32ELLibDirs[] = {"/lib32"};

2488 static const char *const MIPSN32ELTriples[] = {

2489 "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};

2490

2491 static const char *const MSP430LibDirs[] = {"/lib"};

2492 static const char *const MSP430Triples[] = {"msp430-elf"};

2493

2494 static const char *const PPCLibDirs[] = {"/lib32", "/lib"};

2495 static const char *const PPCTriples[] = {

2496 "powerpc-unknown-linux-gnu",

2497

2498

2499 "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};

2500 static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};

2501 static const char *const PPCLETriples[] = {"powerpcle-unknown-linux-gnu",

2502 "powerpcle-linux-musl"};

2503

2504 static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};

2505 static const char *const PPC64Triples[] = {"powerpc64-unknown-linux-gnu",

2506 "powerpc64-suse-linux",

2507 "ppc64-redhat-linux"};

2508 static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};

2509 static const char *const PPC64LETriples[] = {

2510 "powerpc64le-unknown-linux-gnu", "powerpc64le-none-linux-gnu",

2511 "powerpc64le-suse-linux", "ppc64le-redhat-linux"};

2512

2513 static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};

2514 static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",

2515 "riscv32-unknown-elf"};

2516 static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};

2517 static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",

2518 "riscv64-unknown-elf"};

2519

2520 static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};

2521 static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",

2522 "sparcv8-linux-gnu"};

2523 static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};

2524 static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",

2525 "sparcv9-linux-gnu"};

2526

2527 static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};

2528 static const char *const SystemZTriples[] = {

2529 "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", "s390x-suse-linux",

2530 "s390x-redhat-linux"};

2531

2532 using std::begin;

2533 using std::end;

2534

2535 if (TargetTriple.isOSSolaris()) {

2536 static const char *const SolarisLibDirs[] = {"/lib"};

2537 static const char *const SolarisSparcV8Triples[] = {

2538 "sparc-sun-solaris2.11"};

2539 static const char *const SolarisSparcV9Triples[] = {

2540 "sparcv9-sun-solaris2.11"};

2541 static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"};

2542 static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"};

2543 LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));

2544 BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));

2545 switch (TargetTriple.getArch()) {

2546 case llvm::Triple::x86:

2547 TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples));

2548 BiarchTripleAliases.append(begin(SolarisX86_64Triples),

2549 end(SolarisX86_64Triples));

2550 break;

2551 case llvm::Triple::x86_64:

2552 TripleAliases.append(begin(SolarisX86_64Triples),

2553 end(SolarisX86_64Triples));

2554 BiarchTripleAliases.append(begin(SolarisX86Triples),

2555 end(SolarisX86Triples));

2556 break;

2557 case llvm::Triple::sparc:

2558 TripleAliases.append(begin(SolarisSparcV8Triples),

2559 end(SolarisSparcV8Triples));

2560 BiarchTripleAliases.append(begin(SolarisSparcV9Triples),

2561 end(SolarisSparcV9Triples));

2562 break;

2563 case llvm::Triple::sparcv9:

2564 TripleAliases.append(begin(SolarisSparcV9Triples),

2565 end(SolarisSparcV9Triples));

2566 BiarchTripleAliases.append(begin(SolarisSparcV8Triples),

2567 end(SolarisSparcV8Triples));

2568 break;

2569 default:

2570 break;

2571 }

2572 return;

2573 }

2574

2575

2576 if (TargetTriple.isAndroid()) {

2577 static const char *const AArch64AndroidTriples[] = {

2578 "aarch64-linux-android"};

2579 static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"};

2580 static const char *const X86AndroidTriples[] = {"i686-linux-android"};

2581 static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"};

2582

2583 switch (TargetTriple.getArch()) {

2584 case llvm::Triple::aarch64:

2585 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2586 TripleAliases.append(begin(AArch64AndroidTriples),

2587 end(AArch64AndroidTriples));

2588 break;

2589 case llvm::Triple::arm:

2590 case llvm::Triple::thumb:

2591 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));

2592 TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples));

2593 break;

2594 case llvm::Triple::x86_64:

2595 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2596 TripleAliases.append(begin(X86_64AndroidTriples),

2597 end(X86_64AndroidTriples));

2598 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2599 BiarchTripleAliases.append(begin(X86AndroidTriples),

2600 end(X86AndroidTriples));

2601 break;

2602 case llvm::Triple::x86:

2603 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2604 TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples));

2605 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2606 BiarchTripleAliases.append(begin(X86_64AndroidTriples),

2607 end(X86_64AndroidTriples));

2608 break;

2609 default:

2610 break;

2611 }

2612

2613 return;

2614 }

2615

2616 if (TargetTriple.isOSHurd()) {

2617 switch (TargetTriple.getArch()) {

2618 case llvm::Triple::x86_64:

2619 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2620 TripleAliases.push_back("x86_64-gnu");

2621 break;

2622 case llvm::Triple::x86:

2623 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2624 TripleAliases.push_back("i686-gnu");

2625 break;

2626 default:

2627 break;

2628 }

2629

2630 return;

2631 }

2632

2633 switch (TargetTriple.getArch()) {

2634 case llvm::Triple::aarch64:

2635 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2636 TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));

2637 BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2638 BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));

2639 break;

2640 case llvm::Triple::aarch64_be:

2641 LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));

2642 TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));

2643 BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));

2644 BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));

2645 break;

2646 case llvm::Triple::arm:

2647 case llvm::Triple::thumb:

2648 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));

2649 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||

2650 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||

2651 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||

2652 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {

2653 TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));

2654 } else {

2655 TripleAliases.append(begin(ARMTriples), end(ARMTriples));

2656 }

2657 break;

2658 case llvm::Triple::armeb:

2659 case llvm::Triple::thumbeb:

2660 LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));

2661 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||

2662 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||

2663 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||

2664 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {

2665 TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));

2666 } else {

2667 TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));

2668 }

2669 break;

2670 case llvm::Triple::avr:

2671 LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs));

2672 TripleAliases.append(begin(AVRTriples), end(AVRTriples));

2673 break;

2674 case llvm::Triple::csky:

2675 LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs));

2676 TripleAliases.append(begin(CSKYTriples), end(CSKYTriples));

2677 break;

2678 case llvm::Triple::x86_64:

2679 if (TargetTriple.isX32()) {

2680 LibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2681 TripleAliases.append(begin(X32Triples), end(X32Triples));

2682 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2683 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2684 } else {

2685 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2686 TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2687 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2688 BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));

2689 }

2690 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2691 BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));

2692 break;

2693 case llvm::Triple::x86:

2694 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2695

2696

2697 if (!TargetTriple.isOSIAMCU()) {

2698 TripleAliases.append(begin(X86Triples), end(X86Triples));

2699 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2700 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2701 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2702 BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));

2703 }

2704 break;

2705

2706 case llvm::Triple::loongarch64:

2707 LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs));

2708 TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples));

2709 break;

2710 case llvm::Triple::m68k:

2711 LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs));

2712 TripleAliases.append(begin(M68kTriples), end(M68kTriples));

2713 break;

2714 case llvm::Triple::mips:

2715 LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));

2716 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2717 BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));

2718 BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));

2719 BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));

2720 BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));

2721 break;

2722 case llvm::Triple::mipsel:

2723 LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));

2724 TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));

2725 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2726 BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));

2727 BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));

2728 BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));

2729 BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));

2730 break;

2731 case llvm::Triple::mips64:

2732 LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));

2733 TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));

2734 BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));

2735 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2736 BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));

2737 BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));

2738 break;

2739 case llvm::Triple::mips64el:

2740 LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));

2741 TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));

2742 BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));

2743 BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));

2744 BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));

2745 BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));

2746 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2747 break;

2748 case llvm::Triple::msp430:

2749 LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs));

2750 TripleAliases.append(begin(MSP430Triples), end(MSP430Triples));

2751 break;

2752 case llvm::Triple::ppc:

2753 LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));

2754 TripleAliases.append(begin(PPCTriples), end(PPCTriples));

2755 BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));

2756 BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));

2757 break;

2758 case llvm::Triple::ppcle:

2759 LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));

2760 TripleAliases.append(begin(PPCLETriples), end(PPCLETriples));

2761 BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));

2762 BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));

2763 break;

2764 case llvm::Triple::ppc64:

2765 LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));

2766 TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));

2767 BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));

2768 BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));

2769 break;

2770 case llvm::Triple::ppc64le:

2771 LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));

2772 TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));

2773 BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));

2774 BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples));

2775 break;

2776 case llvm::Triple::riscv32:

2777 LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));

2778 TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));

2779 BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));

2780 BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));

2781 break;

2782 case llvm::Triple::riscv64:

2783 LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));

2784 TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));

2785 BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));

2786 BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));

2787 break;

2788 case llvm::Triple::sparc:

2789 case llvm::Triple::sparcel:

2790 LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));

2791 TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));

2792 BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));

2793 BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));

2794 break;

2795 case llvm::Triple::sparcv9:

2796 LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));

2797 TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));

2798 BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));

2799 BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));

2800 break;

2801 case llvm::Triple::systemz:

2802 LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));

2803 TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));

2804 break;

2805 default:

2806

2807

2808 break;

2809 }

2810

2811

2812 if (TargetTriple.str() != BiarchTriple.str())

2813 BiarchTripleAliases.push_back(BiarchTriple.str());

2814}

2815

2816bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(

2817 const llvm::Triple &TargetTriple, const ArgList &Args,

2818 StringRef Path, bool NeedsBiarchSuffix) {

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

2821

2822

2823

2824

2825 if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {

2826

2828 } else if (TargetTriple.isCSKY()) {

2830 } else if (TargetTriple.isMIPS()) {

2832 return false;

2833 } else if (TargetTriple.isRISCV()) {

2835 } else if (isMSP430(TargetArch)) {

2837 } else if (TargetArch == llvm::Triple::avr) {

2838

2840 NeedsBiarchSuffix, Detected)) {

2841 return false;

2842 }

2843

2847 : Detected.SelectedMultilibs.back();

2849

2850 return true;

2851}

2852

2853void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(

2854 const llvm::Triple &TargetTriple, const ArgList &Args,

2855 const std::string &LibDir, StringRef CandidateTriple,

2856 bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) {

2857

2858

2859 struct GCCLibSuffix {

2860

2861 std::string LibSuffix;

2862

2863

2864 StringRef ReversePath;

2865

2866 bool Active;

2868

2869 {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists},

2870

2871

2872 {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists},

2873

2874

2875

2876

2877

2878 {CandidateTriple.str(), "..",

2879 TargetTriple.getVendor() == llvm::Triple::Freescale ||

2880 TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};

2881

2882 for (auto &Suffix : Suffixes) {

2883 if (!Suffix.Active)

2884 continue;

2885

2886 StringRef LibSuffix = Suffix.LibSuffix;

2887 std::error_code EC;

2888 for (llvm::vfs::directory_iterator

2889 LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),

2890 LE;

2891 !EC && LI != LE; LI = LI.increment(EC)) {

2892 StringRef VersionText = llvm::sys::path::filename(LI->path());

2893 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);

2894 if (CandidateVersion.Major != -1)

2895 if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second)

2896 continue;

2897 if (CandidateVersion.isOlderThan(4, 1, 1))

2898 continue;

2899 if (CandidateVersion <= Version)

2900 continue;

2901

2902 if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),

2903 NeedsBiarchSuffix))

2904 continue;

2905

2906 Version = CandidateVersion;

2907 GCCTriple.setTriple(CandidateTriple);

2908

2909

2910

2911 GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();

2912 GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();

2913 IsValid = true;

2914 }

2915 }

2916}

2917

2918bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(

2919 const llvm::Triple &TargetTriple, const ArgList &Args,

2922 if (D.getVFS().exists(concat(D.SysRoot, GentooConfigDir)))

2923 return false;

2924

2925 for (StringRef CandidateTriple : CandidateTriples) {

2926 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))

2927 return true;

2928 }

2929

2930 for (StringRef CandidateTriple : CandidateBiarchTriples) {

2931 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))

2932 return true;

2933 }

2934 return false;

2935}

2936

2937bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(

2938 const llvm::Triple &TargetTriple, const ArgList &Args,

2939 StringRef CandidateTriple, bool NeedsBiarchSuffix) {

2940 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> File =

2941 D.getVFS().getBufferForFile(concat(D.SysRoot, GentooConfigDir,

2942 "/config-" + CandidateTriple.str()));

2945 File.get()->getBuffer().split(Lines, "\n");

2946 for (StringRef Line : Lines) {

2948

2949 if (Line.consume_front("CURRENT="))

2950 continue;

2951

2952 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> ConfigFile =

2953 D.getVFS().getBufferForFile(

2954 concat(D.SysRoot, GentooConfigDir, "/" + Line));

2955 std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-');

2956

2958

2959

2960

2961

2962

2963

2964

2965

2966 if (ConfigFile) {

2968 ConfigFile.get()->getBuffer().split(ConfigLines, "\n");

2969 for (StringRef ConfLine : ConfigLines) {

2970 ConfLine = ConfLine.trim();

2971 if (ConfLine.consume_front("LDPATH=")) {

2972

2973 ConfLine.consume_back("\"");

2974 ConfLine.consume_front("\"");

2975

2976 ConfLine.split(GentooScanPaths, ':', -1, false);

2977 }

2978 }

2979 }

2980

2981 std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/"

2982 + ActiveVersion.second.str();

2983 GentooScanPaths.push_back(StringRef(basePath));

2984

2985

2986 for (const auto &GentooScanPath : GentooScanPaths) {

2987 std::string GentooPath = concat(D.SysRoot, GentooScanPath);

2988 if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {

2989 if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,

2990 NeedsBiarchSuffix))

2991 continue;

2992

2993 Version = GCCVersion::Parse(ActiveVersion.second);

2994 GCCInstallPath = GentooPath;

2995 GCCParentLibPath = GentooPath + std::string("/../../..");

2996 GCCTriple.setTriple(ActiveVersion.first);

2997 IsValid = true;

2998 return true;

2999 }

3000 }

3001 }

3002 }

3003

3004 return false;

3005}

3006

3008 const ArgList &Args)

3009 : ToolChain(D, Triple, Args), GCCInstallation(D),

3010 CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args),

3011 SYCLInstallation(D, Triple, Args) {

3013}

3014

3016

3018 switch (AC) {

3020 if (!Preprocess)

3022 return Preprocess.get();

3024 if (!Compile)

3026 return Compile.get();

3027 default:

3029 }

3030}

3031

3034}

3035

3037

3039

3043}

3044

3048 case llvm::Triple::aarch64:

3049 case llvm::Triple::aarch64_be:

3050 case llvm::Triple::ppc:

3051 case llvm::Triple::ppcle:

3052 case llvm::Triple::ppc64:

3053 case llvm::Triple::ppc64le:

3054 case llvm::Triple::riscv32:

3055 case llvm::Triple::riscv64:

3056 case llvm::Triple::x86:

3057 case llvm::Triple::x86_64:

3059 default:

3061 }

3062}

3063

3066 case llvm::Triple::x86_64:

3067 return getTriple().isOSWindows();

3068 case llvm::Triple::mips64:

3069 case llvm::Triple::mips64el:

3070 return true;

3071 default:

3072 return false;

3073 }

3074}

3075

3077 return false;

3078}

3079

3081 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();

3082}

3083

3086 case llvm::Triple::nvptx:

3087 case llvm::Triple::nvptx64:

3088 case llvm::Triple::xcore:

3089 return false;

3090 default:

3091 return true;

3092 }

3093}

3094

3096

3097

3098

3099

3100

3101

3102

3106 .str());

3107 }

3108}

3109

3111 const std::string &SysRoot,

3112 const std::string &OSLibDir,

3113 const std::string &MultiarchTriple,

3115

3119 const std::string &LibPath =

3121

3122

3123

3127

3128

3129 addPathIfExists(D,

3132 Paths);

3133

3134

3135

3137 Paths);

3138

3139

3140

3141

3142

3143

3144

3145

3146

3147

3148

3149

3150

3151

3152

3153

3154

3155

3156

3157 addPathIfExists(D,

3158 LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +

3160 Paths);

3161

3162

3163

3164

3165

3166

3167

3168

3169

3170

3171 if (StringRef(LibPath).starts_with(SysRoot))

3172 addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);

3173 }

3174}

3175

3177 const std::string &SysRoot,

3178 const std::string &OSLibDir,

3181 const std::string &LibPath =

3185 addPathIfExists(

3186 D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(),

3187 Paths);

3188 }

3189}

3190

3192 ArgStringList &CC1Args) const {

3193

3195 return;

3196

3200 Twine(LibPath) + "/../" + GCCTriple.str() + "/include");

3201

3203 if (Callback) {

3207 }

3208}

3209

3211 ArgStringList &CC1Args) const {

3212 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,

3213 options::OPT_nostdlibinc))

3214 return;

3215

3219 break;

3220

3223 break;

3224 }

3225}

3226

3228 ArgStringList &CC1Args) const {

3230}

3231

3232void

3234 llvm::opt::ArgStringList &CC1Args) const {

3237 if (SysRoot.empty())

3238 SysRoot = llvm::sys::path::get_separator();

3239

3240 auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {

3242 if (Version.empty())

3243 return false;

3244

3245

3246 bool TargetDirExists = false;

3248 if (TargetIncludeDir) {

3250 llvm::sys::path::append(TargetDir, "c++", Version);

3251 if (D.getVFS().exists(TargetDir)) {

3253 TargetDirExists = true;

3254 }

3255 }

3256 if (TargetDirRequired && !TargetDirExists)

3257 return false;

3258

3259

3261 llvm::sys::path::append(GenericDir, "c++", Version);

3263 return true;

3264 };

3265

3266

3267

3268

3270 llvm::sys::path::append(DriverIncludeDir, "..", "include");

3271 if (AddIncludePath(DriverIncludeDir,

3272 getTriple().isAndroid()))

3273 return;

3274

3275

3276

3278 llvm::sys::path::append(UsrLocalIncludeDir, "usr", "local", "include");

3279 if (AddIncludePath(UsrLocalIncludeDir))

3280 return;

3282 llvm::sys::path::append(UsrIncludeDir, "usr", "include");

3283 if (AddIncludePath(UsrIncludeDir))

3284 return;

3285}

3286

3288 Twine IncludeSuffix,

3289 const llvm::opt::ArgList &DriverArgs,

3290 llvm::opt::ArgStringList &CC1Args,

3291 bool DetectDebian) const {

3292 if (getVFS().exists(IncludeDir))

3293 return false;

3294

3295

3296

3297

3298 std::string Dir = IncludeDir.str();

3299 StringRef Include =

3300 llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir));

3301 std::string Path =

3302 (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix)

3303 .str();

3304 if (DetectDebian && getVFS().exists(Path))

3305 return false;

3306

3307

3309

3310

3311 if (DetectDebian)

3313 else if (!Triple.empty())

3315 IncludeDir + "/" + Triple + IncludeSuffix);

3316

3317 addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");

3318 return true;

3319}

3320

3322 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,

3323 StringRef DebianMultiarch) const {

3325

3326

3327

3328

3334

3335

3337 LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,

3339 return true;

3340

3341

3342

3343

3345 Version.Text + "/include/c++/",

3347 CC1Args))

3348 return true;

3349

3350

3353 DriverArgs, CC1Args, true))

3354 return true;

3355

3356

3359 CC1Args))

3360 return true;

3361

3362

3363

3364 const std::string LibStdCXXIncludePathCandidates[] = {

3365

3366

3367 InstallDir.str() + "/include/g++-v" + Version.Text,

3368 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +

3370 InstallDir.str() + "/include/g++-v" + Version.MajorStr,

3371 };

3372

3373 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {

3376 return true;

3377 }

3378 return false;

3379}

3380

3381void

3383 llvm::opt::ArgStringList &CC1Args) const {

3387 }

3388}

3389

3390llvm::opt::DerivedArgList *

3393

3394

3395

3396

3397

3399 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());

3401

3402

3403

3404 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_shared));

3405 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_fPIC));

3406

3407

3408

3409 for (auto *A : Args) {

3410 switch ((options::ID)A->getOption().getID()) {

3411 default:

3412 DAL->append(A);

3413 break;

3414 case options::OPT_shared:

3415 case options::OPT_dynamic:

3416 case options::OPT_static:

3417 case options::OPT_fPIC:

3418 case options::OPT_fno_PIC:

3419 case options::OPT_fpic:

3420 case options::OPT_fno_pic:

3421 case options::OPT_fPIE:

3422 case options::OPT_fno_PIE:

3423 case options::OPT_fpie:

3424 case options::OPT_fno_pie:

3425 break;

3426 }

3427 }

3428 return DAL;

3429 }

3430 return nullptr;

3431}

3432

3433void Generic_ELF::anchor() {}

3434

3436 ArgStringList &CC1Args,

3438 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,

3439 options::OPT_fno_use_init_array, true))

3440 CC1Args.push_back("-fno-use-init-array");

3441}

static constexpr CPUSuffix Suffixes[]

static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static void findAndroidArmMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool findMipsCsMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool isArmOrThumbArch(llvm::Triple::ArchType Arch)

static bool selectRISCVMultilib(const Driver &D, const MultilibSet &RISCVMultilibSet, StringRef Arch, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &SelectedMultilibs)

Extend the multi-lib re-use selection mechanism for RISC-V.

static void normalizeCPUNamesForAssembler(const ArgList &Args, ArgStringList &CmdArgs)

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

static bool isMips16(const ArgList &Args)

static llvm::StringRef getGCCToolchainDir(const ArgList &Args, llvm::StringRef SysRoot)

static bool findMSP430Multilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool getStatic(const ArgList &Args)

static bool isMipsEL(llvm::Triple::ArchType Arch)

static const char * getLDMOption(const llvm::Triple &T, const ArgList &Args)

static bool findMipsMuslMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static void findRISCVBareMetalMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool isMSP430(llvm::Triple::ArchType Arch)

static bool isSoftFloatABI(const ArgList &Args)

static bool getStaticPIE(const ArgList &Args, const ToolChain &TC)

static bool findMipsImgMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool forwardToGCC(const Option &O)

static bool findMipsMtiMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool isMicroMips(const ArgList &Args)

types::ID getType() const

bool isHostOffloading(unsigned int OKind) const

Check if this action have any offload kinds.

Compilation - A set of tasks to perform for a single driver invocation.

Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...

const llvm::opt::OptTable & getOpts() const

InputInfo - Wrapper for information about an input source.

const char * getFilename() const

This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.

MultilibBuilder & flag(StringRef Flag, bool Disallow=false)

Add a flag to the flags list Flag must be a flag accepted by the driver.

const std::string & gccSuffix() const

Get the detected GCC installation path suffix for the multi-arch target variant.

const std::string & osSuffix() const

Get the detected os path suffix for the multi-arch target variant.

Multilib makeMultilib() const

This class can be used to create a MultilibSet, and contains helper functions to add combinations of ...

MultilibSetBuilder & Maybe(const MultilibBuilder &M)

Add an optional Multilib segment.

MultilibSetBuilder & FilterOut(const char *Regex)

Filter out those Multilibs whose gccSuffix matches the given expression.

MultilibSetBuilder & Either(const MultilibBuilder &M1, const MultilibBuilder &M2)

Add a set of mutually incompatible Multilib segments.

MultilibSet makeMultilibSet() const

See also MultilibSetBuilder for combining multilibs into a set.

bool select(const Driver &D, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &, llvm::SmallVector< StringRef > *=nullptr) const

Select compatible variants,.

MultilibSet & setFilePathsCallback(IncludeDirsFunc F)

MultilibSet & FilterOut(FilterCallback F)

Filter out some subset of the Multilibs using a user defined callback.

const IncludeDirsFunc & filePathsCallback() const

const IncludeDirsFunc & includeDirsCallback() const

MultilibSet & setIncludeDirsCallback(IncludeDirsFunc F)

This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.

const std::string & gccSuffix() const

Get the detected GCC installation path suffix for the multi-arch target variant.

const std::string & osSuffix() const

Get the detected os path suffix for the multi-arch target variant.

std::vector< std::string > flags_list

const std::string & includeSuffix() const

Get the include directory suffix.

bool isDefault() const

Check whether the default is selected.

bool isLLVMIR(ID Id)

Is this LLVM IR.

const char * getTypeName(ID Id)

getTypeName - Return the name of the type for Id.

bool canTypeBeUserSpecified(ID Id)

canTypeBeUserSpecified - Can this type be specified on the command line (by the type name); this is u...

bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const llvm::opt::ArgList &Args, DetectedMultilibs &Result)

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

const FunctionProtoType * T

MultilibSet Multilibs

The set of multilibs that the detected installation supports.

std::optional< Multilib > BiarchSibling

On Biarch systems, this corresponds to the default multilib when targeting the non-default multilib.

llvm::SmallVector< Multilib > SelectedMultilibs

The multilibs appropriate for the given flags.

static constexpr ResponseFileSupport AtFileCurCP()