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 unsigned ToolChain::GetDefaultDwarfVersion() const { 431 // TODO: Remove the RISC-V special case when R_RISCV_SET_ULEB128 linker 432 // support becomes more widely available. 433 return getTriple().isRISCV() ? 4 : 5; 434 } 435 436 Tool *ToolChain::getClang() const { 437 if (!Clang) 438 Clang.reset(new tools::Clang(*this, useIntegratedBackend())); 439 return Clang.get(); 440 } 441 442 Tool *ToolChain::getFlang() const { 443 if (!Flang) 444 Flang.reset(new tools::Flang(*this)); 445 return Flang.get(); 446 } 447 448 Tool *ToolChain::buildAssembler() const { 449 return new tools::ClangAs(*this); 450 } 451 452 Tool *ToolChain::buildLinker() const { 453 llvm_unreachable("Linking is not supported by this toolchain"); 454 } 455 456 Tool *ToolChain::buildStaticLibTool() const { 457 llvm_unreachable("Creating static lib is not supported by this toolchain"); 458 } 459 460 Tool *ToolChain::getAssemble() const { 461 if (!Assemble) 462 Assemble.reset(buildAssembler()); 463 return Assemble.get(); 464 } 465 466 Tool *ToolChain::getClangAs() const { 467 if (!Assemble) 468 Assemble.reset(new tools::ClangAs(*this)); 469 return Assemble.get(); 470 } 471 472 Tool *ToolChain::getLink() const { 473 if (!Link) 474 Link.reset(buildLinker()); 475 return Link.get(); 476 } 477 478 Tool *ToolChain::getStaticLibTool() const { 479 if (!StaticLibTool) 480 StaticLibTool.reset(buildStaticLibTool()); 481 return StaticLibTool.get(); 482 } 483 484 Tool *ToolChain::getIfsMerge() const { 485 if (!IfsMerge) 486 IfsMerge.reset(new tools::ifstool::Merger(*this)); 487 return IfsMerge.get(); 488 } 489 490 Tool *ToolChain::getOffloadBundler() const { 491 if (!OffloadBundler) 492 OffloadBundler.reset(new tools::OffloadBundler(*this)); 493 return OffloadBundler.get(); 494 } 495 496 Tool *ToolChain::getOffloadPackager() const { 497 if (!OffloadPackager) 498 OffloadPackager.reset(new tools::OffloadPackager(*this)); 499 return OffloadPackager.get(); 500 } 501 502 Tool *ToolChain::getLinkerWrapper() const { 503 if (!LinkerWrapper) 504 LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink())); 505 return LinkerWrapper.get(); 506 } 507 508 Tool *ToolChain::getTool(Action::ActionClass AC) const { 509 switch (AC) { 510 case Action::AssembleJobClass: 511 return getAssemble(); 512 513 case Action::IfsMergeJobClass: 514 return getIfsMerge(); 515 516 case Action::LinkJobClass: 517 return getLink(); 518 519 case Action::StaticLibJobClass: 520 return getStaticLibTool(); 521 522 case Action::InputClass: 523 case Action::BindArchClass: 524 case Action::OffloadClass: 525 case Action::LipoJobClass: 526 case Action::DsymutilJobClass: 527 case Action::VerifyDebugInfoJobClass: 528 case Action::BinaryAnalyzeJobClass: 529 llvm_unreachable("Invalid tool kind."); 530 531 case Action::CompileJobClass: 532 case Action::PrecompileJobClass: 533 case Action::PreprocessJobClass: 534 case Action::ExtractAPIJobClass: 535 case Action::AnalyzeJobClass: 536 case Action::MigrateJobClass: 537 case Action::VerifyPCHJobClass: 538 case Action::BackendJobClass: 539 return getClang(); 540 541 case Action::OffloadBundlingJobClass: 542 case Action::OffloadUnbundlingJobClass: 543 return getOffloadBundler(); 544 545 case Action::OffloadPackagerJobClass: 546 return getOffloadPackager(); 547 case Action::LinkerWrapperJobClass: 548 return getLinkerWrapper(); 549 } 550 551 llvm_unreachable("Invalid tool kind."); 552 } 553 554 static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, 555 const ArgList &Args) { 556 const llvm::Triple &Triple = TC.getTriple(); 557 bool IsWindows = Triple.isOSWindows(); 558 559 if (TC.isBareMetal()) 560 return Triple.getArchName(); 561 562 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) 563 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows) 564 ? "armhf" 565 : "arm"; 566 567 // For historic reasons, Android library is using i686 instead of i386. 568 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid()) 569 return "i686"; 570 571 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32()) 572 return "x32"; 573 574 return llvm::Triple::getArchTypeName(TC.getArch()); 575 } 576 577 StringRef ToolChain::getOSLibName() const { 578 if (Triple.isOSDarwin()) 579 return "darwin"; 580 581 switch (Triple.getOS()) { 582 case llvm::Triple::FreeBSD: 583 return "freebsd"; 584 case llvm::Triple::NetBSD: 585 return "netbsd"; 586 case llvm::Triple::OpenBSD: 587 return "openbsd"; 588 case llvm::Triple::Solaris: 589 return "sunos"; 590 case llvm::Triple::AIX: 591 return "aix"; 592 default: 593 return getOS(); 594 } 595 } 596 597 std::string ToolChain::getCompilerRTPath() const { 598 SmallString<128> Path(getDriver().ResourceDir); 599 if (isBareMetal()) { 600 llvm::sys::path::append(Path, "lib", getOSLibName()); 601 if (!SelectedMultilibs.empty()) { 602 Path += SelectedMultilibs.back().gccSuffix(); 603 } 604 } else if (Triple.isOSUnknown()) { 605 llvm::sys::path::append(Path, "lib"); 606 } else { 607 llvm::sys::path::append(Path, "lib", getOSLibName()); 608 } 609 return std::string(Path.str()); 610 } 611 612 std::string ToolChain::getCompilerRTBasename(const ArgList &Args, 613 StringRef Component, 614 FileType Type) const { 615 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type); 616 return llvm::sys::path::filename(CRTAbsolutePath).str(); 617 } 618 619 std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args, 620 StringRef Component, 621 FileType Type, 622 bool AddArch) const { 623 const llvm::Triple &TT = getTriple(); 624 bool IsITANMSVCWindows = 625 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); 626 627 const char *Prefix = 628 IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib"; 629 const char *Suffix; 630 switch (Type) { 631 case ToolChain::FT_Object: 632 Suffix = IsITANMSVCWindows ? ".obj" : ".o"; 633 break; 634 case ToolChain::FT_Static: 635 Suffix = IsITANMSVCWindows ? ".lib" : ".a"; 636 break; 637 case ToolChain::FT_Shared: 638 Suffix = TT.isOSWindows() 639 ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib") 640 : ".so"; 641 break; 642 } 643 644 std::string ArchAndEnv; 645 if (AddArch) { 646 StringRef Arch = getArchNameForCompilerRTLib(*this, Args); 647 const char *Env = TT.isAndroid() ? "-android" : ""; 648 ArchAndEnv = ("-" + Arch + Env).str(); 649 } 650 return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str(); 651 } 652 653 std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, 654 FileType Type) const { 655 // Check for runtime files in the new layout without the architecture first. 656 std::string CRTBasename = 657 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false); 658 for (const auto &LibPath : getLibraryPaths()) { 659 SmallString<128> P(LibPath); 660 llvm::sys::path::append(P, CRTBasename); 661 if (getVFS().exists(P)) 662 return std::string(P.str()); 663 } 664 665 // Fall back to the old expected compiler-rt name if the new one does not 666 // exist. 667 CRTBasename = 668 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true); 669 SmallString<128> Path(getCompilerRTPath()); 670 llvm::sys::path::append(Path, CRTBasename); 671 return std::string(Path.str()); 672 } 673 674 const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, 675 StringRef Component, 676 FileType Type) const { 677 return Args.MakeArgString(getCompilerRT(Args, Component, Type)); 678 } 679 680 ToolChain::path_list ToolChain::getRuntimePaths() const { 681 path_list Paths; 682 auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) { 683 SmallString<128> P(D.ResourceDir); 684 llvm::sys::path::append(P, "lib", Triple.str()); 685 Paths.push_back(std::string(P.str())); 686 }; 687 688 addPathForTriple(getTriple()); 689 690 // When building with per target runtime directories, various ways of naming 691 // the Arm architecture may have been normalised to simply "arm". 692 // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm". 693 // Since an armv8l system can use libraries built for earlier architecture 694 // versions assuming endian and float ABI match. 695 // 696 // Original triple: armv8l-unknown-linux-gnueabihf 697 // Runtime triple: arm-unknown-linux-gnueabihf 698 // 699 // We do not do this for armeb (big endian) because doing so could make us 700 // select little endian libraries. In addition, all known armeb triples only 701 // use the "armeb" architecture name. 702 // 703 // M profile Arm is bare metal and we know they will not be using the per 704 // target runtime directory layout. 705 if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) { 706 llvm::Triple ArmTriple = getTriple(); 707 ArmTriple.setArch(Triple::arm); 708 addPathForTriple(ArmTriple); 709 } 710 711 // Android targets may include an API level at the end. We still want to fall 712 // back on a path without the API level. 713 if (getTriple().isAndroid() && 714 getTriple().getEnvironmentName() != "android") { 715 llvm::Triple TripleWithoutLevel = getTriple(); 716 TripleWithoutLevel.setEnvironmentName("android"); 717 addPathForTriple(TripleWithoutLevel); 718 } 719 720 return Paths; 721 } 722 723 ToolChain::path_list ToolChain::getStdlibPaths() const { 724 path_list Paths; 725 SmallString<128> P(D.Dir); 726 llvm::sys::path::append(P, "..", "lib", getTripleString()); 727 Paths.push_back(std::string(P.str())); 728 729 return Paths; 730 } 731 732 ToolChain::path_list ToolChain::getArchSpecificLibPaths() const { 733 path_list Paths; 734 735 auto AddPath = [&](const ArrayRef<StringRef> &SS) { 736 SmallString<128> Path(getDriver().ResourceDir); 737 llvm::sys::path::append(Path, "lib"); 738 for (auto &S : SS) 739 llvm::sys::path::append(Path, S); 740 Paths.push_back(std::string(Path.str())); 741 }; 742 743 AddPath({getTriple().str()}); 744 AddPath({getOSLibName(), llvm::Triple::getArchTypeName(getArch())}); 745 return Paths; 746 } 747 748 bool ToolChain::needsProfileRT(const ArgList &Args) { 749 if (Args.hasArg(options::OPT_noprofilelib)) 750 return false; 751 752 return Args.hasArg(options::OPT_fprofile_generate) || 753 Args.hasArg(options::OPT_fprofile_generate_EQ) || 754 Args.hasArg(options::OPT_fcs_profile_generate) || 755 Args.hasArg(options::OPT_fcs_profile_generate_EQ) || 756 Args.hasArg(options::OPT_fprofile_instr_generate) || 757 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || 758 Args.hasArg(options::OPT_fcreate_profile) || 759 Args.hasArg(options::OPT_forder_file_instrumentation); 760 } 761 762 bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) { 763 return Args.hasArg(options::OPT_coverage) || 764 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, 765 false); 766 } 767 768 Tool *ToolChain::SelectTool(const JobAction &JA) const { 769 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang(); 770 if (getDriver().ShouldUseClangCompiler(JA)) return getClang(); 771 Action::ActionClass AC = JA.getKind(); 772 if (AC == Action::AssembleJobClass && useIntegratedAs() && 773 !getTriple().isOSAIX()) 774 return getClangAs(); 775 return getTool(AC); 776 } 777 778 std::string ToolChain::GetFilePath(const char *Name) const { 779 return D.GetFilePath(Name, *this); 780 } 781 782 std::string ToolChain::GetProgramPath(const char *Name) const { 783 return D.GetProgramPath(Name, *this); 784 } 785 786 std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { 787 if (LinkerIsLLD) 788 *LinkerIsLLD = false; 789 790 // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is 791 // considered as the linker flavor, e.g. "bfd", "gold", or "lld". 792 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ); 793 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; 794 795 // --ld-path= takes precedence over -fuse-ld= and specifies the executable 796 // name. -B, COMPILER_PATH and PATH and consulted if the value does not 797 // contain a path component separator. 798 // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary 799 // that --ld-path= points to is lld. 800 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) { 801 std::string Path(A->getValue()); 802 if (!Path.empty()) { 803 if (llvm::sys::path::parent_path(Path).empty()) 804 Path = GetProgramPath(A->getValue()); 805 if (llvm::sys::fs::can_execute(Path)) { 806 if (LinkerIsLLD) 807 *LinkerIsLLD = UseLinker == "lld"; 808 return std::string(Path); 809 } 810 } 811 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); 812 return GetProgramPath(getDefaultLinker()); 813 } 814 // If we're passed -fuse-ld= with no argument, or with the argument ld, 815 // then use whatever the default system linker is. 816 if (UseLinker.empty() || UseLinker == "ld") { 817 const char *DefaultLinker = getDefaultLinker(); 818 if (llvm::sys::path::is_absolute(DefaultLinker)) 819 return std::string(DefaultLinker); 820 else 821 return GetProgramPath(DefaultLinker); 822 } 823 824 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking 825 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64." 826 // to a relative path is surprising. This is more complex due to priorities 827 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead. 828 if (UseLinker.contains('/')) 829 getDriver().Diag(diag::warn_drv_fuse_ld_path); 830 831 if (llvm::sys::path::is_absolute(UseLinker)) { 832 // If we're passed what looks like an absolute path, don't attempt to 833 // second-guess that. 834 if (llvm::sys::fs::can_execute(UseLinker)) 835 return std::string(UseLinker); 836 } else { 837 llvm::SmallString<8> LinkerName; 838 if (Triple.isOSDarwin()) 839 LinkerName.append("ld64."); 840 else 841 LinkerName.append("ld."); 842 LinkerName.append(UseLinker); 843 844 std::string LinkerPath(GetProgramPath(LinkerName.c_str())); 845 if (llvm::sys::fs::can_execute(LinkerPath)) { 846 if (LinkerIsLLD) 847 *LinkerIsLLD = UseLinker == "lld"; 848 return LinkerPath; 849 } 850 } 851 852 if (A) 853 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); 854 855 return GetProgramPath(getDefaultLinker()); 856 } 857 858 std::string ToolChain::GetStaticLibToolPath() const { 859 // TODO: Add support for static lib archiving on Windows 860 if (Triple.isOSDarwin()) 861 return GetProgramPath("libtool"); 862 return GetProgramPath("llvm-ar"); 863 } 864 865 types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { 866 types::ID id = types::lookupTypeForExtension(Ext); 867 868 // Flang always runs the preprocessor and has no notion of "preprocessed 869 // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating 870 // them differently. 871 if (D.IsFlangMode() && id == types::TY_PP_Fortran) 872 id = types::TY_Fortran; 873 874 return id; 875 } 876 877 bool ToolChain::HasNativeLLVMSupport() const { 878 return false; 879 } 880 881 bool ToolChain::isCrossCompiling() const { 882 llvm::Triple HostTriple(LLVM_HOST_TRIPLE); 883 switch (HostTriple.getArch()) { 884 // The A32/T32/T16 instruction sets are not separate architectures in this 885 // context. 886 case llvm::Triple::arm: 887 case llvm::Triple::armeb: 888 case llvm::Triple::thumb: 889 case llvm::Triple::thumbeb: 890 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb && 891 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb; 892 default: 893 return HostTriple.getArch() != getArch(); 894 } 895 } 896 897 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { 898 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC, 899 VersionTuple()); 900 } 901 902 llvm::ExceptionHandling 903 ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const { 904 return llvm::ExceptionHandling::None; 905 } 906 907 bool ToolChain::isThreadModelSupported(const StringRef Model) const { 908 if (Model == "single") { 909 // FIXME: 'single' is only supported on ARM and WebAssembly so far. 910 return Triple.getArch() == llvm::Triple::arm || 911 Triple.getArch() == llvm::Triple::armeb || 912 Triple.getArch() == llvm::Triple::thumb || 913 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm(); 914 } else if (Model == "posix") 915 return true; 916 917 return false; 918 } 919 920 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, 921 types::ID InputType) const { 922 switch (getTriple().getArch()) { 923 default: 924 return getTripleString(); 925 926 case llvm::Triple::x86_64: { 927 llvm::Triple Triple = getTriple(); 928 if (!Triple.isOSBinFormatMachO()) 929 return getTripleString(); 930 931 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 932 // x86_64h goes in the triple. Other -march options just use the 933 // vanilla triple we already have. 934 StringRef MArch = A->getValue(); 935 if (MArch == "x86_64h") 936 Triple.setArchName(MArch); 937 } 938 return Triple.getTriple(); 939 } 940 case llvm::Triple::aarch64: { 941 llvm::Triple Triple = getTriple(); 942 if (!Triple.isOSBinFormatMachO()) 943 return getTripleString(); 944 945 if (Triple.isArm64e()) 946 return getTripleString(); 947 948 // FIXME: older versions of ld64 expect the "arm64" component in the actual 949 // triple string and query it to determine whether an LTO file can be 950 // handled. Remove this when we don't care any more. 951 Triple.setArchName("arm64"); 952 return Triple.getTriple(); 953 } 954 case llvm::Triple::aarch64_32: 955 return getTripleString(); 956 case llvm::Triple::arm: 957 case llvm::Triple::armeb: 958 case llvm::Triple::thumb: 959 case llvm::Triple::thumbeb: { 960 llvm::Triple Triple = getTriple(); 961 tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple); 962 tools::arm::setFloatABIInTriple(getDriver(), Args, Triple); 963 return Triple.getTriple(); 964 } 965 } 966 } 967 968 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 969 types::ID InputType) const { 970 return ComputeLLVMTriple(Args, InputType); 971 } 972 973 std::string ToolChain::computeSysRoot() const { 974 return D.SysRoot; 975 } 976 977 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 978 ArgStringList &CC1Args) const { 979 // Each toolchain should provide the appropriate include flags. 980 } 981 982 void ToolChain::addClangTargetOptions( 983 const ArgList &DriverArgs, ArgStringList &CC1Args, 984 Action::OffloadKind DeviceOffloadKind) const {} 985 986 void ToolChain::addClangCC1ASTargetOptions(const ArgList &Args, 987 ArgStringList &CC1ASArgs) const {} 988 989 void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} 990 991 void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, 992 llvm::opt::ArgStringList &CmdArgs) const { 993 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args)) 994 return; 995 996 CmdArgs.push_back(getCompilerRTArgString(Args, "profile")); 997 } 998 999 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( 1000 const ArgList &Args) const { 1001 if (runtimeLibType) 1002 return *runtimeLibType; 1003 1004 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ); 1005 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB; 1006 1007 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB! 1008 if (LibName == "compiler-rt") 1009 runtimeLibType = ToolChain::RLT_CompilerRT; 1010 else if (LibName == "libgcc") 1011 runtimeLibType = ToolChain::RLT_Libgcc; 1012 else if (LibName == "platform") 1013 runtimeLibType = GetDefaultRuntimeLibType(); 1014 else { 1015 if (A) 1016 getDriver().Diag(diag::err_drv_invalid_rtlib_name) 1017 << A->getAsString(Args); 1018 1019 runtimeLibType = GetDefaultRuntimeLibType(); 1020 } 1021 1022 return *runtimeLibType; 1023 } 1024 1025 ToolChain::UnwindLibType ToolChain::GetUnwindLibType( 1026 const ArgList &Args) const { 1027 if (unwindLibType) 1028 return *unwindLibType; 1029 1030 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); 1031 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB; 1032 1033 if (LibName == "none") 1034 unwindLibType = ToolChain::UNW_None; 1035 else if (LibName == "platform" || LibName == "") { 1036 ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); 1037 if (RtLibType == ToolChain::RLT_CompilerRT) { 1038 if (getTriple().isAndroid() || getTriple().isOSAIX()) 1039 unwindLibType = ToolChain::UNW_CompilerRT; 1040 else 1041 unwindLibType = ToolChain::UNW_None; 1042 } else if (RtLibType == ToolChain::RLT_Libgcc) 1043 unwindLibType = ToolChain::UNW_Libgcc; 1044 } else if (LibName == "libunwind") { 1045 if (GetRuntimeLibType(Args) == RLT_Libgcc) 1046 getDriver().Diag(diag::err_drv_incompatible_unwindlib); 1047 unwindLibType = ToolChain::UNW_CompilerRT; 1048 } else if (LibName == "libgcc") 1049 unwindLibType = ToolChain::UNW_Libgcc; 1050 else { 1051 if (A) 1052 getDriver().Diag(diag::err_drv_invalid_unwindlib_name) 1053 << A->getAsString(Args); 1054 1055 unwindLibType = GetDefaultUnwindLibType(); 1056 } 1057 1058 return *unwindLibType; 1059 } 1060 1061 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 1062 if (cxxStdlibType) 1063 return *cxxStdlibType; 1064 1065 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 1066 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB; 1067 1068 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB! 1069 if (LibName == "libc++") 1070 cxxStdlibType = ToolChain::CST_Libcxx; 1071 else if (LibName == "libstdc++") 1072 cxxStdlibType = ToolChain::CST_Libstdcxx; 1073 else if (LibName == "platform") 1074 cxxStdlibType = GetDefaultCXXStdlibType(); 1075 else { 1076 if (A) 1077 getDriver().Diag(diag::err_drv_invalid_stdlib_name) 1078 << A->getAsString(Args); 1079 1080 cxxStdlibType = GetDefaultCXXStdlibType(); 1081 } 1082 1083 return *cxxStdlibType; 1084 } 1085 1086 /// Utility function to add a system include directory to CC1 arguments. 1087 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, 1088 ArgStringList &CC1Args, 1089 const Twine &Path) { 1090 CC1Args.push_back("-internal-isystem"); 1091 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1092 } 1093 1094 /// Utility function to add a system include directory with extern "C" 1095 /// semantics to CC1 arguments. 1096 /// 1097 /// Note that this should be used rarely, and only for directories that 1098 /// historically and for legacy reasons are treated as having implicit extern 1099 /// "C" semantics. These semantics are *ignored* by and large today, but its 1100 /// important to preserve the preprocessor changes resulting from the 1101 /// classification. 1102 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs, 1103 ArgStringList &CC1Args, 1104 const Twine &Path) { 1105 CC1Args.push_back("-internal-externc-isystem"); 1106 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1107 } 1108 1109 void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, 1110 ArgStringList &CC1Args, 1111 const Twine &Path) { 1112 if (llvm::sys::fs::exists(Path)) 1113 addExternCSystemInclude(DriverArgs, CC1Args, Path); 1114 } 1115 1116 /// Utility function to add a list of system include directories to CC1. 1117 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, 1118 ArgStringList &CC1Args, 1119 ArrayRef<StringRef> Paths) { 1120 for (const auto &Path : Paths) { 1121 CC1Args.push_back("-internal-isystem"); 1122 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 1123 } 1124 } 1125 1126 /*static*/ std::string ToolChain::concat(StringRef Path, const Twine &A, 1127 const Twine &B, const Twine &C, 1128 const Twine &D) { 1129 SmallString<128> Result(Path); 1130 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D); 1131 return std::string(Result); 1132 } 1133 1134 std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const { 1135 std::error_code EC; 1136 int MaxVersion = 0; 1137 std::string MaxVersionString; 1138 SmallString<128> Path(IncludePath); 1139 llvm::sys::path::append(Path, "c++"); 1140 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE; 1141 !EC && LI != LE; LI = LI.increment(EC)) { 1142 StringRef VersionText = llvm::sys::path::filename(LI->path()); 1143 int Version; 1144 if (VersionText[0] == 'v' && 1145 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { 1146 if (Version > MaxVersion) { 1147 MaxVersion = Version; 1148 MaxVersionString = std::string(VersionText); 1149 } 1150 } 1151 } 1152 if (!MaxVersion) 1153 return ""; 1154 return MaxVersionString; 1155 } 1156 1157 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1158 ArgStringList &CC1Args) const { 1159 // Header search paths should be handled by each of the subclasses. 1160 // Historically, they have not been, and instead have been handled inside of 1161 // the CC1-layer frontend. As the logic is hoisted out, this generic function 1162 // will slowly stop being called. 1163 // 1164 // While it is being called, replicate a bit of a hack to propagate the 1165 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++ 1166 // header search paths with it. Once all systems are overriding this 1167 // function, the CC1 flag and this line can be removed. 1168 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); 1169 } 1170 1171 void ToolChain::AddClangCXXStdlibIsystemArgs( 1172 const llvm::opt::ArgList &DriverArgs, 1173 llvm::opt::ArgStringList &CC1Args) const { 1174 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem); 1175 // This intentionally only looks at -nostdinc++, and not -nostdinc or 1176 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain 1177 // setups with non-standard search logic for the C++ headers, while still 1178 // allowing users of the toolchain to bring their own C++ headers. Such a 1179 // toolchain likely also has non-standard search logic for the C headers and 1180 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should 1181 // still work in that case and only be suppressed by an explicit -nostdinc++ 1182 // in a project using the toolchain. 1183 if (!DriverArgs.hasArg(options::OPT_nostdincxx)) 1184 for (const auto &P : 1185 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem)) 1186 addSystemInclude(DriverArgs, CC1Args, P); 1187 } 1188 1189 bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const { 1190 return getDriver().CCCIsCXX() && 1191 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 1192 options::OPT_nostdlibxx); 1193 } 1194 1195 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 1196 ArgStringList &CmdArgs) const { 1197 assert(!Args.hasArg(options::OPT_nostdlibxx) && 1198 "should not have called this"); 1199 CXXStdlibType Type = GetCXXStdlibType(Args); 1200 1201 switch (Type) { 1202 case ToolChain::CST_Libcxx: 1203 CmdArgs.push_back("-lc++"); 1204 if (Args.hasArg(options::OPT_fexperimental_library)) 1205 CmdArgs.push_back("-lc++experimental"); 1206 break; 1207 1208 case ToolChain::CST_Libstdcxx: 1209 CmdArgs.push_back("-lstdc++"); 1210 break; 1211 } 1212 } 1213 1214 void ToolChain::AddFilePathLibArgs(const ArgList &Args, 1215 ArgStringList &CmdArgs) const { 1216 for (const auto &LibPath : getFilePaths()) 1217 if(LibPath.length() > 0) 1218 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); 1219 } 1220 1221 void ToolChain::AddCCKextLibArgs(const ArgList &Args, 1222 ArgStringList &CmdArgs) const { 1223 CmdArgs.push_back("-lcc_kext"); 1224 } 1225 1226 bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, 1227 std::string &Path) const { 1228 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed 1229 // (to keep the linker options consistent with gcc and clang itself). 1230 if (!isOptimizationLevelFast(Args)) { 1231 // Check if -ffast-math or -funsafe-math. 1232 Arg *A = 1233 Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math, 1234 options::OPT_funsafe_math_optimizations, 1235 options::OPT_fno_unsafe_math_optimizations); 1236 1237 if (!A || A->getOption().getID() == options::OPT_fno_fast_math || 1238 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) 1239 return false; 1240 } 1241 // If crtfastmath.o exists add it to the arguments. 1242 Path = GetFilePath("crtfastmath.o"); 1243 return (Path != "crtfastmath.o"); // Not found. 1244 } 1245 1246 bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args, 1247 ArgStringList &CmdArgs) const { 1248 std::string Path; 1249 if (isFastMathRuntimeAvailable(Args, Path)) { 1250 CmdArgs.push_back(Args.MakeArgString(Path)); 1251 return true; 1252 } 1253 1254 return false; 1255 } 1256 1257 Expected<SmallVector<std::string>> 1258 ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const { 1259 return SmallVector<std::string>(); 1260 } 1261 1262 SanitizerMask ToolChain::getSupportedSanitizers() const { 1263 // Return sanitizers which don't require runtime support and are not 1264 // platform dependent. 1265 1266 SanitizerMask Res = 1267 (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | 1268 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | 1269 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | 1270 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow | 1271 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion | 1272 SanitizerKind::Nullability | SanitizerKind::LocalBounds; 1273 if (getTriple().getArch() == llvm::Triple::x86 || 1274 getTriple().getArch() == llvm::Triple::x86_64 || 1275 getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() || 1276 getTriple().isAArch64() || getTriple().isRISCV()) 1277 Res |= SanitizerKind::CFIICall; 1278 if (getTriple().getArch() == llvm::Triple::x86_64 || 1279 getTriple().isAArch64(64) || getTriple().isRISCV()) 1280 Res |= SanitizerKind::ShadowCallStack; 1281 if (getTriple().isAArch64(64)) 1282 Res |= SanitizerKind::MemTag; 1283 return Res; 1284 } 1285 1286 void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, 1287 ArgStringList &CC1Args) const {} 1288 1289 void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, 1290 ArgStringList &CC1Args) const {} 1291 1292 llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> 1293 ToolChain::getDeviceLibs(const ArgList &DriverArgs) const { 1294 return {}; 1295 } 1296 1297 void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs, 1298 ArgStringList &CC1Args) const {} 1299 1300 static VersionTuple separateMSVCFullVersion(unsigned Version) { 1301 if (Version < 100) 1302 return VersionTuple(Version); 1303 1304 if (Version < 10000) 1305 return VersionTuple(Version / 100, Version % 100); 1306 1307 unsigned Build = 0, Factor = 1; 1308 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) 1309 Build = Build + (Version % 10) * Factor; 1310 return VersionTuple(Version / 100, Version % 100, Build); 1311 } 1312 1313 VersionTuple 1314 ToolChain::computeMSVCVersion(const Driver *D, 1315 const llvm::opt::ArgList &Args) const { 1316 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); 1317 const Arg *MSCompatibilityVersion = 1318 Args.getLastArg(options::OPT_fms_compatibility_version); 1319 1320 if (MSCVersion && MSCompatibilityVersion) { 1321 if (D) 1322 D->Diag(diag::err_drv_argument_not_allowed_with) 1323 << MSCVersion->getAsString(Args) 1324 << MSCompatibilityVersion->getAsString(Args); 1325 return VersionTuple(); 1326 } 1327 1328 if (MSCompatibilityVersion) { 1329 VersionTuple MSVT; 1330 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) { 1331 if (D) 1332 D->Diag(diag::err_drv_invalid_value) 1333 << MSCompatibilityVersion->getAsString(Args) 1334 << MSCompatibilityVersion->getValue(); 1335 } else { 1336 return MSVT; 1337 } 1338 } 1339 1340 if (MSCVersion) { 1341 unsigned Version = 0; 1342 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) { 1343 if (D) 1344 D->Diag(diag::err_drv_invalid_value) 1345 << MSCVersion->getAsString(Args) << MSCVersion->getValue(); 1346 } else { 1347 return separateMSVCFullVersion(Version); 1348 } 1349 } 1350 1351 return VersionTuple(); 1352 } 1353 1354 llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs( 1355 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, 1356 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const { 1357 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1358 const OptTable &Opts = getDriver().getOpts(); 1359 bool Modified = false; 1360 1361 // Handle -Xopenmp-target flags 1362 for (auto *A : Args) { 1363 // Exclude flags which may only apply to the host toolchain. 1364 // Do not exclude flags when the host triple (AuxTriple) 1365 // matches the current toolchain triple. If it is not present 1366 // at all, target and host share a toolchain. 1367 if (A->getOption().matches(options::OPT_m_Group)) { 1368 if (SameTripleAsHost) 1369 DAL->append(A); 1370 else 1371 Modified = true; 1372 continue; 1373 } 1374 1375 unsigned Index; 1376 unsigned Prev; 1377 bool XOpenMPTargetNoTriple = 1378 A->getOption().matches(options::OPT_Xopenmp_target); 1379 1380 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) { 1381 llvm::Triple TT(getOpenMPTriple(A->getValue(0))); 1382 1383 // Passing device args: -Xopenmp-target=<triple> -opt=val. 1384 if (TT.getTriple() == getTripleString()) 1385 Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 1386 else 1387 continue; 1388 } else if (XOpenMPTargetNoTriple) { 1389 // Passing device args: -Xopenmp-target -opt=val. 1390 Index = Args.getBaseArgs().MakeIndex(A->getValue(0)); 1391 } else { 1392 DAL->append(A); 1393 continue; 1394 } 1395 1396 // Parse the argument to -Xopenmp-target. 1397 Prev = Index; 1398 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index)); 1399 if (!XOpenMPTargetArg || Index > Prev + 1) { 1400 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) 1401 << A->getAsString(Args); 1402 continue; 1403 } 1404 if (XOpenMPTargetNoTriple && XOpenMPTargetArg && 1405 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) { 1406 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple); 1407 continue; 1408 } 1409 XOpenMPTargetArg->setBaseArg(A); 1410 A = XOpenMPTargetArg.release(); 1411 AllocatedArgs.push_back(A); 1412 DAL->append(A); 1413 Modified = true; 1414 } 1415 1416 if (Modified) 1417 return DAL; 1418 1419 delete DAL; 1420 return nullptr; 1421 } 1422 1423 // TODO: Currently argument values separated by space e.g. 1424 // -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be 1425 // fixed. 1426 void ToolChain::TranslateXarchArgs( 1427 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, 1428 llvm::opt::DerivedArgList *DAL, 1429 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1430 const OptTable &Opts = getDriver().getOpts(); 1431 unsigned ValuePos = 1; 1432 if (A->getOption().matches(options::OPT_Xarch_device) || 1433 A->getOption().matches(options::OPT_Xarch_host)) 1434 ValuePos = 0; 1435 1436 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos)); 1437 unsigned Prev = Index; 1438 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index)); 1439 1440 // If the argument parsing failed or more than one argument was 1441 // consumed, the -Xarch_ argument's parameter tried to consume 1442 // extra arguments. Emit an error and ignore. 1443 // 1444 // We also want to disallow any options which would alter the 1445 // driver behavior; that isn't going to work in our model. We 1446 // use options::NoXarchOption to control this. 1447 if (!XarchArg || Index > Prev + 1) { 1448 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 1449 << A->getAsString(Args); 1450 return; 1451 } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) { 1452 auto &Diags = getDriver().getDiags(); 1453 unsigned DiagID = 1454 Diags.getCustomDiagID(DiagnosticsEngine::Error, 1455 "invalid Xarch argument: '%0', not all driver " 1456 "options can be forwared via Xarch argument"); 1457 Diags.Report(DiagID) << A->getAsString(Args); 1458 return; 1459 } 1460 XarchArg->setBaseArg(A); 1461 A = XarchArg.release(); 1462 if (!AllocatedArgs) 1463 DAL->AddSynthesizedArg(A); 1464 else 1465 AllocatedArgs->push_back(A); 1466 } 1467 1468 llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( 1469 const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 1470 Action::OffloadKind OFK, 1471 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { 1472 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1473 bool Modified = false; 1474 1475 bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host; 1476 for (Arg *A : Args) { 1477 bool NeedTrans = false; 1478 bool Skip = false; 1479 if (A->getOption().matches(options::OPT_Xarch_device)) { 1480 NeedTrans = IsDevice; 1481 Skip = !IsDevice; 1482 } else if (A->getOption().matches(options::OPT_Xarch_host)) { 1483 NeedTrans = !IsDevice; 1484 Skip = IsDevice; 1485 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) { 1486 // Do not translate -Xarch_ options for non CUDA/HIP toolchain since 1487 // they may need special translation. 1488 // Skip this argument unless the architecture matches BoundArch 1489 if (BoundArch.empty() || A->getValue(0) != BoundArch) 1490 Skip = true; 1491 else 1492 NeedTrans = true; 1493 } 1494 if (NeedTrans || Skip) 1495 Modified = true; 1496 if (NeedTrans) 1497 TranslateXarchArgs(Args, A, DAL, AllocatedArgs); 1498 if (!Skip) 1499 DAL->append(A); 1500 } 1501 1502 if (Modified) 1503 return DAL; 1504 1505 delete DAL; 1506 return nullptr; 1507 } 1508