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