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::arm: 1103 case llvm::Triple::armeb: 1104 case llvm::Triple::thumb: 1105 case llvm::Triple::thumbeb: { 1106 llvm::Triple Triple = getTriple(); 1107 tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple); 1108 tools::arm::setFloatABIInTriple(getDriver(), Args, Triple); 1109 return Triple.getTriple(); 1110 } 1111 } 1112 } 1113 1114 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 1115 types::ID InputType) const { 1116 return ComputeLLVMTriple(Args, InputType); 1117 } 1118 1119 std::string ToolChain::computeSysRoot() const { 1120 return D.SysRoot; 1121 } 1122 1123 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1124 ArgStringList &CC1Args) const { 1125 // Each toolchain should provide the appropriate include flags. 1126 } 1127 1128 void ToolChain::addClangTargetOptions( 1129 const ArgList &DriverArgs, ArgStringList &CC1Args, 1130 Action::OffloadKind DeviceOffloadKind) const {} 1131 1132 void ToolChain::addClangCC1ASTargetOptions(const ArgList &Args, 1133 ArgStringList &CC1ASArgs) const {} 1134 1135 void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} 1136 1137 void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, 1138 llvm::opt::ArgStringList &CmdArgs) const { 1139 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args)) 1140 return; 1141 1142 CmdArgs.push_back(getCompilerRTArgString(Args, "profile")); 1143 } 1144 1145 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( 1146 const ArgList &Args) const { 1147 if (runtimeLibType) 1148 return *runtimeLibType; 1149 1150 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ); 1151 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB; 1152 1153 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB! 1154 if (LibName == "compiler-rt") 1155 runtimeLibType = ToolChain::RLT_CompilerRT; 1156 else if (LibName == "libgcc") 1157 runtimeLibType = ToolChain::RLT_Libgcc; 1158 else if (LibName == "platform") 1159 runtimeLibType = GetDefaultRuntimeLibType(); 1160 else { 1161 if (A) 1162 getDriver().Diag(diag::err_drv_invalid_rtlib_name) 1163 << A->getAsString(Args); 1164 1165 runtimeLibType = GetDefaultRuntimeLibType(); 1166 } 1167 1168 return *runtimeLibType; 1169 } 1170 1171 ToolChain::UnwindLibType ToolChain::GetUnwindLibType( 1172 const ArgList &Args) const { 1173 if (unwindLibType) 1174 return *unwindLibType; 1175 1176 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); 1177 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB; 1178 1179 if (LibName == "none") 1180 unwindLibType = ToolChain::UNW_None; 1181 else if (LibName == "platform" || LibName == "") { 1182 ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); 1183 if (RtLibType == ToolChain::RLT_CompilerRT) { 1184 if (getTriple().isAndroid() || getTriple().isOSAIX()) 1185 unwindLibType = ToolChain::UNW_CompilerRT; 1186 else 1187 unwindLibType = ToolChain::UNW_None; 1188 } else if (RtLibType == ToolChain::RLT_Libgcc) 1189 unwindLibType = ToolChain::UNW_Libgcc; 1190 } else if (LibName == "libunwind") { 1191 if (GetRuntimeLibType(Args) == RLT_Libgcc) 1192 getDriver().Diag(diag::err_drv_incompatible_unwindlib); 1193 unwindLibType = ToolChain::UNW_CompilerRT; 1194 } else if (LibName == "libgcc") 1195 unwindLibType = ToolChain::UNW_Libgcc; 1196 else { 1197 if (A) 1198 getDriver().Diag(diag::err_drv_invalid_unwindlib_name) 1199 << A->getAsString(Args); 1200 1201 unwindLibType = GetDefaultUnwindLibType(); 1202 } 1203 1204 return *unwindLibType; 1205 } 1206 1207 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 1208 if (cxxStdlibType) 1209 return *cxxStdlibType; 1210 1211 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1212 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB; 1213 1214 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB! 1215 if (LibName == "libc++") 1216 cxxStdlibType = ToolChain::CST_Libcxx; 1217 else if (LibName == "libstdc++") 1218 cxxStdlibType = ToolChain::CST_Libstdcxx; 1219 else if (LibName == "platform") 1220 cxxStdlibType = GetDefaultCXXStdlibType(); 1221 else { 1222 if (A) 1223 getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1224 << A->getAsString(Args); 1225 1226 cxxStdlibType = GetDefaultCXXStdlibType(); 1227 } 1228 1229 return *cxxStdlibType; 1230 } 1231 1232 /// Utility function to add a system include directory to CC1 arguments. 1233 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, 1234 ArgStringList &CC1Args, 1235 const Twine &Path) { 1236 CC1Args.push_back("-internal-isystem"); 1237 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1238 } 1239 1240 /// Utility function to add a system include directory with extern "C" 1241 /// semantics to CC1 arguments. 1242 /// 1243 /// Note that this should be used rarely, and only for directories that 1244 /// historically and for legacy reasons are treated as having implicit extern 1245 /// "C" semantics. These semantics are *ignored* by and large today, but its 1246 /// important to preserve the preprocessor changes resulting from the 1247 /// classification. 1248 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs, 1249 ArgStringList &CC1Args, 1250 const Twine &Path) { 1251 CC1Args.push_back("-internal-externc-isystem"); 1252 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1253 } 1254 1255 void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, 1256 ArgStringList &CC1Args, 1257 const Twine &Path) { 1258 if (llvm::sys::fs::exists(Path)) 1259 addExternCSystemInclude(DriverArgs, CC1Args, Path); 1260 } 1261 1262 /// Utility function to add a list of system include directories to CC1. 1263 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, 1264 ArgStringList &CC1Args, 1265 ArrayRef<StringRef> Paths) { 1266 for (const auto &Path : Paths) { 1267 CC1Args.push_back("-internal-isystem"); 1268 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1269 } 1270 } 1271 1272 /*static*/ std::string ToolChain::concat(StringRef Path, const Twine &A, 1273 const Twine &B, const Twine &C, 1274 const Twine &D) { 1275 SmallString<128> Result(Path); 1276 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D); 1277 return std::string(Result); 1278 } 1279 1280 std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const { 1281 std::error_code EC; 1282 int MaxVersion = 0; 1283 std::string MaxVersionString; 1284 SmallString<128> Path(IncludePath); 1285 llvm::sys::path::append(Path, "c++"); 1286 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE; 1287 !EC && LI != LE; LI = LI.increment(EC)) { 1288 StringRef VersionText = llvm::sys::path::filename(LI->path()); 1289 int Version; 1290 if (VersionText[0] == 'v' && 1291 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { 1292 if (Version > MaxVersion) { 1293 MaxVersion = Version; 1294 MaxVersionString = std::string(VersionText); 1295 } 1296 } 1297 } 1298 if (!MaxVersion) 1299 return ""; 1300 return MaxVersionString; 1301 } 1302 1303 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1304 ArgStringList &CC1Args) const { 1305 // Header search paths should be handled by each of the subclasses. 1306 // Historically, they have not been, and instead have been handled inside of 1307 // the CC1-layer frontend. As the logic is hoisted out, this generic function 1308 // will slowly stop being called. 1309 // 1310 // While it is being called, replicate a bit of a hack to propagate the 1311 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++ 1312 // header search paths with it. Once all systems are overriding this 1313 // function, the CC1 flag and this line can be removed. 1314 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); 1315 } 1316 1317 void ToolChain::AddClangCXXStdlibIsystemArgs( 1318 const llvm::opt::ArgList &DriverArgs, 1319 llvm::opt::ArgStringList &CC1Args) const { 1320 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem); 1321 // This intentionally only looks at -nostdinc++, and not -nostdinc or 1322 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain 1323 // setups with non-standard search logic for the C++ headers, while still 1324 // allowing users of the toolchain to bring their own C++ headers. Such a 1325 // toolchain likely also has non-standard search logic for the C headers and 1326 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should 1327 // still work in that case and only be suppressed by an explicit -nostdinc++ 1328 // in a project using the toolchain. 1329 if (!DriverArgs.hasArg(options::OPT_nostdincxx)) 1330 for (const auto &P : 1331 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem)) 1332 addSystemInclude(DriverArgs, CC1Args, P); 1333 } 1334 1335 bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const { 1336 return getDriver().CCCIsCXX() && 1337 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 1338 options::OPT_nostdlibxx); 1339 } 1340 1341 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 1342 ArgStringList &CmdArgs) const { 1343 assert(!Args.hasArg(options::OPT_nostdlibxx) && 1344 "should not have called this"); 1345 CXXStdlibType Type = GetCXXStdlibType(Args); 1346 1347 switch (Type) { 1348 case ToolChain::CST_Libcxx: 1349 CmdArgs.push_back("-lc++"); 1350 if (Args.hasArg(options::OPT_fexperimental_library)) 1351 CmdArgs.push_back("-lc++experimental"); 1352 break; 1353 1354 case ToolChain::CST_Libstdcxx: 1355 CmdArgs.push_back("-lstdc++"); 1356 break; 1357 } 1358 } 1359 1360 void ToolChain::AddFilePathLibArgs(const ArgList &Args, 1361 ArgStringList &CmdArgs) const { 1362 for (const auto &LibPath : getFilePaths()) 1363 if(LibPath.length() > 0) 1364 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); 1365 } 1366 1367 void ToolChain::AddCCKextLibArgs(const ArgList &Args, 1368 ArgStringList &CmdArgs) const { 1369 CmdArgs.push_back("-lcc_kext"); 1370 } 1371 1372 bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, 1373 std::string &Path) const { 1374 // Don't implicitly link in mode-changing libraries in a shared library, since 1375 // this can have very deleterious effects. See the various links from 1376 // https://github.com/llvm/llvm-project/issues/57589 for more information. 1377 bool Default = !Args.hasArgNoClaim(options::OPT_shared); 1378 1379 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed 1380 // (to keep the linker options consistent with gcc and clang itself). 1381 if (Default && !isOptimizationLevelFast(Args)) { 1382 // Check if -ffast-math or -funsafe-math. 1383 Arg *A = Args.getLastArg( 1384 options::OPT_ffast_math, options::OPT_fno_fast_math, 1385 options::OPT_funsafe_math_optimizations, 1386 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ); 1387 1388 if (!A || A->getOption().getID() == options::OPT_fno_fast_math || 1389 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) 1390 Default = false; 1391 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) { 1392 StringRef Model = A->getValue(); 1393 if (Model != "fast" && Model != "aggressive") 1394 Default = false; 1395 } 1396 } 1397 1398 // Whatever decision came as a result of the above implicit settings, either 1399 // -mdaz-ftz or -mno-daz-ftz is capable of overriding it. 1400 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default)) 1401 return false; 1402 1403 // If crtfastmath.o exists add it to the arguments. 1404 Path = GetFilePath("crtfastmath.o"); 1405 return (Path != "crtfastmath.o"); // Not found. 1406 } 1407 1408 bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args, 1409 ArgStringList &CmdArgs) const { 1410 std::string Path; 1411 if (isFastMathRuntimeAvailable(Args, Path)) { 1412 CmdArgs.push_back(Args.MakeArgString(Path)); 1413 return true; 1414 } 1415 1416 return false; 1417 } 1418 1419 Expected<SmallVector<std::string>> 1420 ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const { 1421 return SmallVector<std::string>(); 1422 } 1423 1424 SanitizerMask ToolChain::getSupportedSanitizers() const { 1425 // Return sanitizers which don't require runtime support and are not 1426 // platform dependent. 1427 1428 SanitizerMask Res = 1429 (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | 1430 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | 1431 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | 1432 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow | 1433 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion | 1434 SanitizerKind::Nullability | SanitizerKind::LocalBounds; 1435 if (getTriple().getArch() == llvm::Triple::x86 || 1436 getTriple().getArch() == llvm::Triple::x86_64 || 1437 getTriple().getArch() == llvm::Triple::arm || 1438 getTriple().getArch() == llvm::Triple::thumb || getTriple().isWasm() || 1439 getTriple().isAArch64() || getTriple().isRISCV() || 1440 getTriple().isLoongArch64()) 1441 Res |= SanitizerKind::CFIICall; 1442 if (getTriple().getArch() == llvm::Triple::x86_64 || 1443 getTriple().isAArch64(64) || getTriple().isRISCV()) 1444 Res |= SanitizerKind::ShadowCallStack; 1445 if (getTriple().isAArch64(64)) 1446 Res |= SanitizerKind::MemTag; 1447 return Res; 1448 } 1449 1450 void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, 1451 ArgStringList &CC1Args) const {} 1452 1453 void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, 1454 ArgStringList &CC1Args) const {} 1455 1456 llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> 1457 ToolChain::getDeviceLibs(const ArgList &DriverArgs) const { 1458 return {}; 1459 } 1460 1461 void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs, 1462 ArgStringList &CC1Args) const {} 1463 1464 static VersionTuple separateMSVCFullVersion(unsigned Version) { 1465 if (Version < 100) 1466 return VersionTuple(Version); 1467 1468 if (Version < 10000) 1469 return VersionTuple(Version / 100, Version % 100); 1470 1471 unsigned Build = 0, Factor = 1; 1472 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) 1473 Build = Build + (Version % 10) * Factor; 1474 return VersionTuple(Version / 100, Version % 100, Build); 1475 } 1476 1477 VersionTuple 1478 ToolChain::computeMSVCVersion(const Driver *D, 1479 const llvm::opt::ArgList &Args) const { 1480 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); 1481 const Arg *MSCompatibilityVersion = 1482 Args.getLastArg(options::OPT_fms_compatibility_version); 1483 1484 if (MSCVersion && MSCompatibilityVersion) { 1485 if (D) 1486 D->Diag(diag::err_drv_argument_not_allowed_with) 1487 << MSCVersion->getAsString(Args) 1488 << MSCompatibilityVersion->getAsString(Args); 1489 return VersionTuple(); 1490 } 1491 1492 if (MSCompatibilityVersion) { 1493 VersionTuple MSVT; 1494 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) { 1495 if (D) 1496 D->Diag(diag::err_drv_invalid_value) 1497 << MSCompatibilityVersion->getAsString(Args) 1498 << MSCompatibilityVersion->getValue(); 1499 } else { 1500 return MSVT; 1501 } 1502 } 1503 1504 if (MSCVersion) { 1505 unsigned Version = 0; 1506 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) { 1507 if (D) 1508 D->Diag(diag::err_drv_invalid_value) 1509 << MSCVersion->getAsString(Args) << MSCVersion->getValue(); 1510 } else { 1511 return separateMSVCFullVersion(Version); 1512 } 1513 } 1514 1515 return VersionTuple(); 1516 } 1517 1518 llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs( 1519 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, 1520 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const { 1521 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1522 const OptTable &Opts = getDriver().getOpts(); 1523 bool Modified = false; 1524 1525 // Handle -Xopenmp-target flags 1526 for (auto *A : Args) { 1527 // Exclude flags which may only apply to the host toolchain. 1528 // Do not exclude flags when the host triple (AuxTriple) 1529 // matches the current toolchain triple. If it is not present 1530 // at all, target and host share a toolchain. 1531 if (A->getOption().matches(options::OPT_m_Group)) { 1532 // Pass code object version to device toolchain 1533 // to correctly set metadata in intermediate files. 1534 if (SameTripleAsHost || 1535 A->getOption().matches(options::OPT_mcode_object_version_EQ)) 1536 DAL->append(A); 1537 else 1538 Modified = true; 1539 continue; 1540 } 1541 1542 unsigned Index; 1543 unsigned Prev; 1544 bool XOpenMPTargetNoTriple = 1545 A->getOption().matches(options::OPT_Xopenmp_target); 1546 1547 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) { 1548 llvm::Triple TT(getOpenMPTriple(A->getValue(0))); 1549 1550 // Passing device args: -Xopenmp-target=<triple> -opt=val. 1551 if (TT.getTriple() == getTripleString()) 1552 Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 1553 else 1554 continue; 1555 } else if (XOpenMPTargetNoTriple) { 1556 // Passing device args: -Xopenmp-target -opt=val. 1557 Index = Args.getBaseArgs().MakeIndex(A->getValue(0)); 1558 } else { 1559 DAL->append(A); 1560 continue; 1561 } 1562 1563 // Parse the argument to -Xopenmp-target. 1564 Prev = Index; 1565 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index)); 1566 if (!XOpenMPTargetArg || Index > Prev + 1) { 1567 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) 1568 << A->getAsString(Args); 1569 continue; 1570 } 1571 if (XOpenMPTargetNoTriple && XOpenMPTargetArg && 1572 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) { 1573 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple); 1574 continue; 1575 } 1576 XOpenMPTargetArg->setBaseArg(A); 1577 A = XOpenMPTargetArg.release(); 1578 AllocatedArgs.push_back(A); 1579 DAL->append(A); 1580 Modified = true; 1581 } 1582 1583 if (Modified) 1584 return DAL; 1585 1586 delete DAL; 1587 return nullptr; 1588 } 1589 1590 // TODO: Currently argument values separated by space e.g. 1591 // -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be 1592 // fixed. 1593 void ToolChain::TranslateXarchArgs( 1594 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, 1595 llvm::opt::DerivedArgList *DAL, 1596 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1597 const OptTable &Opts = getDriver().getOpts(); 1598 unsigned ValuePos = 1; 1599 if (A->getOption().matches(options::OPT_Xarch_device) || 1600 A->getOption().matches(options::OPT_Xarch_host)) 1601 ValuePos = 0; 1602 1603 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos)); 1604 unsigned Prev = Index; 1605 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index)); 1606 1607 // If the argument parsing failed or more than one argument was 1608 // consumed, the -Xarch_ argument's parameter tried to consume 1609 // extra arguments. Emit an error and ignore. 1610 // 1611 // We also want to disallow any options which would alter the 1612 // driver behavior; that isn't going to work in our model. We 1613 // use options::NoXarchOption to control this. 1614 if (!XarchArg || Index > Prev + 1) { 1615 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 1616 << A->getAsString(Args); 1617 return; 1618 } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) { 1619 auto &Diags = getDriver().getDiags(); 1620 unsigned DiagID = 1621 Diags.getCustomDiagID(DiagnosticsEngine::Error, 1622 "invalid Xarch argument: '%0', not all driver " 1623 "options can be forwared via Xarch argument"); 1624 Diags.Report(DiagID) << A->getAsString(Args); 1625 return; 1626 } 1627 XarchArg->setBaseArg(A); 1628 A = XarchArg.release(); 1629 if (!AllocatedArgs) 1630 DAL->AddSynthesizedArg(A); 1631 else 1632 AllocatedArgs->push_back(A); 1633 } 1634 1635 llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( 1636 const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 1637 Action::OffloadKind OFK, 1638 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1639 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1640 bool Modified = false; 1641 1642 bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host; 1643 for (Arg *A : Args) { 1644 bool NeedTrans = false; 1645 bool Skip = false; 1646 if (A->getOption().matches(options::OPT_Xarch_device)) { 1647 NeedTrans = IsDevice; 1648 Skip = !IsDevice; 1649 } else if (A->getOption().matches(options::OPT_Xarch_host)) { 1650 NeedTrans = !IsDevice; 1651 Skip = IsDevice; 1652 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) { 1653 // Do not translate -Xarch_ options for non CUDA/HIP toolchain since 1654 // they may need special translation. 1655 // Skip this argument unless the architecture matches BoundArch 1656 if (BoundArch.empty() || A->getValue(0) != BoundArch) 1657 Skip = true; 1658 else 1659 NeedTrans = true; 1660 } 1661 if (NeedTrans || Skip) 1662 Modified = true; 1663 if (NeedTrans) 1664 TranslateXarchArgs(Args, A, DAL, AllocatedArgs); 1665 if (!Skip) 1666 DAL->append(A); 1667 } 1668 1669 if (Modified) 1670 return DAL; 1671 1672 delete DAL; 1673 return nullptr; 1674 } 1675