1 //===- ToolChain.cpp - Collections of tools for one platform --------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/Driver/ToolChain.h" 10 #include "ToolChains/Arch/AArch64.h" 11 #include "ToolChains/Arch/ARM.h" 12 #include "ToolChains/Clang.h" 13 #include "ToolChains/CommonArgs.h" 14 #include "ToolChains/Flang.h" 15 #include "ToolChains/InterfaceStubs.h" 16 #include "clang/Basic/ObjCRuntime.h" 17 #include "clang/Basic/Sanitizers.h" 18 #include "clang/Config/config.h" 19 #include "clang/Driver/Action.h" 20 #include "clang/Driver/Driver.h" 21 #include "clang/Driver/DriverDiagnostic.h" 22 #include "clang/Driver/InputInfo.h" 23 #include "clang/Driver/Job.h" 24 #include "clang/Driver/Options.h" 25 #include "clang/Driver/SanitizerArgs.h" 26 #include "clang/Driver/XRayArgs.h" 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/ADT/SmallString.h" 29 #include "llvm/ADT/StringExtras.h" 30 #include "llvm/ADT/StringRef.h" 31 #include "llvm/ADT/Twine.h" 32 #include "llvm/Config/llvm-config.h" 33 #include "llvm/MC/MCTargetOptions.h" 34 #include "llvm/MC/TargetRegistry.h" 35 #include "llvm/Option/Arg.h" 36 #include "llvm/Option/ArgList.h" 37 #include "llvm/Option/OptTable.h" 38 #include "llvm/Option/Option.h" 39 #include "llvm/Support/ErrorHandling.h" 40 #include "llvm/Support/FileSystem.h" 41 #include "llvm/Support/FileUtilities.h" 42 #include "llvm/Support/Path.h" 43 #include "llvm/Support/VersionTuple.h" 44 #include "llvm/Support/VirtualFileSystem.h" 45 #include "llvm/TargetParser/AArch64TargetParser.h" 46 #include "llvm/TargetParser/TargetParser.h" 47 #include "llvm/TargetParser/Triple.h" 48 #include <cassert> 49 #include <cstddef> 50 #include <cstring> 51 #include <string> 52 53 using namespace clang; 54 using namespace driver; 55 using namespace tools; 56 using namespace llvm; 57 using namespace llvm::opt; 58 59 static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) { 60 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext, 61 options::OPT_fno_rtti, options::OPT_frtti); 62 } 63 64 static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args, 65 const llvm::Triple &Triple, 66 const Arg *CachedRTTIArg) { 67 // Explicit rtti/no-rtti args 68 if (CachedRTTIArg) { 69 if (CachedRTTIArg->getOption().matches(options::OPT_frtti)) 70 return ToolChain::RM_Enabled; 71 else 72 return ToolChain::RM_Disabled; 73 } 74 75 // -frtti is default, except for the PS4/PS5 and DriverKit. 76 bool NoRTTI = Triple.isPS() || Triple.isDriverKit(); 77 return NoRTTI ? ToolChain::RM_Disabled : ToolChain::RM_Enabled; 78 } 79 80 static ToolChain::ExceptionsMode CalculateExceptionsMode(const ArgList &Args) { 81 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, 82 true)) { 83 return ToolChain::EM_Enabled; 84 } 85 return ToolChain::EM_Disabled; 86 } 87 88 ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, 89 const ArgList &Args) 90 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)), 91 CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)), 92 CachedExceptionsMode(CalculateExceptionsMode(Args)) { 93 auto addIfExists = [this](path_list &List, const std::string &Path) { 94 if (getVFS().exists(Path)) 95 List.push_back(Path); 96 }; 97 98 if (std::optional<std::string> Path = getRuntimePath()) 99 getLibraryPaths().push_back(*Path); 100 if (std::optional<std::string> Path = getStdlibPath()) 101 getFilePaths().push_back(*Path); 102 for (const auto &Path : getArchSpecificLibPaths()) 103 addIfExists(getFilePaths(), Path); 104 } 105 106 llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 107 ToolChain::executeToolChainProgram(StringRef Executable, 108 unsigned SecondsToWait) const { 109 llvm::SmallString<64> OutputFile; 110 llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile); 111 llvm::FileRemover OutputRemover(OutputFile.c_str()); 112 std::optional<llvm::StringRef> Redirects[] = { 113 {""}, 114 OutputFile.str(), 115 {""}, 116 }; 117 118 std::string ErrorMessage; 119 if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects, SecondsToWait, 120 /*MemoryLimit=*/0, &ErrorMessage)) 121 return llvm::createStringError(std::error_code(), 122 Executable + ": " + ErrorMessage); 123 124 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf = 125 llvm::MemoryBuffer::getFile(OutputFile.c_str()); 126 if (!OutputBuf) 127 return llvm::createStringError(OutputBuf.getError(), 128 "Failed to read stdout of " + Executable + 129 ": " + OutputBuf.getError().message()); 130 return std::move(*OutputBuf); 131 } 132 133 void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) { 134 Triple.setEnvironment(Env); 135 if (EffectiveTriple != llvm::Triple()) 136 EffectiveTriple.setEnvironment(Env); 137 } 138 139 ToolChain::~ToolChain() = default; 140 141 llvm::vfs::FileSystem &ToolChain::getVFS() const { 142 return getDriver().getVFS(); 143 } 144 145 bool ToolChain::useIntegratedAs() const { 146 return Args.hasFlag(options::OPT_fintegrated_as, 147 options::OPT_fno_integrated_as, 148 IsIntegratedAssemblerDefault()); 149 } 150 151 bool ToolChain::useIntegratedBackend() const { 152 assert( 153 ((IsIntegratedBackendDefault() && IsIntegratedBackendSupported()) || 154 (!IsIntegratedBackendDefault() || IsNonIntegratedBackendSupported())) && 155 "(Non-)integrated backend set incorrectly!"); 156 157 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter, 158 options::OPT_fno_integrated_objemitter, 159 IsIntegratedBackendDefault()); 160 161 // Diagnose when integrated-objemitter options are not supported by this 162 // toolchain. 163 unsigned DiagID; 164 if ((IBackend && !IsIntegratedBackendSupported()) || 165 (!IBackend && !IsNonIntegratedBackendSupported())) 166 DiagID = clang::diag::err_drv_unsupported_opt_for_target; 167 else 168 DiagID = clang::diag::warn_drv_unsupported_opt_for_target; 169 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter); 170 if (A && !IsNonIntegratedBackendSupported()) 171 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple(); 172 A = Args.getLastArg(options::OPT_fintegrated_objemitter); 173 if (A && !IsIntegratedBackendSupported()) 174 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple(); 175 176 return IBackend; 177 } 178 179 bool ToolChain::useRelaxRelocations() const { 180 return ENABLE_X86_RELAX_RELOCATIONS; 181 } 182 183 bool ToolChain::defaultToIEEELongDouble() const { 184 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux(); 185 } 186 187 static void getAArch64MultilibFlags(const Driver &D, 188 const llvm::Triple &Triple, 189 const llvm::opt::ArgList &Args, 190 Multilib::flags_list &Result) { 191 std::vector<StringRef> Features; 192 tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, false); 193 const auto UnifiedFeatures = tools::unifyTargetFeatures(Features); 194 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(), 195 UnifiedFeatures.end()); 196 std::vector<std::string> MArch; 197 for (const auto &Ext : AArch64::Extensions) 198 if (FeatureSet.contains(Ext.PosTargetFeature)) 199 MArch.push_back(Ext.UserVisibleName.str()); 200 for (const auto &Ext : AArch64::Extensions) 201 if (FeatureSet.contains(Ext.NegTargetFeature)) 202 MArch.push_back(("no" + Ext.UserVisibleName).str()); 203 StringRef ArchName; 204 for (const auto &ArchInfo : AArch64::ArchInfos) 205 if (FeatureSet.contains(ArchInfo->ArchFeature)) 206 ArchName = ArchInfo->Name; 207 assert(!ArchName.empty() && "at least one architecture should be found"); 208 MArch.insert(MArch.begin(), ("-march=" + ArchName).str()); 209 Result.push_back(llvm::join(MArch, "+")); 210 } 211 212 static void getARMMultilibFlags(const Driver &D, 213 const llvm::Triple &Triple, 214 const llvm::opt::ArgList &Args, 215 Multilib::flags_list &Result) { 216 std::vector<StringRef> Features; 217 llvm::ARM::FPUKind FPUKind = tools::arm::getARMTargetFeatures( 218 D, Triple, Args, Features, false /*ForAs*/, true /*ForMultilib*/); 219 const auto UnifiedFeatures = tools::unifyTargetFeatures(Features); 220 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(), 221 UnifiedFeatures.end()); 222 std::vector<std::string> MArch; 223 for (const auto &Ext : ARM::ARCHExtNames) 224 if (FeatureSet.contains(Ext.Feature)) 225 MArch.push_back(Ext.Name.str()); 226 for (const auto &Ext : ARM::ARCHExtNames) 227 if (FeatureSet.contains(Ext.NegFeature)) 228 MArch.push_back(("no" + Ext.Name).str()); 229 MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str()); 230 Result.push_back(llvm::join(MArch, "+")); 231 232 switch (FPUKind) { 233 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \ 234 case llvm::ARM::KIND: \ 235 Result.push_back("-mfpu=" NAME); \ 236 break; 237 #include "llvm/TargetParser/ARMTargetParser.def" 238 default: 239 llvm_unreachable("Invalid FPUKind"); 240 } 241 242 switch (arm::getARMFloatABI(D, Triple, Args)) { 243 case arm::FloatABI::Soft: 244 Result.push_back("-mfloat-abi=soft"); 245 break; 246 case arm::FloatABI::SoftFP: 247 Result.push_back("-mfloat-abi=softfp"); 248 break; 249 case arm::FloatABI::Hard: 250 Result.push_back("-mfloat-abi=hard"); 251 break; 252 case arm::FloatABI::Invalid: 253 llvm_unreachable("Invalid float ABI"); 254 } 255 } 256 257 Multilib::flags_list 258 ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const { 259 using namespace clang::driver::options; 260 261 std::vector<std::string> Result; 262 const llvm::Triple Triple(ComputeEffectiveClangTriple(Args)); 263 Result.push_back("--target=" + Triple.str()); 264 265 switch (Triple.getArch()) { 266 case llvm::Triple::aarch64: 267 case llvm::Triple::aarch64_32: 268 case llvm::Triple::aarch64_be: 269 getAArch64MultilibFlags(D, Triple, Args, Result); 270 break; 271 case llvm::Triple::arm: 272 case llvm::Triple::armeb: 273 case llvm::Triple::thumb: 274 case llvm::Triple::thumbeb: 275 getARMMultilibFlags(D, Triple, Args, Result); 276 break; 277 default: 278 break; 279 } 280 281 // Include fno-exceptions and fno-rtti 282 // to improve multilib selection 283 if (getRTTIMode() == ToolChain::RTTIMode::RM_Disabled) 284 Result.push_back("-fno-rtti"); 285 else 286 Result.push_back("-frtti"); 287 288 if (getExceptionsMode() == ToolChain::ExceptionsMode::EM_Disabled) 289 Result.push_back("-fno-exceptions"); 290 else 291 Result.push_back("-fexceptions"); 292 293 // Sort and remove duplicates. 294 std::sort(Result.begin(), Result.end()); 295 Result.erase(std::unique(Result.begin(), Result.end()), Result.end()); 296 return Result; 297 } 298 299 SanitizerArgs 300 ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const { 301 SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked); 302 SanitizerArgsChecked = true; 303 return SanArgs; 304 } 305 306 const XRayArgs& ToolChain::getXRayArgs() const { 307 if (!XRayArguments) 308 XRayArguments.reset(new XRayArgs(*this, Args)); 309 return *XRayArguments; 310 } 311 312 namespace { 313 314 struct DriverSuffix { 315 const char *Suffix; 316 const char *ModeFlag; 317 }; 318 319 } // namespace 320 321 static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { 322 // A list of known driver suffixes. Suffixes are compared against the 323 // program name in order. If there is a match, the frontend type is updated as 324 // necessary by applying the ModeFlag. 325 static const DriverSuffix DriverSuffixes[] = { 326 {"clang", nullptr}, 327 {"clang++", "--driver-mode=g++"}, 328 {"clang-c++", "--driver-mode=g++"}, 329 {"clang-cc", nullptr}, 330 {"clang-cpp", "--driver-mode=cpp"}, 331 {"clang-g++", "--driver-mode=g++"}, 332 {"clang-gcc", nullptr}, 333 {"clang-cl", "--driver-mode=cl"}, 334 {"cc", nullptr}, 335 {"cpp", "--driver-mode=cpp"}, 336 {"cl", "--driver-mode=cl"}, 337 {"++", "--driver-mode=g++"}, 338 {"flang", "--driver-mode=flang"}, 339 {"clang-dxc", "--driver-mode=dxc"}, 340 }; 341 342 for (const auto &DS : DriverSuffixes) { 343 StringRef Suffix(DS.Suffix); 344 if (ProgName.ends_with(Suffix)) { 345 Pos = ProgName.size() - Suffix.size(); 346 return &DS; 347 } 348 } 349 return nullptr; 350 } 351 352 /// Normalize the program name from argv[0] by stripping the file extension if 353 /// present and lower-casing the string on Windows. 354 static std::string normalizeProgramName(llvm::StringRef Argv0) { 355 std::string ProgName = std::string(llvm::sys::path::filename(Argv0)); 356 if (is_style_windows(llvm::sys::path::Style::native)) { 357 // Transform to lowercase for case insensitive file systems. 358 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), 359 ::tolower); 360 } 361 return ProgName; 362 } 363 364 static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { 365 // Try to infer frontend type and default target from the program name by 366 // comparing it against DriverSuffixes in order. 367 368 // If there is a match, the function tries to identify a target as prefix. 369 // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target 370 // prefix "x86_64-linux". If such a target prefix is found, it may be 371 // added via -target as implicit first argument. 372 const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos); 373 374 if (!DS && ProgName.ends_with(".exe")) { 375 // Try again after stripping the executable suffix: 376 // clang++.exe -> clang++ 377 ProgName = ProgName.drop_back(StringRef(".exe").size()); 378 DS = FindDriverSuffix(ProgName, Pos); 379 } 380 381 if (!DS) { 382 // Try again after stripping any trailing version number: 383 // clang++3.5 -> clang++ 384 ProgName = ProgName.rtrim("0123456789."); 385 DS = FindDriverSuffix(ProgName, Pos); 386 } 387 388 if (!DS) { 389 // Try again after stripping trailing -component. 390 // clang++-tot -> clang++ 391 ProgName = ProgName.slice(0, ProgName.rfind('-')); 392 DS = FindDriverSuffix(ProgName, Pos); 393 } 394 return DS; 395 } 396 397 ParsedClangName 398 ToolChain::getTargetAndModeFromProgramName(StringRef PN) { 399 std::string ProgName = normalizeProgramName(PN); 400 size_t SuffixPos; 401 const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos); 402 if (!DS) 403 return {}; 404 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix); 405 406 size_t LastComponent = ProgName.rfind('-', SuffixPos); 407 if (LastComponent == std::string::npos) 408 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag); 409 std::string ModeSuffix = ProgName.substr(LastComponent + 1, 410 SuffixEnd - LastComponent - 1); 411 412 // Infer target from the prefix. 413 StringRef Prefix(ProgName); 414 Prefix = Prefix.slice(0, LastComponent); 415 std::string IgnoredError; 416 bool IsRegistered = 417 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError); 418 return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag, 419 IsRegistered}; 420 } 421 422 StringRef ToolChain::getDefaultUniversalArchName() const { 423 // In universal driver terms, the arch name accepted by -arch isn't exactly 424 // the same as the ones that appear in the triple. Roughly speaking, this is 425 // an inverse of the darwin::getArchTypeForDarwinArchName() function. 426 switch (Triple.getArch()) { 427 case llvm::Triple::aarch64: { 428 if (getTriple().isArm64e()) 429 return "arm64e"; 430 return "arm64"; 431 } 432 case llvm::Triple::aarch64_32: 433 return "arm64_32"; 434 case llvm::Triple::ppc: 435 return "ppc"; 436 case llvm::Triple::ppcle: 437 return "ppcle"; 438 case llvm::Triple::ppc64: 439 return "ppc64"; 440 case llvm::Triple::ppc64le: 441 return "ppc64le"; 442 default: 443 return Triple.getArchName(); 444 } 445 } 446 447 std::string ToolChain::getInputFilename(const InputInfo &Input) const { 448 return Input.getFilename(); 449 } 450 451 ToolChain::UnwindTableLevel 452 ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const { 453 return UnwindTableLevel::None; 454 } 455 456 Tool *ToolChain::getClang() const { 457 if (!Clang) 458 Clang.reset(new tools::Clang(*this, useIntegratedBackend())); 459 return Clang.get(); 460 } 461 462 Tool *ToolChain::getFlang() const { 463 if (!Flang) 464 Flang.reset(new tools::Flang(*this)); 465 return Flang.get(); 466 } 467 468 Tool *ToolChain::buildAssembler() const { 469 return new tools::ClangAs(*this); 470 } 471 472 Tool *ToolChain::buildLinker() const { 473 llvm_unreachable("Linking is not supported by this toolchain"); 474 } 475 476 Tool *ToolChain::buildStaticLibTool() const { 477 llvm_unreachable("Creating static lib is not supported by this toolchain"); 478 } 479 480 Tool *ToolChain::getAssemble() const { 481 if (!Assemble) 482 Assemble.reset(buildAssembler()); 483 return Assemble.get(); 484 } 485 486 Tool *ToolChain::getClangAs() const { 487 if (!Assemble) 488 Assemble.reset(new tools::ClangAs(*this)); 489 return Assemble.get(); 490 } 491 492 Tool *ToolChain::getLink() const { 493 if (!Link) 494 Link.reset(buildLinker()); 495 return Link.get(); 496 } 497 498 Tool *ToolChain::getStaticLibTool() const { 499 if (!StaticLibTool) 500 StaticLibTool.reset(buildStaticLibTool()); 501 return StaticLibTool.get(); 502 } 503 504 Tool *ToolChain::getIfsMerge() const { 505 if (!IfsMerge) 506 IfsMerge.reset(new tools::ifstool::Merger(*this)); 507 return IfsMerge.get(); 508 } 509 510 Tool *ToolChain::getOffloadBundler() const { 511 if (!OffloadBundler) 512 OffloadBundler.reset(new tools::OffloadBundler(*this)); 513 return OffloadBundler.get(); 514 } 515 516 Tool *ToolChain::getOffloadPackager() const { 517 if (!OffloadPackager) 518 OffloadPackager.reset(new tools::OffloadPackager(*this)); 519 return OffloadPackager.get(); 520 } 521 522 Tool *ToolChain::getLinkerWrapper() const { 523 if (!LinkerWrapper) 524 LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink())); 525 return LinkerWrapper.get(); 526 } 527 528 Tool *ToolChain::getTool(Action::ActionClass AC) const { 529 switch (AC) { 530 case Action::AssembleJobClass: 531 return getAssemble(); 532 533 case Action::IfsMergeJobClass: 534 return getIfsMerge(); 535 536 case Action::LinkJobClass: 537 return getLink(); 538 539 case Action::StaticLibJobClass: 540 return getStaticLibTool(); 541 542 case Action::InputClass: 543 case Action::BindArchClass: 544 case Action::OffloadClass: 545 case Action::LipoJobClass: 546 case Action::DsymutilJobClass: 547 case Action::VerifyDebugInfoJobClass: 548 case Action::BinaryAnalyzeJobClass: 549 llvm_unreachable("Invalid tool kind."); 550 551 case Action::CompileJobClass: 552 case Action::PrecompileJobClass: 553 case Action::PreprocessJobClass: 554 case Action::ExtractAPIJobClass: 555 case Action::AnalyzeJobClass: 556 case Action::MigrateJobClass: 557 case Action::VerifyPCHJobClass: 558 case Action::BackendJobClass: 559 return getClang(); 560 561 case Action::OffloadBundlingJobClass: 562 case Action::OffloadUnbundlingJobClass: 563 return getOffloadBundler(); 564 565 case Action::OffloadPackagerJobClass: 566 return getOffloadPackager(); 567 case Action::LinkerWrapperJobClass: 568 return getLinkerWrapper(); 569 } 570 571 llvm_unreachable("Invalid tool kind."); 572 } 573 574 static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, 575 const ArgList &Args) { 576 const llvm::Triple &Triple = TC.getTriple(); 577 bool IsWindows = Triple.isOSWindows(); 578 579 if (TC.isBareMetal()) 580 return Triple.getArchName(); 581 582 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) 583 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows) 584 ? "armhf" 585 : "arm"; 586 587 // For historic reasons, Android library is using i686 instead of i386. 588 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid()) 589 return "i686"; 590 591 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32()) 592 return "x32"; 593 594 return llvm::Triple::getArchTypeName(TC.getArch()); 595 } 596 597 StringRef ToolChain::getOSLibName() const { 598 if (Triple.isOSDarwin()) 599 return "darwin"; 600 601 switch (Triple.getOS()) { 602 case llvm::Triple::FreeBSD: 603 return "freebsd"; 604 case llvm::Triple::NetBSD: 605 return "netbsd"; 606 case llvm::Triple::OpenBSD: 607 return "openbsd"; 608 case llvm::Triple::Solaris: 609 return "sunos"; 610 case llvm::Triple::AIX: 611 return "aix"; 612 default: 613 return getOS(); 614 } 615 } 616 617 std::string ToolChain::getCompilerRTPath() const { 618 SmallString<128> Path(getDriver().ResourceDir); 619 if (isBareMetal()) { 620 llvm::sys::path::append(Path, "lib", getOSLibName()); 621 if (!SelectedMultilibs.empty()) { 622 Path += SelectedMultilibs.back().gccSuffix(); 623 } 624 } else if (Triple.isOSUnknown()) { 625 llvm::sys::path::append(Path, "lib"); 626 } else { 627 llvm::sys::path::append(Path, "lib", getOSLibName()); 628 } 629 return std::string(Path); 630 } 631 632 std::string ToolChain::getCompilerRTBasename(const ArgList &Args, 633 StringRef Component, 634 FileType Type) const { 635 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type); 636 return llvm::sys::path::filename(CRTAbsolutePath).str(); 637 } 638 639 std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args, 640 StringRef Component, 641 FileType Type, 642 bool AddArch) const { 643 const llvm::Triple &TT = getTriple(); 644 bool IsITANMSVCWindows = 645 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); 646 647 const char *Prefix = 648 IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib"; 649 const char *Suffix; 650 switch (Type) { 651 case ToolChain::FT_Object: 652 Suffix = IsITANMSVCWindows ? ".obj" : ".o"; 653 break; 654 case ToolChain::FT_Static: 655 Suffix = IsITANMSVCWindows ? ".lib" : ".a"; 656 break; 657 case ToolChain::FT_Shared: 658 Suffix = TT.isOSWindows() 659 ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib") 660 : ".so"; 661 break; 662 } 663 664 std::string ArchAndEnv; 665 if (AddArch) { 666 StringRef Arch = getArchNameForCompilerRTLib(*this, Args); 667 const char *Env = TT.isAndroid() ? "-android" : ""; 668 ArchAndEnv = ("-" + Arch + Env).str(); 669 } 670 return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str(); 671 } 672 673 std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, 674 FileType Type) const { 675 // Check for runtime files in the new layout without the architecture first. 676 std::string CRTBasename = 677 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false); 678 SmallString<128> Path; 679 for (const auto &LibPath : getLibraryPaths()) { 680 SmallString<128> P(LibPath); 681 llvm::sys::path::append(P, CRTBasename); 682 if (getVFS().exists(P)) 683 return std::string(P); 684 if (Path.empty()) 685 Path = P; 686 } 687 if (getTriple().isOSAIX()) 688 Path.clear(); 689 690 // Check the filename for the old layout if the new one does not exist. 691 CRTBasename = 692 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true); 693 SmallString<128> OldPath(getCompilerRTPath()); 694 llvm::sys::path::append(OldPath, CRTBasename); 695 if (Path.empty() || getVFS().exists(OldPath)) 696 return std::string(OldPath); 697 698 // If none is found, use a file name from the new layout, which may get 699 // printed in an error message, aiding users in knowing what Clang is 700 // looking for. 701 return std::string(Path); 702 } 703 704 const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, 705 StringRef Component, 706 FileType Type) const { 707 return Args.MakeArgString(getCompilerRT(Args, Component, Type)); 708 } 709 710 // Android target triples contain a target version. If we don't have libraries 711 // for the exact target version, we should fall back to the next newest version 712 // or a versionless path, if any. 713 std::optional<std::string> 714 ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const { 715 llvm::Triple TripleWithoutLevel(getTriple()); 716 TripleWithoutLevel.setEnvironmentName("android"); // remove any version number 717 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str(); 718 unsigned TripleVersion = getTriple().getEnvironmentVersion().getMajor(); 719 unsigned BestVersion = 0; 720 721 SmallString<32> TripleDir; 722 bool UsingUnversionedDir = false; 723 std::error_code EC; 724 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE; 725 !EC && LI != LE; LI = LI.increment(EC)) { 726 StringRef DirName = llvm::sys::path::filename(LI->path()); 727 StringRef DirNameSuffix = DirName; 728 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) { 729 if (DirNameSuffix.empty() && TripleDir.empty()) { 730 TripleDir = DirName; 731 UsingUnversionedDir = true; 732 } else { 733 unsigned Version; 734 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion && 735 Version < TripleVersion) { 736 BestVersion = Version; 737 TripleDir = DirName; 738 UsingUnversionedDir = false; 739 } 740 } 741 } 742 } 743 744 if (TripleDir.empty()) 745 return {}; 746 747 SmallString<128> P(BaseDir); 748 llvm::sys::path::append(P, TripleDir); 749 if (UsingUnversionedDir) 750 D.Diag(diag::warn_android_unversioned_fallback) << P << getTripleString(); 751 return std::string(P); 752 } 753 754 std::optional<std::string> 755 ToolChain::getTargetSubDirPath(StringRef BaseDir) const { 756 auto getPathForTriple = 757 [&](const llvm::Triple &Triple) -> std::optional<std::string> { 758 SmallString<128> P(BaseDir); 759 llvm::sys::path::append(P, Triple.str()); 760 if (getVFS().exists(P)) 761 return std::string(P); 762 return {}; 763 }; 764 765 if (auto Path = getPathForTriple(getTriple())) 766 return *Path; 767 768 // When building with per target runtime directories, various ways of naming 769 // the Arm architecture may have been normalised to simply "arm". 770 // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm". 771 // Since an armv8l system can use libraries built for earlier architecture 772 // versions assuming endian and float ABI match. 773 // 774 // Original triple: armv8l-unknown-linux-gnueabihf 775 // Runtime triple: arm-unknown-linux-gnueabihf 776 // 777 // We do not do this for armeb (big endian) because doing so could make us 778 // select little endian libraries. In addition, all known armeb triples only 779 // use the "armeb" architecture name. 780 // 781 // M profile Arm is bare metal and we know they will not be using the per 782 // target runtime directory layout. 783 if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) { 784 llvm::Triple ArmTriple = getTriple(); 785 ArmTriple.setArch(Triple::arm); 786 if (auto Path = getPathForTriple(ArmTriple)) 787 return *Path; 788 } 789 790 if (getTriple().isAndroid()) 791 return getFallbackAndroidTargetPath(BaseDir); 792 793 return {}; 794 } 795 796 std::optional<std::string> ToolChain::getRuntimePath() const { 797 SmallString<128> P(D.ResourceDir); 798 llvm::sys::path::append(P, "lib"); 799 if (auto Ret = getTargetSubDirPath(P)) 800 return Ret; 801 // Darwin does not use per-target runtime directory. 802 if (Triple.isOSDarwin()) 803 return {}; 804 llvm::sys::path::append(P, Triple.str()); 805 return std::string(P); 806 } 807 808 std::optional<std::string> ToolChain::getStdlibPath() const { 809 SmallString<128> P(D.Dir); 810 llvm::sys::path::append(P, "..", "lib"); 811 return getTargetSubDirPath(P); 812 } 813 814 std::optional<std::string> ToolChain::getStdlibIncludePath() const { 815 SmallString<128> P(D.Dir); 816 llvm::sys::path::append(P, "..", "include"); 817 return getTargetSubDirPath(P); 818 } 819 820 ToolChain::path_list ToolChain::getArchSpecificLibPaths() const { 821 path_list Paths; 822 823 auto AddPath = [&](const ArrayRef<StringRef> &SS) { 824 SmallString<128> Path(getDriver().ResourceDir); 825 llvm::sys::path::append(Path, "lib"); 826 for (auto &S : SS) 827 llvm::sys::path::append(Path, S); 828 Paths.push_back(std::string(Path)); 829 }; 830 831 AddPath({getTriple().str()}); 832 AddPath({getOSLibName(), llvm::Triple::getArchTypeName(getArch())}); 833 return Paths; 834 } 835 836 bool ToolChain::needsProfileRT(const ArgList &Args) { 837 if (Args.hasArg(options::OPT_noprofilelib)) 838 return false; 839 840 return Args.hasArg(options::OPT_fprofile_generate) || 841 Args.hasArg(options::OPT_fprofile_generate_EQ) || 842 Args.hasArg(options::OPT_fcs_profile_generate) || 843 Args.hasArg(options::OPT_fcs_profile_generate_EQ) || 844 Args.hasArg(options::OPT_fprofile_instr_generate) || 845 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || 846 Args.hasArg(options::OPT_fcreate_profile) || 847 Args.hasArg(options::OPT_forder_file_instrumentation); 848 } 849 850 bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) { 851 return Args.hasArg(options::OPT_coverage) || 852 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, 853 false); 854 } 855 856 Tool *ToolChain::SelectTool(const JobAction &JA) const { 857 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang(); 858 if (getDriver().ShouldUseClangCompiler(JA)) return getClang(); 859 Action::ActionClass AC = JA.getKind(); 860 if (AC == Action::AssembleJobClass && useIntegratedAs() && 861 !getTriple().isOSAIX()) 862 return getClangAs(); 863 return getTool(AC); 864 } 865 866 std::string ToolChain::GetFilePath(const char *Name) const { 867 return D.GetFilePath(Name, *this); 868 } 869 870 std::string ToolChain::GetProgramPath(const char *Name) const { 871 return D.GetProgramPath(Name, *this); 872 } 873 874 std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { 875 if (LinkerIsLLD) 876 *LinkerIsLLD = false; 877 878 // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is 879 // considered as the linker flavor, e.g. "bfd", "gold", or "lld". 880 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ); 881 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; 882 883 // --ld-path= takes precedence over -fuse-ld= and specifies the executable 884 // name. -B, COMPILER_PATH and PATH and consulted if the value does not 885 // contain a path component separator. 886 // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary 887 // that --ld-path= points to is lld. 888 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) { 889 std::string Path(A->getValue()); 890 if (!Path.empty()) { 891 if (llvm::sys::path::parent_path(Path).empty()) 892 Path = GetProgramPath(A->getValue()); 893 if (llvm::sys::fs::can_execute(Path)) { 894 if (LinkerIsLLD) 895 *LinkerIsLLD = UseLinker == "lld"; 896 return std::string(Path); 897 } 898 } 899 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); 900 return GetProgramPath(getDefaultLinker()); 901 } 902 // If we're passed -fuse-ld= with no argument, or with the argument ld, 903 // then use whatever the default system linker is. 904 if (UseLinker.empty() || UseLinker == "ld") { 905 const char *DefaultLinker = getDefaultLinker(); 906 if (llvm::sys::path::is_absolute(DefaultLinker)) 907 return std::string(DefaultLinker); 908 else 909 return GetProgramPath(DefaultLinker); 910 } 911 912 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking 913 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64." 914 // to a relative path is surprising. This is more complex due to priorities 915 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead. 916 if (UseLinker.contains('/')) 917 getDriver().Diag(diag::warn_drv_fuse_ld_path); 918 919 if (llvm::sys::path::is_absolute(UseLinker)) { 920 // If we're passed what looks like an absolute path, don't attempt to 921 // second-guess that. 922 if (llvm::sys::fs::can_execute(UseLinker)) 923 return std::string(UseLinker); 924 } else { 925 llvm::SmallString<8> LinkerName; 926 if (Triple.isOSDarwin()) 927 LinkerName.append("ld64."); 928 else 929 LinkerName.append("ld."); 930 LinkerName.append(UseLinker); 931 932 std::string LinkerPath(GetProgramPath(LinkerName.c_str())); 933 if (llvm::sys::fs::can_execute(LinkerPath)) { 934 if (LinkerIsLLD) 935 *LinkerIsLLD = UseLinker == "lld"; 936 return LinkerPath; 937 } 938 } 939 940 if (A) 941 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); 942 943 return GetProgramPath(getDefaultLinker()); 944 } 945 946 std::string ToolChain::GetStaticLibToolPath() const { 947 // TODO: Add support for static lib archiving on Windows 948 if (Triple.isOSDarwin()) 949 return GetProgramPath("libtool"); 950 return GetProgramPath("llvm-ar"); 951 } 952 953 types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { 954 types::ID id = types::lookupTypeForExtension(Ext); 955 956 // Flang always runs the preprocessor and has no notion of "preprocessed 957 // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating 958 // them differently. 959 if (D.IsFlangMode() && id == types::TY_PP_Fortran) 960 id = types::TY_Fortran; 961 962 return id; 963 } 964 965 bool ToolChain::HasNativeLLVMSupport() const { 966 return false; 967 } 968 969 bool ToolChain::isCrossCompiling() const { 970 llvm::Triple HostTriple(LLVM_HOST_TRIPLE); 971 switch (HostTriple.getArch()) { 972 // The A32/T32/T16 instruction sets are not separate architectures in this 973 // context. 974 case llvm::Triple::arm: 975 case llvm::Triple::armeb: 976 case llvm::Triple::thumb: 977 case llvm::Triple::thumbeb: 978 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb && 979 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb; 980 default: 981 return HostTriple.getArch() != getArch(); 982 } 983 } 984 985 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { 986 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC, 987 VersionTuple()); 988 } 989 990 llvm::ExceptionHandling 991 ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const { 992 return llvm::ExceptionHandling::None; 993 } 994 995 bool ToolChain::isThreadModelSupported(const StringRef Model) const { 996 if (Model == "single") { 997 // FIXME: 'single' is only supported on ARM and WebAssembly so far. 998 return Triple.getArch() == llvm::Triple::arm || 999 Triple.getArch() == llvm::Triple::armeb || 1000 Triple.getArch() == llvm::Triple::thumb || 1001 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm(); 1002 } else if (Model == "posix") 1003 return true; 1004 1005 return false; 1006 } 1007 1008 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, 1009 types::ID InputType) const { 1010 switch (getTriple().getArch()) { 1011 default: 1012 return getTripleString(); 1013 1014 case llvm::Triple::x86_64: { 1015 llvm::Triple Triple = getTriple(); 1016 if (!Triple.isOSBinFormatMachO()) 1017 return getTripleString(); 1018 1019 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 1020 // x86_64h goes in the triple. Other -march options just use the 1021 // vanilla triple we already have. 1022 StringRef MArch = A->getValue(); 1023 if (MArch == "x86_64h") 1024 Triple.setArchName(MArch); 1025 } 1026 return Triple.getTriple(); 1027 } 1028 case llvm::Triple::aarch64: { 1029 llvm::Triple Triple = getTriple(); 1030 if (!Triple.isOSBinFormatMachO()) 1031 return getTripleString(); 1032 1033 if (Triple.isArm64e()) 1034 return getTripleString(); 1035 1036 // FIXME: older versions of ld64 expect the "arm64" component in the actual 1037 // triple string and query it to determine whether an LTO file can be 1038 // handled. Remove this when we don't care any more. 1039 Triple.setArchName("arm64"); 1040 return Triple.getTriple(); 1041 } 1042 case llvm::Triple::aarch64_32: 1043 return getTripleString(); 1044 case llvm::Triple::arm: 1045 case llvm::Triple::armeb: 1046 case llvm::Triple::thumb: 1047 case llvm::Triple::thumbeb: { 1048 llvm::Triple Triple = getTriple(); 1049 tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple); 1050 tools::arm::setFloatABIInTriple(getDriver(), Args, Triple); 1051 return Triple.getTriple(); 1052 } 1053 } 1054 } 1055 1056 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 1057 types::ID InputType) const { 1058 return ComputeLLVMTriple(Args, InputType); 1059 } 1060 1061 std::string ToolChain::computeSysRoot() const { 1062 return D.SysRoot; 1063 } 1064 1065 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1066 ArgStringList &CC1Args) const { 1067 // Each toolchain should provide the appropriate include flags. 1068 } 1069 1070 void ToolChain::addClangTargetOptions( 1071 const ArgList &DriverArgs, ArgStringList &CC1Args, 1072 Action::OffloadKind DeviceOffloadKind) const {} 1073 1074 void ToolChain::addClangCC1ASTargetOptions(const ArgList &Args, 1075 ArgStringList &CC1ASArgs) const {} 1076 1077 void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} 1078 1079 void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, 1080 llvm::opt::ArgStringList &CmdArgs) const { 1081 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args)) 1082 return; 1083 1084 CmdArgs.push_back(getCompilerRTArgString(Args, "profile")); 1085 } 1086 1087 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( 1088 const ArgList &Args) const { 1089 if (runtimeLibType) 1090 return *runtimeLibType; 1091 1092 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ); 1093 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB; 1094 1095 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB! 1096 if (LibName == "compiler-rt") 1097 runtimeLibType = ToolChain::RLT_CompilerRT; 1098 else if (LibName == "libgcc") 1099 runtimeLibType = ToolChain::RLT_Libgcc; 1100 else if (LibName == "platform") 1101 runtimeLibType = GetDefaultRuntimeLibType(); 1102 else { 1103 if (A) 1104 getDriver().Diag(diag::err_drv_invalid_rtlib_name) 1105 << A->getAsString(Args); 1106 1107 runtimeLibType = GetDefaultRuntimeLibType(); 1108 } 1109 1110 return *runtimeLibType; 1111 } 1112 1113 ToolChain::UnwindLibType ToolChain::GetUnwindLibType( 1114 const ArgList &Args) const { 1115 if (unwindLibType) 1116 return *unwindLibType; 1117 1118 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); 1119 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB; 1120 1121 if (LibName == "none") 1122 unwindLibType = ToolChain::UNW_None; 1123 else if (LibName == "platform" || LibName == "") { 1124 ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); 1125 if (RtLibType == ToolChain::RLT_CompilerRT) { 1126 if (getTriple().isAndroid() || getTriple().isOSAIX()) 1127 unwindLibType = ToolChain::UNW_CompilerRT; 1128 else 1129 unwindLibType = ToolChain::UNW_None; 1130 } else if (RtLibType == ToolChain::RLT_Libgcc) 1131 unwindLibType = ToolChain::UNW_Libgcc; 1132 } else if (LibName == "libunwind") { 1133 if (GetRuntimeLibType(Args) == RLT_Libgcc) 1134 getDriver().Diag(diag::err_drv_incompatible_unwindlib); 1135 unwindLibType = ToolChain::UNW_CompilerRT; 1136 } else if (LibName == "libgcc") 1137 unwindLibType = ToolChain::UNW_Libgcc; 1138 else { 1139 if (A) 1140 getDriver().Diag(diag::err_drv_invalid_unwindlib_name) 1141 << A->getAsString(Args); 1142 1143 unwindLibType = GetDefaultUnwindLibType(); 1144 } 1145 1146 return *unwindLibType; 1147 } 1148 1149 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 1150 if (cxxStdlibType) 1151 return *cxxStdlibType; 1152 1153 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1154 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB; 1155 1156 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB! 1157 if (LibName == "libc++") 1158 cxxStdlibType = ToolChain::CST_Libcxx; 1159 else if (LibName == "libstdc++") 1160 cxxStdlibType = ToolChain::CST_Libstdcxx; 1161 else if (LibName == "platform") 1162 cxxStdlibType = GetDefaultCXXStdlibType(); 1163 else { 1164 if (A) 1165 getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1166 << A->getAsString(Args); 1167 1168 cxxStdlibType = GetDefaultCXXStdlibType(); 1169 } 1170 1171 return *cxxStdlibType; 1172 } 1173 1174 /// Utility function to add a system include directory to CC1 arguments. 1175 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, 1176 ArgStringList &CC1Args, 1177 const Twine &Path) { 1178 CC1Args.push_back("-internal-isystem"); 1179 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1180 } 1181 1182 /// Utility function to add a system include directory with extern "C" 1183 /// semantics to CC1 arguments. 1184 /// 1185 /// Note that this should be used rarely, and only for directories that 1186 /// historically and for legacy reasons are treated as having implicit extern 1187 /// "C" semantics. These semantics are *ignored* by and large today, but its 1188 /// important to preserve the preprocessor changes resulting from the 1189 /// classification. 1190 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs, 1191 ArgStringList &CC1Args, 1192 const Twine &Path) { 1193 CC1Args.push_back("-internal-externc-isystem"); 1194 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1195 } 1196 1197 void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, 1198 ArgStringList &CC1Args, 1199 const Twine &Path) { 1200 if (llvm::sys::fs::exists(Path)) 1201 addExternCSystemInclude(DriverArgs, CC1Args, Path); 1202 } 1203 1204 /// Utility function to add a list of system include directories to CC1. 1205 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, 1206 ArgStringList &CC1Args, 1207 ArrayRef<StringRef> Paths) { 1208 for (const auto &Path : Paths) { 1209 CC1Args.push_back("-internal-isystem"); 1210 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1211 } 1212 } 1213 1214 /*static*/ std::string ToolChain::concat(StringRef Path, const Twine &A, 1215 const Twine &B, const Twine &C, 1216 const Twine &D) { 1217 SmallString<128> Result(Path); 1218 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D); 1219 return std::string(Result); 1220 } 1221 1222 std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const { 1223 std::error_code EC; 1224 int MaxVersion = 0; 1225 std::string MaxVersionString; 1226 SmallString<128> Path(IncludePath); 1227 llvm::sys::path::append(Path, "c++"); 1228 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE; 1229 !EC && LI != LE; LI = LI.increment(EC)) { 1230 StringRef VersionText = llvm::sys::path::filename(LI->path()); 1231 int Version; 1232 if (VersionText[0] == 'v' && 1233 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { 1234 if (Version > MaxVersion) { 1235 MaxVersion = Version; 1236 MaxVersionString = std::string(VersionText); 1237 } 1238 } 1239 } 1240 if (!MaxVersion) 1241 return ""; 1242 return MaxVersionString; 1243 } 1244 1245 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1246 ArgStringList &CC1Args) const { 1247 // Header search paths should be handled by each of the subclasses. 1248 // Historically, they have not been, and instead have been handled inside of 1249 // the CC1-layer frontend. As the logic is hoisted out, this generic function 1250 // will slowly stop being called. 1251 // 1252 // While it is being called, replicate a bit of a hack to propagate the 1253 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++ 1254 // header search paths with it. Once all systems are overriding this 1255 // function, the CC1 flag and this line can be removed. 1256 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); 1257 } 1258 1259 void ToolChain::AddClangCXXStdlibIsystemArgs( 1260 const llvm::opt::ArgList &DriverArgs, 1261 llvm::opt::ArgStringList &CC1Args) const { 1262 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem); 1263 // This intentionally only looks at -nostdinc++, and not -nostdinc or 1264 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain 1265 // setups with non-standard search logic for the C++ headers, while still 1266 // allowing users of the toolchain to bring their own C++ headers. Such a 1267 // toolchain likely also has non-standard search logic for the C headers and 1268 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should 1269 // still work in that case and only be suppressed by an explicit -nostdinc++ 1270 // in a project using the toolchain. 1271 if (!DriverArgs.hasArg(options::OPT_nostdincxx)) 1272 for (const auto &P : 1273 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem)) 1274 addSystemInclude(DriverArgs, CC1Args, P); 1275 } 1276 1277 bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const { 1278 return getDriver().CCCIsCXX() && 1279 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 1280 options::OPT_nostdlibxx); 1281 } 1282 1283 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 1284 ArgStringList &CmdArgs) const { 1285 assert(!Args.hasArg(options::OPT_nostdlibxx) && 1286 "should not have called this"); 1287 CXXStdlibType Type = GetCXXStdlibType(Args); 1288 1289 switch (Type) { 1290 case ToolChain::CST_Libcxx: 1291 CmdArgs.push_back("-lc++"); 1292 if (Args.hasArg(options::OPT_fexperimental_library)) 1293 CmdArgs.push_back("-lc++experimental"); 1294 break; 1295 1296 case ToolChain::CST_Libstdcxx: 1297 CmdArgs.push_back("-lstdc++"); 1298 break; 1299 } 1300 } 1301 1302 void ToolChain::AddFilePathLibArgs(const ArgList &Args, 1303 ArgStringList &CmdArgs) const { 1304 for (const auto &LibPath : getFilePaths()) 1305 if(LibPath.length() > 0) 1306 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); 1307 } 1308 1309 void ToolChain::AddCCKextLibArgs(const ArgList &Args, 1310 ArgStringList &CmdArgs) const { 1311 CmdArgs.push_back("-lcc_kext"); 1312 } 1313 1314 bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, 1315 std::string &Path) const { 1316 // Don't implicitly link in mode-changing libraries in a shared library, since 1317 // this can have very deleterious effects. See the various links from 1318 // https://github.com/llvm/llvm-project/issues/57589 for more information. 1319 bool Default = !Args.hasArgNoClaim(options::OPT_shared); 1320 1321 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed 1322 // (to keep the linker options consistent with gcc and clang itself). 1323 if (Default && !isOptimizationLevelFast(Args)) { 1324 // Check if -ffast-math or -funsafe-math. 1325 Arg *A = Args.getLastArg( 1326 options::OPT_ffast_math, options::OPT_fno_fast_math, 1327 options::OPT_funsafe_math_optimizations, 1328 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ); 1329 1330 if (!A || A->getOption().getID() == options::OPT_fno_fast_math || 1331 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) 1332 Default = false; 1333 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) { 1334 StringRef Model = A->getValue(); 1335 if (Model != "fast") 1336 Default = false; 1337 } 1338 } 1339 1340 // Whatever decision came as a result of the above implicit settings, either 1341 // -mdaz-ftz or -mno-daz-ftz is capable of overriding it. 1342 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default)) 1343 return false; 1344 1345 // If crtfastmath.o exists add it to the arguments. 1346 Path = GetFilePath("crtfastmath.o"); 1347 return (Path != "crtfastmath.o"); // Not found. 1348 } 1349 1350 bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args, 1351 ArgStringList &CmdArgs) const { 1352 std::string Path; 1353 if (isFastMathRuntimeAvailable(Args, Path)) { 1354 CmdArgs.push_back(Args.MakeArgString(Path)); 1355 return true; 1356 } 1357 1358 return false; 1359 } 1360 1361 Expected<SmallVector<std::string>> 1362 ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const { 1363 return SmallVector<std::string>(); 1364 } 1365 1366 SanitizerMask ToolChain::getSupportedSanitizers() const { 1367 // Return sanitizers which don't require runtime support and are not 1368 // platform dependent. 1369 1370 SanitizerMask Res = 1371 (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | 1372 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | 1373 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | 1374 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow | 1375 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion | 1376 SanitizerKind::Nullability | SanitizerKind::LocalBounds; 1377 if (getTriple().getArch() == llvm::Triple::x86 || 1378 getTriple().getArch() == llvm::Triple::x86_64 || 1379 getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() || 1380 getTriple().isAArch64() || getTriple().isRISCV() || 1381 getTriple().isLoongArch64()) 1382 Res |= SanitizerKind::CFIICall; 1383 if (getTriple().getArch() == llvm::Triple::x86_64 || 1384 getTriple().isAArch64(64) || getTriple().isRISCV()) 1385 Res |= SanitizerKind::ShadowCallStack; 1386 if (getTriple().isAArch64(64)) 1387 Res |= SanitizerKind::MemTag; 1388 return Res; 1389 } 1390 1391 void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, 1392 ArgStringList &CC1Args) const {} 1393 1394 void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, 1395 ArgStringList &CC1Args) const {} 1396 1397 llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> 1398 ToolChain::getDeviceLibs(const ArgList &DriverArgs) const { 1399 return {}; 1400 } 1401 1402 void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs, 1403 ArgStringList &CC1Args) const {} 1404 1405 static VersionTuple separateMSVCFullVersion(unsigned Version) { 1406 if (Version < 100) 1407 return VersionTuple(Version); 1408 1409 if (Version < 10000) 1410 return VersionTuple(Version / 100, Version % 100); 1411 1412 unsigned Build = 0, Factor = 1; 1413 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) 1414 Build = Build + (Version % 10) * Factor; 1415 return VersionTuple(Version / 100, Version % 100, Build); 1416 } 1417 1418 VersionTuple 1419 ToolChain::computeMSVCVersion(const Driver *D, 1420 const llvm::opt::ArgList &Args) const { 1421 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); 1422 const Arg *MSCompatibilityVersion = 1423 Args.getLastArg(options::OPT_fms_compatibility_version); 1424 1425 if (MSCVersion && MSCompatibilityVersion) { 1426 if (D) 1427 D->Diag(diag::err_drv_argument_not_allowed_with) 1428 << MSCVersion->getAsString(Args) 1429 << MSCompatibilityVersion->getAsString(Args); 1430 return VersionTuple(); 1431 } 1432 1433 if (MSCompatibilityVersion) { 1434 VersionTuple MSVT; 1435 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) { 1436 if (D) 1437 D->Diag(diag::err_drv_invalid_value) 1438 << MSCompatibilityVersion->getAsString(Args) 1439 << MSCompatibilityVersion->getValue(); 1440 } else { 1441 return MSVT; 1442 } 1443 } 1444 1445 if (MSCVersion) { 1446 unsigned Version = 0; 1447 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) { 1448 if (D) 1449 D->Diag(diag::err_drv_invalid_value) 1450 << MSCVersion->getAsString(Args) << MSCVersion->getValue(); 1451 } else { 1452 return separateMSVCFullVersion(Version); 1453 } 1454 } 1455 1456 return VersionTuple(); 1457 } 1458 1459 llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs( 1460 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, 1461 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const { 1462 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1463 const OptTable &Opts = getDriver().getOpts(); 1464 bool Modified = false; 1465 1466 // Handle -Xopenmp-target flags 1467 for (auto *A : Args) { 1468 // Exclude flags which may only apply to the host toolchain. 1469 // Do not exclude flags when the host triple (AuxTriple) 1470 // matches the current toolchain triple. If it is not present 1471 // at all, target and host share a toolchain. 1472 if (A->getOption().matches(options::OPT_m_Group)) { 1473 // Pass code object version to device toolchain 1474 // to correctly set metadata in intermediate files. 1475 if (SameTripleAsHost || 1476 A->getOption().matches(options::OPT_mcode_object_version_EQ)) 1477 DAL->append(A); 1478 else 1479 Modified = true; 1480 continue; 1481 } 1482 1483 unsigned Index; 1484 unsigned Prev; 1485 bool XOpenMPTargetNoTriple = 1486 A->getOption().matches(options::OPT_Xopenmp_target); 1487 1488 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) { 1489 llvm::Triple TT(getOpenMPTriple(A->getValue(0))); 1490 1491 // Passing device args: -Xopenmp-target=<triple> -opt=val. 1492 if (TT.getTriple() == getTripleString()) 1493 Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 1494 else 1495 continue; 1496 } else if (XOpenMPTargetNoTriple) { 1497 // Passing device args: -Xopenmp-target -opt=val. 1498 Index = Args.getBaseArgs().MakeIndex(A->getValue(0)); 1499 } else { 1500 DAL->append(A); 1501 continue; 1502 } 1503 1504 // Parse the argument to -Xopenmp-target. 1505 Prev = Index; 1506 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index)); 1507 if (!XOpenMPTargetArg || Index > Prev + 1) { 1508 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) 1509 << A->getAsString(Args); 1510 continue; 1511 } 1512 if (XOpenMPTargetNoTriple && XOpenMPTargetArg && 1513 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) { 1514 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple); 1515 continue; 1516 } 1517 XOpenMPTargetArg->setBaseArg(A); 1518 A = XOpenMPTargetArg.release(); 1519 AllocatedArgs.push_back(A); 1520 DAL->append(A); 1521 Modified = true; 1522 } 1523 1524 if (Modified) 1525 return DAL; 1526 1527 delete DAL; 1528 return nullptr; 1529 } 1530 1531 // TODO: Currently argument values separated by space e.g. 1532 // -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be 1533 // fixed. 1534 void ToolChain::TranslateXarchArgs( 1535 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, 1536 llvm::opt::DerivedArgList *DAL, 1537 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1538 const OptTable &Opts = getDriver().getOpts(); 1539 unsigned ValuePos = 1; 1540 if (A->getOption().matches(options::OPT_Xarch_device) || 1541 A->getOption().matches(options::OPT_Xarch_host)) 1542 ValuePos = 0; 1543 1544 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos)); 1545 unsigned Prev = Index; 1546 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index)); 1547 1548 // If the argument parsing failed or more than one argument was 1549 // consumed, the -Xarch_ argument's parameter tried to consume 1550 // extra arguments. Emit an error and ignore. 1551 // 1552 // We also want to disallow any options which would alter the 1553 // driver behavior; that isn't going to work in our model. We 1554 // use options::NoXarchOption to control this. 1555 if (!XarchArg || Index > Prev + 1) { 1556 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 1557 << A->getAsString(Args); 1558 return; 1559 } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) { 1560 auto &Diags = getDriver().getDiags(); 1561 unsigned DiagID = 1562 Diags.getCustomDiagID(DiagnosticsEngine::Error, 1563 "invalid Xarch argument: '%0', not all driver " 1564 "options can be forwared via Xarch argument"); 1565 Diags.Report(DiagID) << A->getAsString(Args); 1566 return; 1567 } 1568 XarchArg->setBaseArg(A); 1569 A = XarchArg.release(); 1570 if (!AllocatedArgs) 1571 DAL->AddSynthesizedArg(A); 1572 else 1573 AllocatedArgs->push_back(A); 1574 } 1575 1576 llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( 1577 const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 1578 Action::OffloadKind OFK, 1579 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1580 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1581 bool Modified = false; 1582 1583 bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host; 1584 for (Arg *A : Args) { 1585 bool NeedTrans = false; 1586 bool Skip = false; 1587 if (A->getOption().matches(options::OPT_Xarch_device)) { 1588 NeedTrans = IsDevice; 1589 Skip = !IsDevice; 1590 } else if (A->getOption().matches(options::OPT_Xarch_host)) { 1591 NeedTrans = !IsDevice; 1592 Skip = IsDevice; 1593 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) { 1594 // Do not translate -Xarch_ options for non CUDA/HIP toolchain since 1595 // they may need special translation. 1596 // Skip this argument unless the architecture matches BoundArch 1597 if (BoundArch.empty() || A->getValue(0) != BoundArch) 1598 Skip = true; 1599 else 1600 NeedTrans = true; 1601 } 1602 if (NeedTrans || Skip) 1603 Modified = true; 1604 if (NeedTrans) 1605 TranslateXarchArgs(Args, A, DAL, AllocatedArgs); 1606 if (!Skip) 1607 DAL->append(A); 1608 } 1609 1610 if (Modified) 1611 return DAL; 1612 1613 delete DAL; 1614 return nullptr; 1615 } 1616