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