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