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