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