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