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

1

2

3

4

5

6

7

8

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

27#include "llvm/ADT/SmallString.h"

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

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

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

31#include "llvm/Config/llvm-config.h"

32#include "llvm/MC/MCTargetOptions.h"

33#include "llvm/MC/TargetRegistry.h"

34#include "llvm/Option/Arg.h"

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

36#include "llvm/Option/OptTable.h"

37#include "llvm/Option/Option.h"

38#include "llvm/Support/ErrorHandling.h"

39#include "llvm/Support/FileSystem.h"

40#include "llvm/Support/FileUtilities.h"

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

42#include "llvm/Support/Process.h"

43#include "llvm/Support/VersionTuple.h"

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

45#include "llvm/TargetParser/AArch64TargetParser.h"

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

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

48#include "llvm/TargetParser/Triple.h"

49#include

50#include

51#include

52#include

53

54using namespace clang;

55using namespace driver;

56using namespace tools;

57using namespace llvm;

59

61 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,

62 options::OPT_fno_rtti, options::OPT_frtti);

63}

64

66 const llvm::Triple &Triple,

67 const Arg *CachedRTTIArg) {

68

69 if (CachedRTTIArg) {

70 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))

72 else

74 }

75

76

77 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();

79}

80

82 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,

83 true)) {

85 }

87}

88

90 const ArgList &Args)

94 auto addIfExists = [this](path_list &List, const std::string &Path) {

96 List.push_back(Path);

97 };

98

105}

106

110 llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile,

111 llvm::sys::fs::OF_Text);

112 llvm::FileRemover OutputRemover(OutputFile.c_str());

113 std::optionalllvm::StringRef Redirects[] = {

114 {""},

115 OutputFile.str(),

116 {""},

117 };

118

119 std::string ErrorMessage;

120 int SecondsToWait = 60;

121 if (std::optionalstd::string Str =

122 llvm::sys::Process::GetEnv("CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {

123 if (!llvm::to_integer(*Str, SecondsToWait))

124 return llvm::createStringError(std::error_code(),

125 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "

126 "an integer, got '" +

127 *Str + "'");

128 SecondsToWait = std::max(SecondsToWait, 0);

129 }

130 if (llvm::sys::ExecuteAndWait(Executable, {Executable}, {}, Redirects,

131 SecondsToWait,

132 0, &ErrorMessage))

133 return llvm::createStringError(std::error_code(),

134 Executable + ": " + ErrorMessage);

135

136 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> OutputBuf =

137 llvm::MemoryBuffer::getFile(OutputFile.c_str());

138 if (!OutputBuf)

139 return llvm::createStringError(OutputBuf.getError(),

140 "Failed to read stdout of " + Executable +

141 ": " + OutputBuf.getError().message());

142 return std::move(*OutputBuf);

143}

144

146 Triple.setEnvironment(Env);

147 if (EffectiveTriple != llvm::Triple())

148 EffectiveTriple.setEnvironment(Env);

149}

150

152

155}

156

158 return Args.hasFlag(options::OPT_fintegrated_as,

159 options::OPT_fno_integrated_as,

161}

162

164 assert(

167 "(Non-)integrated backend set incorrectly!");

168

169 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,

170 options::OPT_fno_integrated_objemitter,

172

173

174

175 unsigned DiagID;

178 DiagID = clang::diag::err_drv_unsupported_opt_for_target;

179 else

180 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;

181 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);

183 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();

184 A = Args.getLastArg(options::OPT_fintegrated_objemitter);

186 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();

187

188 return IBackend;

189}

190

192 return ENABLE_X86_RELAX_RELOCATIONS;

193}

194

196 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();

197}

198

200 const llvm::opt::ArgList &Args) {

201 for (const Arg *MultilibFlagArg :

202 Args.filtered(options::OPT_fmultilib_flag)) {

203 List.push_back(MultilibFlagArg->getAsString(Args));

204 MultilibFlagArg->claim();

205 }

206}

207

209 const llvm::Triple &Triple,

210 const llvm::opt::ArgList &Args,

212 std::vector Features;

215 llvm::DenseSet FeatureSet(UnifiedFeatures.begin(),

216 UnifiedFeatures.end());

217 std::vectorstd::string MArch;

218 for (const auto &Ext : AArch64::Extensions)

219 if (!Ext.UserVisibleName.empty())

220 if (FeatureSet.contains(Ext.PosTargetFeature))

221 MArch.push_back(Ext.UserVisibleName.str());

222 for (const auto &Ext : AArch64::Extensions)

223 if (!Ext.UserVisibleName.empty())

224 if (FeatureSet.contains(Ext.NegTargetFeature))

225 MArch.push_back(("no" + Ext.UserVisibleName).str());

226 StringRef ArchName;

227 for (const auto &ArchInfo : AArch64::ArchInfos)

228 if (FeatureSet.contains(ArchInfo->ArchFeature))

229 ArchName = ArchInfo->Name;

230 assert(!ArchName.empty() && "at least one architecture should be found");

231 MArch.insert(MArch.begin(), ("-march=" + ArchName).str());

232 Result.push_back(llvm::join(MArch, "+"));

233

234 const Arg *BranchProtectionArg =

235 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);

236 if (BranchProtectionArg) {

237 Result.push_back(BranchProtectionArg->getAsString(Args));

238 }

239

240 if (Arg *AlignArg = Args.getLastArg(

241 options::OPT_mstrict_align, options::OPT_mno_strict_align,

242 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {

243 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||

244 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))

245 Result.push_back(AlignArg->getAsString(Args));

246 }

247

248 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,

249 options::OPT_mlittle_endian)) {

250 if (Endian->getOption().matches(options::OPT_mbig_endian))

251 Result.push_back(Endian->getAsString(Args));

252 }

253

254 const Arg *ABIArg = Args.getLastArgNoClaim(options::OPT_mabi_EQ);

255 if (ABIArg) {

256 Result.push_back(ABIArg->getAsString(Args));

257 }

258

260}

261

263 const llvm::Triple &Triple,

264 const llvm::opt::ArgList &Args,

266 std::vector Features;

268 D, Triple, Args, Features, false , true );

270 llvm::DenseSet FeatureSet(UnifiedFeatures.begin(),

271 UnifiedFeatures.end());

272 std::vectorstd::string MArch;

273 for (const auto &Ext : ARM::ARCHExtNames)

274 if (!Ext.Name.empty())

275 if (FeatureSet.contains(Ext.Feature))

276 MArch.push_back(Ext.Name.str());

277 for (const auto &Ext : ARM::ARCHExtNames)

278 if (!Ext.Name.empty())

279 if (FeatureSet.contains(Ext.NegFeature))

280 MArch.push_back(("no" + Ext.Name).str());

281 MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());

282 Result.push_back(llvm::join(MArch, "+"));

283

284 switch (FPUKind) {

285#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \

286 case llvm::ARM::KIND: \

287 Result.push_back("-mfpu=" NAME); \

288 break;

289#include "llvm/TargetParser/ARMTargetParser.def"

290 default:

291 llvm_unreachable("Invalid FPUKind");

292 }

293

295 case arm::FloatABI::Soft:

296 Result.push_back("-mfloat-abi=soft");

297 break;

298 case arm::FloatABI::SoftFP:

299 Result.push_back("-mfloat-abi=softfp");

300 break;

301 case arm::FloatABI::Hard:

302 Result.push_back("-mfloat-abi=hard");

303 break;

304 case arm::FloatABI::Invalid:

305 llvm_unreachable("Invalid float ABI");

306 }

307

308 const Arg *BranchProtectionArg =

309 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);

310 if (BranchProtectionArg) {

311 Result.push_back(BranchProtectionArg->getAsString(Args));

312 }

313

314 if (Arg *AlignArg = Args.getLastArg(

315 options::OPT_mstrict_align, options::OPT_mno_strict_align,

316 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {

317 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||

318 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))

319 Result.push_back(AlignArg->getAsString(Args));

320 }

321

322 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,

323 options::OPT_mlittle_endian)) {

324 if (Endian->getOption().matches(options::OPT_mbig_endian))

325 Result.push_back(Endian->getAsString(Args));

326 }

328}

329

331 const llvm::opt::ArgList &Args,

334

335 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(

336 Arch, true);

337 if (!llvm::errorToBool(ISAInfo.takeError()))

338 Result.push_back("-march=" + (*ISAInfo)->toString());

339

341}

342

346

347 std::vectorstd::string Result;

349 Result.push_back("--target=" + Triple.str());

350

351 switch (Triple.getArch()) {

352 case llvm::Triple::aarch64:

353 case llvm::Triple::aarch64_32:

354 case llvm::Triple::aarch64_be:

356 break;

357 case llvm::Triple::arm:

358 case llvm::Triple::armeb:

359 case llvm::Triple::thumb:

360 case llvm::Triple::thumbeb:

362 break;

363 case llvm::Triple::riscv32:

364 case llvm::Triple::riscv64:

366 break;

367 default:

368 break;

369 }

370

371

372

374 Result.push_back("-fno-rtti");

375 else

376 Result.push_back("-frtti");

377

379 Result.push_back("-fno-exceptions");

380 else

381 Result.push_back("-fexceptions");

382

383

387}

388

391 SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);

392 SanitizerArgsChecked = true;

393 return SanArgs;

394}

395

397 if (!XRayArguments)

398 XRayArguments.reset(new XRayArgs(*this, Args));

399 return *XRayArguments;

400}

401

402namespace {

403

404struct DriverSuffix {

405 const char *Suffix;

406 const char *ModeFlag;

407};

408

409}

410

411static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {

412

413

414

415 static const DriverSuffix DriverSuffixes[] = {

416 {"clang", nullptr},

417 {"clang++", "--driver-mode=g++"},

418 {"clang-c++", "--driver-mode=g++"},

419 {"clang-cc", nullptr},

420 {"clang-cpp", "--driver-mode=cpp"},

421 {"clang-g++", "--driver-mode=g++"},

422 {"clang-gcc", nullptr},

423 {"clang-cl", "--driver-mode=cl"},

424 {"cc", nullptr},

425 {"cpp", "--driver-mode=cpp"},

426 {"cl", "--driver-mode=cl"},

427 {"++", "--driver-mode=g++"},

428 {"flang", "--driver-mode=flang"},

429

430

431 {"flang-new", "--driver-mode=flang"},

432 {"clang-dxc", "--driver-mode=dxc"},

433 };

434

435 for (const auto &DS : DriverSuffixes) {

436 StringRef Suffix(DS.Suffix);

437 if (ProgName.ends_with(Suffix)) {

438 Pos = ProgName.size() - Suffix.size();

439 return &DS;

440 }

441 }

442 return nullptr;

443}

444

445

446

448 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));

449 if (is_style_windows(llvm::sys::path::Style::native)) {

450

451 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),

452 ::tolower);

453 }

454 return ProgName;

455}

456

457static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {

458

459

460

461

462

463

464

466

467 if (!DS && ProgName.ends_with(".exe")) {

468

469

470 ProgName = ProgName.drop_back(StringRef(".exe").size());

472 }

473

474 if (!DS) {

475

476

477 ProgName = ProgName.rtrim("0123456789.");

479 }

480

481 if (!DS) {

482

483

484 ProgName = ProgName.slice(0, ProgName.rfind('-'));

486 }

487 return DS;

488}

489

493 size_t SuffixPos;

495 if (!DS)

496 return {};

497 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);

498

499 size_t LastComponent = ProgName.rfind('-', SuffixPos);

500 if (LastComponent == std:🧵:npos)

501 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);

502 std::string ModeSuffix = ProgName.substr(LastComponent + 1,

503 SuffixEnd - LastComponent - 1);

504

505

506 StringRef Prefix(ProgName);

507 Prefix = Prefix.slice(0, LastComponent);

508 std::string IgnoredError;

509 bool IsRegistered =

510 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);

511 return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,

512 IsRegistered};

513}

514

516

517

518

519 switch (Triple.getArch()) {

520 case llvm::Triple::aarch64: {

522 return "arm64e";

523 return "arm64";

524 }

525 case llvm::Triple::aarch64_32:

526 return "arm64_32";

527 case llvm::Triple::ppc:

528 return "ppc";

529 case llvm::Triple::ppcle:

530 return "ppcle";

531 case llvm::Triple::ppc64:

532 return "ppc64";

533 case llvm::Triple::ppc64le:

534 return "ppc64le";

535 default:

536 return Triple.getArchName();

537 }

538}

539

542}

543

547}

548

549Tool *ToolChain::getClang() const {

552 return Clang.get();

553}

554

555Tool *ToolChain::getFlang() const {

558 return Flang.get();

559}

560

563}

564

566 llvm_unreachable("Linking is not supported by this toolchain");

567}

568

570 llvm_unreachable("Creating static lib is not supported by this toolchain");

571}

572

573Tool *ToolChain::getAssemble() const {

574 if (!Assemble)

576 return Assemble.get();

577}

578

579Tool *ToolChain::getClangAs() const {

580 if (!Assemble)

582 return Assemble.get();

583}

584

585Tool *ToolChain::getLink() const {

586 if (!Link)

588 return Link.get();

589}

590

591Tool *ToolChain::getStaticLibTool() const {

592 if (!StaticLibTool)

594 return StaticLibTool.get();

595}

596

597Tool *ToolChain::getIfsMerge() const {

598 if (!IfsMerge)

600 return IfsMerge.get();

601}

602

603Tool *ToolChain::getOffloadBundler() const {

607}

608

609Tool *ToolChain::getOffloadPackager() const {

613}

614

615Tool *ToolChain::getLinkerWrapper() const {

619}

620

622 switch (AC) {

624 return getAssemble();

625

627 return getIfsMerge();

628

630 return getLink();

631

633 return getStaticLibTool();

634

642 llvm_unreachable("Invalid tool kind.");

643

652 return getClang();

653

656 return getOffloadBundler();

657

659 return getOffloadPackager();

661 return getLinkerWrapper();

662 }

663

664 llvm_unreachable("Invalid tool kind.");

665}

666

668 const ArgList &Args) {

669 const llvm::Triple &Triple = TC.getTriple();

670 bool IsWindows = Triple.isOSWindows();

671

673 return Triple.getArchName();

674

675 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)

676 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)

677 ? "armhf"

678 : "arm";

679

680

681 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())

682 return "i686";

683

684 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32())

685 return "x32";

686

687 return llvm::Triple::getArchTypeName(TC.getArch());

688}

689

691 if (Triple.isOSDarwin())

692 return "darwin";

693

694 switch (Triple.getOS()) {

695 case llvm::Triple::FreeBSD:

696 return "freebsd";

697 case llvm::Triple::NetBSD:

698 return "netbsd";

699 case llvm::Triple::OpenBSD:

700 return "openbsd";

701 case llvm::Triple::Solaris:

702 return "sunos";

703 case llvm::Triple::AIX:

704 return "aix";

705 default:

707 }

708}

709

716 }

717 } else if (Triple.isOSUnknown()) {

718 llvm::sys::path::append(Path, "lib");

719 } else {

721 }

722 return std::string(Path);

723}

724

726 StringRef Component,

728 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type);

729 return llvm::sys::path::filename(CRTAbsolutePath).str();

730}

731

733 StringRef Component,

735 bool AddArch) const {

736 const llvm::Triple &TT = getTriple();

737 bool IsITANMSVCWindows =

738 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();

739

740 const char *Prefix =

742 const char *Suffix;

743 switch (Type) {

745 Suffix = IsITANMSVCWindows ? ".obj" : ".o";

746 break;

748 Suffix = IsITANMSVCWindows ? ".lib" : ".a";

749 break;

751 Suffix = TT.isOSWindows()

752 ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")

753 : ".so";

754 break;

755 }

756

757 std::string ArchAndEnv;

758 if (AddArch) {

760 const char *Env = TT.isAndroid() ? "-android" : "";

761 ArchAndEnv = ("-" + Arch + Env).str();

762 }

763 return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();

764}

765

768

769 std::string CRTBasename =

774 llvm::sys::path::append(P, CRTBasename);

776 return std::string(P);

777 if (Path.empty())

779 }

781 Path.clear();

782

783

784 CRTBasename =

787 llvm::sys::path::append(OldPath, CRTBasename);

788 if (Path.empty() || getVFS().exists(OldPath))

789 return std::string(OldPath);

790

791

792

793

794 return std::string(Path);

795}

796

798 StringRef Component,

801}

802

803

804

805

806std::optionalstd::string

807ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {

808 llvm::Triple TripleWithoutLevel(getTriple());

809 TripleWithoutLevel.setEnvironmentName("android");

810 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();

811 unsigned TripleVersion = getTriple().getEnvironmentVersion().getMajor();

812 unsigned BestVersion = 0;

813

815 bool UsingUnversionedDir = false;

816 std::error_code EC;

817 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE;

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

819 StringRef DirName = llvm::sys::path::filename(LI->path());

820 StringRef DirNameSuffix = DirName;

821 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {

822 if (DirNameSuffix.empty() && TripleDir.empty()) {

823 TripleDir = DirName;

824 UsingUnversionedDir = true;

825 } else {

826 unsigned Version;

827 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&

828 Version < TripleVersion) {

829 BestVersion = Version;

830 TripleDir = DirName;

831 UsingUnversionedDir = false;

832 }

833 }

834 }

835 }

836

837 if (TripleDir.empty())

838 return {};

839

841 llvm::sys::path::append(P, TripleDir);

842 if (UsingUnversionedDir)

844 return std::string(P);

845}

846

847std::optionalstd::string

849 auto getPathForTriple =

850 [&](const llvm::Triple &Triple) -> std::optionalstd::string {

852 llvm::sys::path::append(P, Triple.str());

854 return std::string(P);

855 return {};

856 };

857

859 return *Path;

860

861

862

863

864

865

866

867

868

869

870

871

872

873

874

875

877 llvm::Triple ArmTriple = getTriple();

878 ArmTriple.setArch(Triple::arm);

879 if (auto Path = getPathForTriple(ArmTriple))

880 return *Path;

881 }

882

884 return getFallbackAndroidTargetPath(BaseDir);

885

886 return {};

887}

888

891 llvm::sys::path::append(P, "lib");

893 return Ret;

894

895 if (Triple.isOSDarwin() || Triple.isOSAIX())

896 return {};

897 llvm::sys::path::append(P, Triple.str());

898 return std::string(P);

899}

900

903 llvm::sys::path::append(P, "..", "lib");

905}

906

909 llvm::sys::path::append(P, "..", "include");

911}

912

915

918 llvm::sys::path::append(Path, "lib");

919 for (auto &S : SS)

920 llvm::sys::path::append(Path, S);

921 Paths.push_back(std::string(Path));

922 };

923

926 return Paths;

927}

928

930 if (Args.hasArg(options::OPT_noprofilelib))

931 return false;

932

933 return Args.hasArg(options::OPT_fprofile_generate) ||

934 Args.hasArg(options::OPT_fprofile_generate_EQ) ||

935 Args.hasArg(options::OPT_fcs_profile_generate) ||

936 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||

937 Args.hasArg(options::OPT_fprofile_instr_generate) ||

938 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||

939 Args.hasArg(options::OPT_fcreate_profile) ||

940 Args.hasArg(options::OPT_forder_file_instrumentation) ||

941 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||

942 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);

943}

944

946 return Args.hasArg(options::OPT_coverage) ||

947 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,

948 false);

949}

950

952 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();

953 if (getDriver().ShouldUseClangCompiler(JA)) return getClang();

957 return getClangAs();

959}

960

963}

964

967}

968

970 if (LinkerIsLLD)

971 *LinkerIsLLD = false;

972

973

974

975 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);

976 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;

977

978

979

980

981

982

983 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {

984 std::string Path(A->getValue());

985 if (Path.empty()) {

986 if (llvm::sys::path::parent_path(Path).empty())

988 if (llvm::sys::fs::can_execute(Path)) {

989 if (LinkerIsLLD)

990 *LinkerIsLLD = UseLinker == "lld";

991 return std::string(Path);

992 }

993 }

994 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);

996 }

997

998

999 if (UseLinker.empty() || UseLinker == "ld") {

1001 if (llvm::sys::path::is_absolute(DefaultLinker))

1002 return std::string(DefaultLinker);

1003 else

1005 }

1006

1007

1008

1009

1010

1011 if (UseLinker.contains('/'))

1013

1014 if (llvm::sys::path::is_absolute(UseLinker)) {

1015

1016

1017 if (llvm::sys::fs::can_execute(UseLinker))

1018 return std::string(UseLinker);

1019 } else {

1021 if (Triple.isOSDarwin())

1022 LinkerName.append("ld64.");

1023 else

1024 LinkerName.append("ld.");

1025 LinkerName.append(UseLinker);

1026

1027 std::string LinkerPath(GetProgramPath(LinkerName.c_str()));

1028 if (llvm::sys::fs::can_execute(LinkerPath)) {

1029 if (LinkerIsLLD)

1030 *LinkerIsLLD = UseLinker == "lld";

1031 return LinkerPath;

1032 }

1033 }

1034

1035 if (A)

1036 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);

1037

1039}

1040

1042

1043 if (Triple.isOSDarwin())

1046}

1047

1050

1051

1052

1053

1054 if (D.IsFlangMode() && id == types::TY_PP_Fortran)

1055 id = types::TY_Fortran;

1056

1057 return id;

1058}

1059

1061 return false;

1062}

1063

1065 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);

1066 switch (HostTriple.getArch()) {

1067

1068

1069 case llvm::Triple::arm:

1070 case llvm::Triple::armeb:

1071 case llvm::Triple::thumb:

1072 case llvm::Triple::thumbeb:

1073 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&

1074 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;

1075 default:

1076 return HostTriple.getArch() != getArch();

1077 }

1078}

1079

1082 VersionTuple());

1083}

1084

1085llvm::ExceptionHandling

1087 return llvm::ExceptionHandling::None;

1088}

1089

1091 if (Model == "single") {

1092

1093 return Triple.getArch() == llvm::Triple::arm ||

1094 Triple.getArch() == llvm::Triple::armeb ||

1095 Triple.getArch() == llvm::Triple::thumb ||

1096 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();

1097 } else if (Model == "posix")

1098 return true;

1099

1100 return false;

1101}

1102

1106 default:

1108

1109 case llvm::Triple::x86_64: {

1110 llvm::Triple Triple = getTriple();

1111 if (!Triple.isOSBinFormatMachO())

1113

1114 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {

1115

1116

1117 StringRef MArch = A->getValue();

1118 if (MArch == "x86_64h")

1119 Triple.setArchName(MArch);

1120 }

1121 return Triple.getTriple();

1122 }

1123 case llvm::Triple::aarch64: {

1124 llvm::Triple Triple = getTriple();

1126 if (!Triple.isOSBinFormatMachO())

1127 return Triple.getTriple();

1128

1129 if (Triple.isArm64e())

1130 return Triple.getTriple();

1131

1132

1133

1134

1135 Triple.setArchName("arm64");

1136 return Triple.getTriple();

1137 }

1138 case llvm::Triple::aarch64_32:

1140 case llvm::Triple::amdgcn: {

1141 llvm::Triple Triple = getTriple();

1142 if (Args.getLastArgValue(options::OPT_mcpu_EQ) == "amdgcnspirv")

1143 Triple.setArch(llvm::Triple::ArchType::spirv64);

1144 return Triple.getTriple();

1145 }

1146 case llvm::Triple::arm:

1147 case llvm::Triple::armeb:

1148 case llvm::Triple::thumb:

1149 case llvm::Triple::thumbeb: {

1150 llvm::Triple Triple = getTriple();

1153 return Triple.getTriple();

1154 }

1155 }

1156}

1157

1161}

1162

1165}

1166

1168 ArgStringList &CC1Args) const {

1169

1170}

1171

1173 const ArgList &DriverArgs, ArgStringList &CC1Args,

1175

1177 ArgStringList &CC1ASArgs) const {}

1178

1180

1182 llvm::opt::ArgStringList &CmdArgs) const {

1184 return;

1185

1187}

1188

1190 const ArgList &Args) const {

1191 if (runtimeLibType)

1192 return *runtimeLibType;

1193

1194 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);

1195 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;

1196

1197

1198 if (LibName == "compiler-rt")

1200 else if (LibName == "libgcc")

1202 else if (LibName == "platform")

1204 else {

1205 if (A)

1206 getDriver().Diag(diag::err_drv_invalid_rtlib_name)

1207 << A->getAsString(Args);

1208

1210 }

1211

1212 return *runtimeLibType;

1213}

1214

1216 const ArgList &Args) const {

1217 if (unwindLibType)

1218 return *unwindLibType;

1219

1220 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);

1221 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;

1222

1223 if (LibName == "none")

1225 else if (LibName == "platform" || LibName == "") {

1230 else

1234 } else if (LibName == "libunwind") {

1236 getDriver().Diag(diag::err_drv_incompatible_unwindlib);

1238 } else if (LibName == "libgcc")

1240 else {

1241 if (A)

1242 getDriver().Diag(diag::err_drv_invalid_unwindlib_name)

1243 << A->getAsString(Args);

1244

1246 }

1247

1248 return *unwindLibType;

1249}

1250

1252 if (cxxStdlibType)

1253 return *cxxStdlibType;

1254

1255 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);

1256 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;

1257

1258

1259 if (LibName == "libc++")

1261 else if (LibName == "libstdc++")

1263 else if (LibName == "platform")

1265 else {

1266 if (A)

1267 getDriver().Diag(diag::err_drv_invalid_stdlib_name)

1268 << A->getAsString(Args);

1269

1271 }

1272

1273 return *cxxStdlibType;

1274}

1275

1276

1278 ArgStringList &CC1Args,

1279 const Twine &Path) {

1280 CC1Args.push_back("-internal-isystem");

1281 CC1Args.push_back(DriverArgs.MakeArgString(Path));

1282}

1283

1284

1285

1286

1287

1288

1289

1290

1291

1293 ArgStringList &CC1Args,

1294 const Twine &Path) {

1295 CC1Args.push_back("-internal-externc-isystem");

1296 CC1Args.push_back(DriverArgs.MakeArgString(Path));

1297}

1298

1300 ArgStringList &CC1Args,

1301 const Twine &Path) {

1302 if (llvm::sys::fs::exists(Path))

1304}

1305

1306

1308 ArgStringList &CC1Args,

1310 for (const auto &Path : Paths) {

1311 CC1Args.push_back("-internal-isystem");

1312 CC1Args.push_back(DriverArgs.MakeArgString(Path));

1313 }

1314}

1315

1317 const Twine &B, const Twine &C,

1318 const Twine &D) {

1320 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D);

1321 return std::string(Result);

1322}

1323

1325 std::error_code EC;

1326 int MaxVersion = 0;

1327 std::string MaxVersionString;

1329 llvm::sys::path::append(Path, "c++");

1330 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;

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

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

1333 int Version;

1334 if (VersionText[0] == 'v' &&

1335 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {

1336 if (Version > MaxVersion) {

1337 MaxVersion = Version;

1338 MaxVersionString = std::string(VersionText);

1339 }

1340 }

1341 }

1342 if (!MaxVersion)

1343 return "";

1344 return MaxVersionString;

1345}

1346

1348 ArgStringList &CC1Args) const {

1349

1350

1351

1352

1353

1354

1355

1356

1357

1358 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);

1359}

1360

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

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

1364 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);

1365

1366

1367

1368

1369

1370

1371

1372

1373 if (!DriverArgs.hasArg(options::OPT_nostdincxx))

1374 for (const auto &P :

1375 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))

1377}

1378

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

1382 options::OPT_nostdlibxx);

1383}

1384

1386 ArgStringList &CmdArgs) const {

1387 assert(!Args.hasArg(options::OPT_nostdlibxx) &&

1388 "should not have called this");

1390

1391 switch (Type) {

1393 CmdArgs.push_back("-lc++");

1394 if (Args.hasArg(options::OPT_fexperimental_library))

1395 CmdArgs.push_back("-lc++experimental");

1396 break;

1397

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

1400 break;

1401 }

1402}

1403

1405 ArgStringList &CmdArgs) const {

1407 if(LibPath.length() > 0)

1408 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));

1409}

1410

1412 ArgStringList &CmdArgs) const {

1413 CmdArgs.push_back("-lcc_kext");

1414}

1415

1417 std::string &Path) const {

1418

1419

1420

1421 bool Default = !Args.hasArgNoClaim(options::OPT_shared);

1422

1423

1424

1426

1427 Arg *A = Args.getLastArg(

1428 options::OPT_ffast_math, options::OPT_fno_fast_math,

1429 options::OPT_funsafe_math_optimizations,

1430 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);

1431

1432 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||

1433 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)

1435 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {

1436 StringRef Model = A->getValue();

1437 if (Model != "fast" && Model != "aggressive")

1439 }

1440 }

1441

1442

1443

1444 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default))

1445 return false;

1446

1447

1449 return (Path != "crtfastmath.o");

1450}

1451

1453 ArgStringList &CmdArgs) const {

1454 std::string Path;

1456 CmdArgs.push_back(Args.MakeArgString(Path));

1457 return true;

1458 }

1459

1460 return false;

1461}

1462

1466}

1467

1469

1470

1471

1474 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |

1475 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |

1476 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |

1477 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |

1478 SanitizerKind::Nullability | SanitizerKind::LocalBounds;

1479 if (getTriple().getArch() == llvm::Triple::x86 ||

1480 getTriple().getArch() == llvm::Triple::x86_64 ||

1481 getTriple().getArch() == llvm::Triple::arm ||

1482 getTriple().getArch() == llvm::Triple::thumb || getTriple().isWasm() ||

1485 Res |= SanitizerKind::CFIICall;

1486 if (getTriple().getArch() == llvm::Triple::x86_64 ||

1488 Res |= SanitizerKind::ShadowCallStack;

1490 Res |= SanitizerKind::MemTag;

1491 return Res;

1492}

1493

1495 ArgStringList &CC1Args) const {}

1496

1498 ArgStringList &CC1Args) const {}

1499

1501 ArgStringList &CC1Args) const {}

1502

1505 return {};

1506}

1507

1509 ArgStringList &CC1Args) const {}

1510

1512 if (Version < 100)

1513 return VersionTuple(Version);

1514

1515 if (Version < 10000)

1516 return VersionTuple(Version / 100, Version % 100);

1517

1518 unsigned Build = 0, Factor = 1;

1519 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)

1520 Build = Build + (Version % 10) * Factor;

1521 return VersionTuple(Version / 100, Version % 100, Build);

1522}

1523

1524VersionTuple

1526 const llvm::opt::ArgList &Args) const {

1527 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);

1528 const Arg *MSCompatibilityVersion =

1529 Args.getLastArg(options::OPT_fms_compatibility_version);

1530

1531 if (MSCVersion && MSCompatibilityVersion) {

1532 if (D)

1533 D->Diag(diag::err_drv_argument_not_allowed_with)

1534 << MSCVersion->getAsString(Args)

1535 << MSCompatibilityVersion->getAsString(Args);

1536 return VersionTuple();

1537 }

1538

1539 if (MSCompatibilityVersion) {

1540 VersionTuple MSVT;

1541 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {

1542 if (D)

1543 D->Diag(diag::err_drv_invalid_value)

1544 << MSCompatibilityVersion->getAsString(Args)

1545 << MSCompatibilityVersion->getValue();

1546 } else {

1547 return MSVT;

1548 }

1549 }

1550

1551 if (MSCVersion) {

1552 unsigned Version = 0;

1553 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {

1554 if (D)

1555 D->Diag(diag::err_drv_invalid_value)

1556 << MSCVersion->getAsString(Args) << MSCVersion->getValue();

1557 } else {

1559 }

1560 }

1561

1562 return VersionTuple();

1563}

1564

1566 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,

1568 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());

1570 bool Modified = false;

1571

1572

1573 for (auto *A : Args) {

1574

1575

1576

1577

1578 if (A->getOption().matches(options::OPT_m_Group)) {

1579

1580

1581 if (SameTripleAsHost ||

1582 A->getOption().matches(options::OPT_mcode_object_version_EQ))

1583 DAL->append(A);

1584 else

1585 Modified = true;

1586 continue;

1587 }

1588

1589 unsigned Index;

1590 unsigned Prev;

1591 bool XOpenMPTargetNoTriple =

1592 A->getOption().matches(options::OPT_Xopenmp_target);

1593

1594 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {

1596

1597

1599 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));

1600 else

1601 continue;

1602 } else if (XOpenMPTargetNoTriple) {

1603

1604 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));

1605 } else {

1606 DAL->append(A);

1607 continue;

1608 }

1609

1610

1611 Prev = Index;

1612 std::unique_ptr XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));

1613 if (!XOpenMPTargetArg || Index > Prev + 1) {

1614 if (!A->isClaimed()) {

1615 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)

1616 << A->getAsString(Args);

1617 }

1618 continue;

1619 }

1620 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&

1621 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {

1622 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);

1623 continue;

1624 }

1625 XOpenMPTargetArg->setBaseArg(A);

1626 A = XOpenMPTargetArg.release();

1627 AllocatedArgs.push_back(A);

1628 DAL->append(A);

1629 Modified = true;

1630 }

1631

1632 if (Modified)

1633 return DAL;

1634

1635 delete DAL;

1636 return nullptr;

1637}

1638

1639

1640

1641

1643 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,

1644 llvm::opt::DerivedArgList *DAL,

1647 unsigned ValuePos = 1;

1648 if (A->getOption().matches(options::OPT_Xarch_device) ||

1649 A->getOption().matches(options::OPT_Xarch_host))

1650 ValuePos = 0;

1651

1652 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));

1653 unsigned Prev = Index;

1654 std::unique_ptrllvm::opt::Arg XarchArg(Opts.ParseOneArg(Args, Index));

1655

1656

1657

1658

1659

1660

1661

1662

1663 if (!XarchArg || Index > Prev + 1) {

1664 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)

1665 << A->getAsString(Args);

1666 return;

1669 unsigned DiagID =

1671 "invalid Xarch argument: '%0', not all driver "

1672 "options can be forwared via Xarch argument");

1673 Diags.Report(DiagID) << A->getAsString(Args);

1674 return;

1675 }

1676 XarchArg->setBaseArg(A);

1677 A = XarchArg.release();

1678 if (!AllocatedArgs)

1679 DAL->AddSynthesizedArg(A);

1680 else

1681 AllocatedArgs->push_back(A);

1682}

1683

1685 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,

1688 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());

1689 bool Modified = false;

1690

1692 for (Arg *A : Args) {

1693 bool NeedTrans = false;

1694 bool Skip = false;

1695 if (A->getOption().matches(options::OPT_Xarch_device)) {

1696 NeedTrans = IsDevice;

1697 Skip = !IsDevice;

1698 } else if (A->getOption().matches(options::OPT_Xarch_host)) {

1699 NeedTrans = !IsDevice;

1700 Skip = IsDevice;

1701 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {

1702

1703

1704

1705 if (BoundArch.empty() || A->getValue(0) != BoundArch)

1706 Skip = true;

1707 else

1708 NeedTrans = true;

1709 }

1710 if (NeedTrans || Skip)

1711 Modified = true;

1712 if (NeedTrans)

1715 DAL->append(A);

1716 }

1717

1718 if (Modified)

1719 return DAL;

1720

1721 delete DAL;

1722 return nullptr;

1723}

Defines types useful for describing an Objective-C runtime.

Defines the clang::SanitizerKind enum.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

The basic abstraction for the target Objective-C runtime.

@ GNUstep

'gnustep' is the modern non-fragile GNUstep runtime.

@ GCC

'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI

The base class of the type hierarchy.

ActionClass getKind() const

@ OffloadUnbundlingJobClass

@ OffloadBundlingJobClass

@ VerifyDebugInfoJobClass

@ OffloadPackagerJobClass

Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...

std::string SysRoot

sysroot, if present

std::string GetFilePath(StringRef Name, const ToolChain &TC) const

GetFilePath - Lookup Name in the list of file search paths.

DiagnosticsEngine & getDiags() const

DiagnosticBuilder Diag(unsigned DiagID) const

const llvm::opt::OptTable & getOpts() const

std::string GetProgramPath(StringRef Name, const ToolChain &TC) const

GetProgramPath - Lookup Name in the list of program search paths.

std::string ResourceDir

The path to the compiler resource directory.

llvm::vfs::FileSystem & getVFS() const

std::string Dir

The path the driver executable was in, as invoked from the command line.

bool IsFlangMode() const

Whether the driver should invoke flang for fortran inputs.

bool CCCIsCXX() const

Whether the driver should follow g++ like behavior.

InputInfo - Wrapper for information about an input source.

const char * getFilename() const

std::vector< std::string > flags_list

ID lookupTypeForExtension(llvm::StringRef Ext)

lookupTypeForExtension - Lookup the type to use for the file extension Ext.

bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

const FunctionProtoType * T

Diagnostic wrappers for TextAPI types for error reporting.

Helper structure used to pass information extracted from clang executable name such as i686-linux-and...