1 //===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===// 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 "Darwin.h" 10 #include "Arch/AArch64.h" 11 #include "Arch/ARM.h" 12 #include "CommonArgs.h" 13 #include "clang/Basic/AlignedAllocation.h" 14 #include "clang/Basic/ObjCRuntime.h" 15 #include "clang/Config/config.h" 16 #include "clang/Driver/Compilation.h" 17 #include "clang/Driver/Driver.h" 18 #include "clang/Driver/DriverDiagnostic.h" 19 #include "clang/Driver/Options.h" 20 #include "clang/Driver/SanitizerArgs.h" 21 #include "llvm/ADT/StringSwitch.h" 22 #include "llvm/Option/ArgList.h" 23 #include "llvm/ProfileData/InstrProf.h" 24 #include "llvm/Support/Path.h" 25 #include "llvm/Support/ScopedPrinter.h" 26 #include "llvm/Support/Threading.h" 27 #include "llvm/Support/VirtualFileSystem.h" 28 #include "llvm/TargetParser/TargetParser.h" 29 #include "llvm/TargetParser/Triple.h" 30 #include <cstdlib> // ::getenv 31 32 using namespace clang::driver; 33 using namespace clang::driver::tools; 34 using namespace clang::driver::toolchains; 35 using namespace clang; 36 using namespace llvm::opt; 37 38 static VersionTuple minimumMacCatalystDeploymentTarget() { 39 return VersionTuple(13, 1); 40 } 41 42 llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { 43 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 44 // archs which Darwin doesn't use. 45 46 // The matching this routine does is fairly pointless, since it is neither the 47 // complete architecture list, nor a reasonable subset. The problem is that 48 // historically the driver accepts this and also ties its -march= 49 // handling to the architecture name, so we need to be careful before removing 50 // support for it. 51 52 // This code must be kept in sync with Clang's Darwin specific argument 53 // translation. 54 55 return llvm::StringSwitch<llvm::Triple::ArchType>(Str) 56 .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) 57 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 58 llvm::Triple::x86) 59 .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) 60 // This is derived from the driver. 61 .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) 62 .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) 63 .Cases("armv7s", "xscale", llvm::Triple::arm) 64 .Cases("arm64", "arm64e", llvm::Triple::aarch64) 65 .Case("arm64_32", llvm::Triple::aarch64_32) 66 .Case("r600", llvm::Triple::r600) 67 .Case("amdgcn", llvm::Triple::amdgcn) 68 .Case("nvptx", llvm::Triple::nvptx) 69 .Case("nvptx64", llvm::Triple::nvptx64) 70 .Case("amdil", llvm::Triple::amdil) 71 .Case("spir", llvm::Triple::spir) 72 .Default(llvm::Triple::UnknownArch); 73 } 74 75 void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str, 76 const ArgList &Args) { 77 const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str); 78 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str); 79 T.setArch(Arch); 80 if (Arch != llvm::Triple::UnknownArch) 81 T.setArchName(Str); 82 83 if (ArchKind == llvm::ARM::ArchKind::ARMV6M || 84 ArchKind == llvm::ARM::ArchKind::ARMV7M || 85 ArchKind == llvm::ARM::ArchKind::ARMV7EM) { 86 // Don't reject these -version-min= if we have the appropriate triple. 87 if (T.getOS() == llvm::Triple::IOS) 88 for (Arg *A : Args.filtered(options::OPT_mios_version_min_EQ)) 89 A->ignoreTargetSpecific(); 90 if (T.getOS() == llvm::Triple::WatchOS) 91 for (Arg *A : Args.filtered(options::OPT_mwatchos_version_min_EQ)) 92 A->ignoreTargetSpecific(); 93 if (T.getOS() == llvm::Triple::TvOS) 94 for (Arg *A : Args.filtered(options::OPT_mtvos_version_min_EQ)) 95 A->ignoreTargetSpecific(); 96 97 T.setOS(llvm::Triple::UnknownOS); 98 T.setObjectFormat(llvm::Triple::MachO); 99 } 100 } 101 102 void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 103 const InputInfo &Output, 104 const InputInfoList &Inputs, 105 const ArgList &Args, 106 const char *LinkingOutput) const { 107 const llvm::Triple &T(getToolChain().getTriple()); 108 109 ArgStringList CmdArgs; 110 111 assert(Inputs.size() == 1 && "Unexpected number of inputs."); 112 const InputInfo &Input = Inputs[0]; 113 114 // Determine the original source input. 115 const Action *SourceAction = &JA; 116 while (SourceAction->getKind() != Action::InputClass) { 117 assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 118 SourceAction = SourceAction->getInputs()[0]; 119 } 120 121 // If -fno-integrated-as is used add -Q to the darwin assembler driver to make 122 // sure it runs its system assembler not clang's integrated assembler. 123 // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as. 124 // FIXME: at run-time detect assembler capabilities or rely on version 125 // information forwarded by -target-assembler-version. 126 if (Args.hasArg(options::OPT_fno_integrated_as)) { 127 if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7))) 128 CmdArgs.push_back("-Q"); 129 } 130 131 // Forward -g, assuming we are dealing with an actual assembly file. 132 if (SourceAction->getType() == types::TY_Asm || 133 SourceAction->getType() == types::TY_PP_Asm) { 134 if (Args.hasArg(options::OPT_gstabs)) 135 CmdArgs.push_back("--gstabs"); 136 else if (Args.hasArg(options::OPT_g_Group)) 137 CmdArgs.push_back("-g"); 138 } 139 140 // Derived from asm spec. 141 AddMachOArch(Args, CmdArgs); 142 143 // Use -force_cpusubtype_ALL on x86 by default. 144 if (T.isX86() || Args.hasArg(options::OPT_force__cpusubtype__ALL)) 145 CmdArgs.push_back("-force_cpusubtype_ALL"); 146 147 if (getToolChain().getArch() != llvm::Triple::x86_64 && 148 (((Args.hasArg(options::OPT_mkernel) || 149 Args.hasArg(options::OPT_fapple_kext)) && 150 getMachOToolChain().isKernelStatic()) || 151 Args.hasArg(options::OPT_static))) 152 CmdArgs.push_back("-static"); 153 154 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 155 156 assert(Output.isFilename() && "Unexpected lipo output."); 157 CmdArgs.push_back("-o"); 158 CmdArgs.push_back(Output.getFilename()); 159 160 assert(Input.isFilename() && "Invalid input."); 161 CmdArgs.push_back(Input.getFilename()); 162 163 // asm_final spec is empty. 164 165 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 166 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), 167 Exec, CmdArgs, Inputs, Output)); 168 } 169 170 void darwin::MachOTool::anchor() {} 171 172 void darwin::MachOTool::AddMachOArch(const ArgList &Args, 173 ArgStringList &CmdArgs) const { 174 StringRef ArchName = getMachOToolChain().getMachOArchName(Args); 175 176 // Derived from darwin_arch spec. 177 CmdArgs.push_back("-arch"); 178 CmdArgs.push_back(Args.MakeArgString(ArchName)); 179 180 // FIXME: Is this needed anymore? 181 if (ArchName == "arm") 182 CmdArgs.push_back("-force_cpusubtype_ALL"); 183 } 184 185 bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const { 186 // We only need to generate a temp path for LTO if we aren't compiling object 187 // files. When compiling source files, we run 'dsymutil' after linking. We 188 // don't run 'dsymutil' when compiling object files. 189 for (const auto &Input : Inputs) 190 if (Input.getType() != types::TY_Object) 191 return true; 192 193 return false; 194 } 195 196 /// Pass -no_deduplicate to ld64 under certain conditions: 197 /// 198 /// - Either -O0 or -O1 is explicitly specified 199 /// - No -O option is specified *and* this is a compile+link (implicit -O0) 200 /// 201 /// Also do *not* add -no_deduplicate when no -O option is specified and this 202 /// is just a link (we can't imply -O0) 203 static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { 204 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 205 if (A->getOption().matches(options::OPT_O0)) 206 return true; 207 if (A->getOption().matches(options::OPT_O)) 208 return llvm::StringSwitch<bool>(A->getValue()) 209 .Case("1", true) 210 .Default(false); 211 return false; // OPT_Ofast & OPT_O4 212 } 213 214 if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only. 215 return true; 216 return false; 217 } 218 219 void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, 220 ArgStringList &CmdArgs, 221 const InputInfoList &Inputs, 222 VersionTuple Version, bool LinkerIsLLD, 223 bool UsePlatformVersion) const { 224 const Driver &D = getToolChain().getDriver(); 225 const toolchains::MachO &MachOTC = getMachOToolChain(); 226 227 // Newer linkers support -demangle. Pass it if supported and not disabled by 228 // the user. 229 if ((Version >= VersionTuple(100) || LinkerIsLLD) && 230 !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 231 CmdArgs.push_back("-demangle"); 232 233 if (Args.hasArg(options::OPT_rdynamic) && 234 (Version >= VersionTuple(137) || LinkerIsLLD)) 235 CmdArgs.push_back("-export_dynamic"); 236 237 // If we are using App Extension restrictions, pass a flag to the linker 238 // telling it that the compiled code has been audited. 239 if (Args.hasFlag(options::OPT_fapplication_extension, 240 options::OPT_fno_application_extension, false)) 241 CmdArgs.push_back("-application_extension"); 242 243 if (D.isUsingLTO() && (Version >= VersionTuple(116) || LinkerIsLLD) && 244 NeedsTempPath(Inputs)) { 245 std::string TmpPathName; 246 if (D.getLTOMode() == LTOK_Full) { 247 // If we are using full LTO, then automatically create a temporary file 248 // path for the linker to use, so that it's lifetime will extend past a 249 // possible dsymutil step. 250 TmpPathName = 251 D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)); 252 } else if (D.getLTOMode() == LTOK_Thin) 253 // If we are using thin LTO, then create a directory instead. 254 TmpPathName = D.GetTemporaryDirectory("thinlto"); 255 256 if (!TmpPathName.empty()) { 257 auto *TmpPath = C.getArgs().MakeArgString(TmpPathName); 258 C.addTempFile(TmpPath); 259 CmdArgs.push_back("-object_path_lto"); 260 CmdArgs.push_back(TmpPath); 261 } 262 } 263 264 // Use -lto_library option to specify the libLTO.dylib path. Try to find 265 // it in clang installed libraries. ld64 will only look at this argument 266 // when it actually uses LTO, so libLTO.dylib only needs to exist at link 267 // time if ld64 decides that it needs to use LTO. 268 // Since this is passed unconditionally, ld64 will never look for libLTO.dylib 269 // next to it. That's ok since ld64 using a libLTO.dylib not matching the 270 // clang version won't work anyways. 271 // lld is built at the same revision as clang and statically links in 272 // LLVM libraries, so it doesn't need libLTO.dylib. 273 if (Version >= VersionTuple(133) && !LinkerIsLLD) { 274 // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib 275 StringRef P = llvm::sys::path::parent_path(D.Dir); 276 SmallString<128> LibLTOPath(P); 277 llvm::sys::path::append(LibLTOPath, "lib"); 278 llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); 279 CmdArgs.push_back("-lto_library"); 280 CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath)); 281 } 282 283 // ld64 version 262 and above runs the deduplicate pass by default. 284 // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe` 285 // if `!shouldLinkerNotDedup()` if LinkerIsLLD here? 286 if (Version >= VersionTuple(262) && 287 shouldLinkerNotDedup(C.getJobs().empty(), Args)) 288 CmdArgs.push_back("-no_deduplicate"); 289 290 // Derived from the "link" spec. 291 Args.AddAllArgs(CmdArgs, options::OPT_static); 292 if (!Args.hasArg(options::OPT_static)) 293 CmdArgs.push_back("-dynamic"); 294 if (Args.hasArg(options::OPT_fgnu_runtime)) { 295 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 296 // here. How do we wish to handle such things? 297 } 298 299 if (!Args.hasArg(options::OPT_dynamiclib)) { 300 AddMachOArch(Args, CmdArgs); 301 // FIXME: Why do this only on this path? 302 Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 303 304 Args.AddLastArg(CmdArgs, options::OPT_bundle); 305 Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 306 Args.AddAllArgs(CmdArgs, options::OPT_client__name); 307 308 Arg *A; 309 if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 310 (A = Args.getLastArg(options::OPT_current__version)) || 311 (A = Args.getLastArg(options::OPT_install__name))) 312 D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) 313 << "-dynamiclib"; 314 315 Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 316 Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 317 Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 318 } else { 319 CmdArgs.push_back("-dylib"); 320 321 Arg *A; 322 if ((A = Args.getLastArg(options::OPT_bundle)) || 323 (A = Args.getLastArg(options::OPT_bundle__loader)) || 324 (A = Args.getLastArg(options::OPT_client__name)) || 325 (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 326 (A = Args.getLastArg(options::OPT_keep__private__externs)) || 327 (A = Args.getLastArg(options::OPT_private__bundle))) 328 D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) 329 << "-dynamiclib"; 330 331 Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 332 "-dylib_compatibility_version"); 333 Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 334 "-dylib_current_version"); 335 336 AddMachOArch(Args, CmdArgs); 337 338 Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 339 "-dylib_install_name"); 340 } 341 342 Args.AddLastArg(CmdArgs, options::OPT_all__load); 343 Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 344 Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 345 if (MachOTC.isTargetIOSBased()) 346 Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 347 Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 348 Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 349 Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 350 Args.AddLastArg(CmdArgs, options::OPT_dynamic); 351 Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 352 Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 353 Args.AddAllArgs(CmdArgs, options::OPT_force__load); 354 Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 355 Args.AddAllArgs(CmdArgs, options::OPT_image__base); 356 Args.AddAllArgs(CmdArgs, options::OPT_init); 357 358 // Add the deployment target. 359 if (Version >= VersionTuple(520) || LinkerIsLLD || UsePlatformVersion) 360 MachOTC.addPlatformVersionArgs(Args, CmdArgs); 361 else 362 MachOTC.addMinVersionArgs(Args, CmdArgs); 363 364 Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 365 Args.AddLastArg(CmdArgs, options::OPT_multi__module); 366 Args.AddLastArg(CmdArgs, options::OPT_single__module); 367 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 368 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 369 370 if (const Arg *A = 371 Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, 372 options::OPT_fno_pie, options::OPT_fno_PIE)) { 373 if (A->getOption().matches(options::OPT_fpie) || 374 A->getOption().matches(options::OPT_fPIE)) 375 CmdArgs.push_back("-pie"); 376 else 377 CmdArgs.push_back("-no_pie"); 378 } 379 380 // for embed-bitcode, use -bitcode_bundle in linker command 381 if (C.getDriver().embedBitcodeEnabled()) { 382 // Check if the toolchain supports bitcode build flow. 383 if (MachOTC.SupportsEmbeddedBitcode()) { 384 CmdArgs.push_back("-bitcode_bundle"); 385 // FIXME: Pass this if LinkerIsLLD too, once it implements this flag. 386 if (C.getDriver().embedBitcodeMarkerOnly() && 387 Version >= VersionTuple(278)) { 388 CmdArgs.push_back("-bitcode_process_mode"); 389 CmdArgs.push_back("marker"); 390 } 391 } else 392 D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain); 393 } 394 395 // If GlobalISel is enabled, pass it through to LLVM. 396 if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel, 397 options::OPT_fno_global_isel)) { 398 if (A->getOption().matches(options::OPT_fglobal_isel)) { 399 CmdArgs.push_back("-mllvm"); 400 CmdArgs.push_back("-global-isel"); 401 // Disable abort and fall back to SDAG silently. 402 CmdArgs.push_back("-mllvm"); 403 CmdArgs.push_back("-global-isel-abort=0"); 404 } 405 } 406 407 if (Args.hasArg(options::OPT_mkernel) || 408 Args.hasArg(options::OPT_fapple_kext) || 409 Args.hasArg(options::OPT_ffreestanding)) { 410 CmdArgs.push_back("-mllvm"); 411 CmdArgs.push_back("-disable-atexit-based-global-dtor-lowering"); 412 } 413 414 Args.AddLastArg(CmdArgs, options::OPT_prebind); 415 Args.AddLastArg(CmdArgs, options::OPT_noprebind); 416 Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 417 Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 418 Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 419 Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 420 Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 421 Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 422 Args.AddAllArgs(CmdArgs, options::OPT_segprot); 423 Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 424 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 425 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 426 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 427 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 428 Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 429 Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 430 431 // Give --sysroot= preference, over the Apple specific behavior to also use 432 // --isysroot as the syslibroot. 433 StringRef sysroot = C.getSysRoot(); 434 if (sysroot != "") { 435 CmdArgs.push_back("-syslibroot"); 436 CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 437 } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 438 CmdArgs.push_back("-syslibroot"); 439 CmdArgs.push_back(A->getValue()); 440 } 441 442 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 443 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 444 Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 445 Args.AddAllArgs(CmdArgs, options::OPT_undefined); 446 Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 447 Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 448 Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 449 Args.AddAllArgs(CmdArgs, options::OPT_y); 450 Args.AddLastArg(CmdArgs, options::OPT_w); 451 Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 452 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 453 Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 454 Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 455 Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 456 Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 457 Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 458 Args.AddLastArg(CmdArgs, options::OPT_why_load); 459 Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 460 Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 461 Args.AddLastArg(CmdArgs, options::OPT_dylinker); 462 Args.AddLastArg(CmdArgs, options::OPT_Mach); 463 464 if (LinkerIsLLD) { 465 if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) { 466 SmallString<128> Path(CSPGOGenerateArg->getNumValues() == 0 467 ? "" 468 : CSPGOGenerateArg->getValue()); 469 llvm::sys::path::append(Path, "default_%m.profraw"); 470 CmdArgs.push_back("--cs-profile-generate"); 471 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path)); 472 } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) { 473 SmallString<128> Path( 474 ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue()); 475 if (Path.empty() || llvm::sys::fs::is_directory(Path)) 476 llvm::sys::path::append(Path, "default.profdata"); 477 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path)); 478 } 479 } 480 } 481 482 /// Determine whether we are linking the ObjC runtime. 483 static bool isObjCRuntimeLinked(const ArgList &Args) { 484 if (isObjCAutoRefCount(Args)) { 485 Args.ClaimAllArgs(options::OPT_fobjc_link_runtime); 486 return true; 487 } 488 return Args.hasArg(options::OPT_fobjc_link_runtime); 489 } 490 491 static bool checkRemarksOptions(const Driver &D, const ArgList &Args, 492 const llvm::Triple &Triple) { 493 // When enabling remarks, we need to error if: 494 // * The remark file is specified but we're targeting multiple architectures, 495 // which means more than one remark file is being generated. 496 bool hasMultipleInvocations = 497 Args.getAllArgValues(options::OPT_arch).size() > 1; 498 bool hasExplicitOutputFile = 499 Args.getLastArg(options::OPT_foptimization_record_file_EQ); 500 if (hasMultipleInvocations && hasExplicitOutputFile) { 501 D.Diag(diag::err_drv_invalid_output_with_multiple_archs) 502 << "-foptimization-record-file"; 503 return false; 504 } 505 return true; 506 } 507 508 static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, 509 const llvm::Triple &Triple, 510 const InputInfo &Output, const JobAction &JA) { 511 StringRef Format = "yaml"; 512 if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) 513 Format = A->getValue(); 514 515 CmdArgs.push_back("-mllvm"); 516 CmdArgs.push_back("-lto-pass-remarks-output"); 517 CmdArgs.push_back("-mllvm"); 518 519 const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ); 520 if (A) { 521 CmdArgs.push_back(A->getValue()); 522 } else { 523 assert(Output.isFilename() && "Unexpected ld output."); 524 SmallString<128> F; 525 F = Output.getFilename(); 526 F += ".opt."; 527 F += Format; 528 529 CmdArgs.push_back(Args.MakeArgString(F)); 530 } 531 532 if (const Arg *A = 533 Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { 534 CmdArgs.push_back("-mllvm"); 535 std::string Passes = 536 std::string("-lto-pass-remarks-filter=") + A->getValue(); 537 CmdArgs.push_back(Args.MakeArgString(Passes)); 538 } 539 540 if (!Format.empty()) { 541 CmdArgs.push_back("-mllvm"); 542 Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format; 543 CmdArgs.push_back(Args.MakeArgString(FormatArg)); 544 } 545 546 if (getLastProfileUseArg(Args)) { 547 CmdArgs.push_back("-mllvm"); 548 CmdArgs.push_back("-lto-pass-remarks-with-hotness"); 549 550 if (const Arg *A = 551 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) { 552 CmdArgs.push_back("-mllvm"); 553 std::string Opt = 554 std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue(); 555 CmdArgs.push_back(Args.MakeArgString(Opt)); 556 } 557 } 558 } 559 560 static void AppendPlatformPrefix(SmallString<128> &Path, const llvm::Triple &T); 561 562 void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, 563 const InputInfo &Output, 564 const InputInfoList &Inputs, 565 const ArgList &Args, 566 const char *LinkingOutput) const { 567 assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 568 569 // If the number of arguments surpasses the system limits, we will encode the 570 // input files in a separate file, shortening the command line. To this end, 571 // build a list of input file names that can be passed via a file with the 572 // -filelist linker option. 573 llvm::opt::ArgStringList InputFileList; 574 575 // The logic here is derived from gcc's behavior; most of which 576 // comes from specs (starting with link_command). Consult gcc for 577 // more information. 578 ArgStringList CmdArgs; 579 580 /// Hack(tm) to ignore linking errors when we are doing ARC migration. 581 if (Args.hasArg(options::OPT_ccc_arcmt_check, 582 options::OPT_ccc_arcmt_migrate)) { 583 for (const auto &Arg : Args) 584 Arg->claim(); 585 const char *Exec = 586 Args.MakeArgString(getToolChain().GetProgramPath("touch")); 587 CmdArgs.push_back(Output.getFilename()); 588 C.addCommand(std::make_unique<Command>(JA, *this, 589 ResponseFileSupport::None(), Exec, 590 CmdArgs, std::nullopt, Output)); 591 return; 592 } 593 594 VersionTuple Version = getMachOToolChain().getLinkerVersion(Args); 595 596 bool LinkerIsLLD; 597 const char *Exec = 598 Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD)); 599 600 // xrOS always uses -platform-version. 601 bool UsePlatformVersion = getToolChain().getTriple().isXROS(); 602 603 // I'm not sure why this particular decomposition exists in gcc, but 604 // we follow suite for ease of comparison. 605 AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD, 606 UsePlatformVersion); 607 608 if (willEmitRemarks(Args) && 609 checkRemarksOptions(getToolChain().getDriver(), Args, 610 getToolChain().getTriple())) 611 renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA); 612 613 // Propagate the -moutline flag to the linker in LTO. 614 if (Arg *A = 615 Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { 616 if (A->getOption().matches(options::OPT_moutline)) { 617 if (getMachOToolChain().getMachOArchName(Args) == "arm64") { 618 CmdArgs.push_back("-mllvm"); 619 CmdArgs.push_back("-enable-machine-outliner"); 620 } 621 } else { 622 // Disable all outlining behaviour if we have mno-outline. We need to do 623 // this explicitly, because targets which support default outlining will 624 // try to do work if we don't. 625 CmdArgs.push_back("-mllvm"); 626 CmdArgs.push_back("-enable-machine-outliner=never"); 627 } 628 } 629 630 // Outline from linkonceodr functions by default in LTO, whenever the outliner 631 // is enabled. Note that the target may enable the machine outliner 632 // independently of -moutline. 633 CmdArgs.push_back("-mllvm"); 634 CmdArgs.push_back("-enable-linkonceodr-outlining"); 635 636 // Setup statistics file output. 637 SmallString<128> StatsFile = 638 getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver()); 639 if (!StatsFile.empty()) { 640 CmdArgs.push_back("-mllvm"); 641 CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); 642 } 643 644 // It seems that the 'e' option is completely ignored for dynamic executables 645 // (the default), and with static executables, the last one wins, as expected. 646 Args.addAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, 647 options::OPT_Z_Flag, options::OPT_u_Group}); 648 649 // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading 650 // members of static archive libraries which implement Objective-C classes or 651 // categories. 652 if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX)) 653 CmdArgs.push_back("-ObjC"); 654 655 CmdArgs.push_back("-o"); 656 CmdArgs.push_back(Output.getFilename()); 657 658 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) 659 getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs); 660 661 Args.AddAllArgs(CmdArgs, options::OPT_L); 662 663 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 664 // Build the input file for -filelist (list of linker input files) in case we 665 // need it later 666 for (const auto &II : Inputs) { 667 if (!II.isFilename()) { 668 // This is a linker input argument. 669 // We cannot mix input arguments and file names in a -filelist input, thus 670 // we prematurely stop our list (remaining files shall be passed as 671 // arguments). 672 if (InputFileList.size() > 0) 673 break; 674 675 continue; 676 } 677 678 InputFileList.push_back(II.getFilename()); 679 } 680 681 // Additional linker set-up and flags for Fortran. This is required in order 682 // to generate executables. 683 if (getToolChain().getDriver().IsFlangMode()) { 684 addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs); 685 addFortranRuntimeLibs(getToolChain(), Args, CmdArgs); 686 } 687 688 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 689 addOpenMPRuntime(C, CmdArgs, getToolChain(), Args); 690 691 if (isObjCRuntimeLinked(Args) && 692 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 693 // We use arclite library for both ARC and subscripting support. 694 getMachOToolChain().AddLinkARCArgs(Args, CmdArgs); 695 696 CmdArgs.push_back("-framework"); 697 CmdArgs.push_back("Foundation"); 698 // Link libobj. 699 CmdArgs.push_back("-lobjc"); 700 } 701 702 if (LinkingOutput) { 703 CmdArgs.push_back("-arch_multiple"); 704 CmdArgs.push_back("-final_output"); 705 CmdArgs.push_back(LinkingOutput); 706 } 707 708 if (Args.hasArg(options::OPT_fnested_functions)) 709 CmdArgs.push_back("-allow_stack_execute"); 710 711 getMachOToolChain().addProfileRTLibs(Args, CmdArgs); 712 713 StringRef Parallelism = getLTOParallelism(Args, getToolChain().getDriver()); 714 if (!Parallelism.empty()) { 715 CmdArgs.push_back("-mllvm"); 716 unsigned NumThreads = 717 llvm::get_threadpool_strategy(Parallelism)->compute_thread_count(); 718 CmdArgs.push_back(Args.MakeArgString("-threads=" + Twine(NumThreads))); 719 } 720 721 if (getToolChain().ShouldLinkCXXStdlib(Args)) 722 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 723 724 bool NoStdOrDefaultLibs = 725 Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); 726 bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); 727 if (!NoStdOrDefaultLibs || ForceLinkBuiltins) { 728 // link_ssp spec is empty. 729 730 // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then 731 // we just want to link the builtins, not the other libs like libSystem. 732 if (NoStdOrDefaultLibs && ForceLinkBuiltins) { 733 getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 734 } else { 735 // Let the tool chain choose which runtime library to link. 736 getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs, 737 ForceLinkBuiltins); 738 739 // No need to do anything for pthreads. Claim argument to avoid warning. 740 Args.ClaimAllArgs(options::OPT_pthread); 741 Args.ClaimAllArgs(options::OPT_pthreads); 742 } 743 } 744 745 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 746 // endfile_spec is empty. 747 } 748 749 Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 750 Args.AddAllArgs(CmdArgs, options::OPT_F); 751 752 // -iframework should be forwarded as -F. 753 for (const Arg *A : Args.filtered(options::OPT_iframework)) 754 CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue())); 755 756 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 757 if (Arg *A = Args.getLastArg(options::OPT_fveclib)) { 758 if (A->getValue() == StringRef("Accelerate")) { 759 CmdArgs.push_back("-framework"); 760 CmdArgs.push_back("Accelerate"); 761 } 762 } 763 } 764 765 // Add non-standard, platform-specific search paths, e.g., for DriverKit: 766 // -L<sysroot>/System/DriverKit/usr/lib 767 // -F<sysroot>/System/DriverKit/System/Library/Framework 768 { 769 bool NonStandardSearchPath = false; 770 const auto &Triple = getToolChain().getTriple(); 771 if (Triple.isDriverKit()) { 772 // ld64 fixed the implicit -F and -L paths in ld64-605.1+. 773 NonStandardSearchPath = 774 Version.getMajor() < 605 || 775 (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1); 776 } 777 778 if (NonStandardSearchPath) { 779 if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) { 780 auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) { 781 SmallString<128> P(Sysroot->getValue()); 782 AppendPlatformPrefix(P, Triple); 783 llvm::sys::path::append(P, SearchPath); 784 if (getToolChain().getVFS().exists(P)) { 785 CmdArgs.push_back(Args.MakeArgString(Flag + P)); 786 } 787 }; 788 AddSearchPath("-L", "/usr/lib"); 789 AddSearchPath("-F", "/System/Library/Frameworks"); 790 } 791 } 792 } 793 794 ResponseFileSupport ResponseSupport; 795 if (Version >= VersionTuple(705) || LinkerIsLLD) { 796 ResponseSupport = ResponseFileSupport::AtFileUTF8(); 797 } else { 798 // For older versions of the linker, use the legacy filelist method instead. 799 ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8, 800 "-filelist"}; 801 } 802 803 std::unique_ptr<Command> Cmd = std::make_unique<Command>( 804 JA, *this, ResponseSupport, Exec, CmdArgs, Inputs, Output); 805 Cmd->setInputFileList(std::move(InputFileList)); 806 C.addCommand(std::move(Cmd)); 807 } 808 809 void darwin::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA, 810 const InputInfo &Output, 811 const InputInfoList &Inputs, 812 const ArgList &Args, 813 const char *LinkingOutput) const { 814 const Driver &D = getToolChain().getDriver(); 815 816 // Silence warning for "clang -g foo.o -o foo" 817 Args.ClaimAllArgs(options::OPT_g_Group); 818 // and "clang -emit-llvm foo.o -o foo" 819 Args.ClaimAllArgs(options::OPT_emit_llvm); 820 // and for "clang -w foo.o -o foo". Other warning options are already 821 // handled somewhere else. 822 Args.ClaimAllArgs(options::OPT_w); 823 // Silence warnings when linking C code with a C++ '-stdlib' argument. 824 Args.ClaimAllArgs(options::OPT_stdlib_EQ); 825 826 // libtool <options> <output_file> <input_files> 827 ArgStringList CmdArgs; 828 // Create and insert file members with a deterministic index. 829 CmdArgs.push_back("-static"); 830 CmdArgs.push_back("-D"); 831 CmdArgs.push_back("-no_warning_for_no_symbols"); 832 CmdArgs.push_back("-o"); 833 CmdArgs.push_back(Output.getFilename()); 834 835 for (const auto &II : Inputs) { 836 if (II.isFilename()) { 837 CmdArgs.push_back(II.getFilename()); 838 } 839 } 840 841 // Delete old output archive file if it already exists before generating a new 842 // archive file. 843 const auto *OutputFileName = Output.getFilename(); 844 if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) { 845 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) { 846 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message(); 847 return; 848 } 849 } 850 851 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); 852 C.addCommand(std::make_unique<Command>(JA, *this, 853 ResponseFileSupport::AtFileUTF8(), 854 Exec, CmdArgs, Inputs, Output)); 855 } 856 857 void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 858 const InputInfo &Output, 859 const InputInfoList &Inputs, 860 const ArgList &Args, 861 const char *LinkingOutput) const { 862 ArgStringList CmdArgs; 863 864 CmdArgs.push_back("-create"); 865 assert(Output.isFilename() && "Unexpected lipo output."); 866 867 CmdArgs.push_back("-output"); 868 CmdArgs.push_back(Output.getFilename()); 869 870 for (const auto &II : Inputs) { 871 assert(II.isFilename() && "Unexpected lipo input."); 872 CmdArgs.push_back(II.getFilename()); 873 } 874 875 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); 876 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), 877 Exec, CmdArgs, Inputs, Output)); 878 } 879 880 void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, 881 const InputInfo &Output, 882 const InputInfoList &Inputs, 883 const ArgList &Args, 884 const char *LinkingOutput) const { 885 ArgStringList CmdArgs; 886 887 CmdArgs.push_back("-o"); 888 CmdArgs.push_back(Output.getFilename()); 889 890 assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 891 const InputInfo &Input = Inputs[0]; 892 assert(Input.isFilename() && "Unexpected dsymutil input."); 893 CmdArgs.push_back(Input.getFilename()); 894 895 const char *Exec = 896 Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); 897 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), 898 Exec, CmdArgs, Inputs, Output)); 899 } 900 901 void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, 902 const InputInfo &Output, 903 const InputInfoList &Inputs, 904 const ArgList &Args, 905 const char *LinkingOutput) const { 906 ArgStringList CmdArgs; 907 CmdArgs.push_back("--verify"); 908 CmdArgs.push_back("--debug-info"); 909 CmdArgs.push_back("--eh-frame"); 910 CmdArgs.push_back("--quiet"); 911 912 assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 913 const InputInfo &Input = Inputs[0]; 914 assert(Input.isFilename() && "Unexpected verify input"); 915 916 // Grabbing the output of the earlier dsymutil run. 917 CmdArgs.push_back(Input.getFilename()); 918 919 const char *Exec = 920 Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); 921 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), 922 Exec, CmdArgs, Inputs, Output)); 923 } 924 925 MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 926 : ToolChain(D, Triple, Args) { 927 // We expect 'as', 'ld', etc. to be adjacent to our install dir. 928 getProgramPaths().push_back(getDriver().Dir); 929 } 930 931 /// Darwin - Darwin tool chain for i386 and x86_64. 932 Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 933 : MachO(D, Triple, Args), TargetInitialized(false), 934 CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {} 935 936 types::ID MachO::LookupTypeForExtension(StringRef Ext) const { 937 types::ID Ty = ToolChain::LookupTypeForExtension(Ext); 938 939 // Darwin always preprocesses assembly files (unless -x is used explicitly). 940 if (Ty == types::TY_PP_Asm) 941 return types::TY_Asm; 942 943 return Ty; 944 } 945 946 bool MachO::HasNativeLLVMSupport() const { return true; } 947 948 ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { 949 // Always use libc++ by default 950 return ToolChain::CST_Libcxx; 951 } 952 953 /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 954 ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 955 if (isTargetWatchOSBased()) 956 return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion); 957 if (isTargetIOSBased()) 958 return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 959 if (isTargetXROS()) { 960 // XROS uses the iOS runtime. 961 auto T = llvm::Triple(Twine("arm64-apple-") + 962 llvm::Triple::getOSTypeName(llvm::Triple::XROS) + 963 TargetVersion.getAsString()); 964 return ObjCRuntime(ObjCRuntime::iOS, T.getiOSVersion()); 965 } 966 if (isNonFragile) 967 return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 968 return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 969 } 970 971 /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 972 bool Darwin::hasBlocksRuntime() const { 973 if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS()) 974 return true; 975 else if (isTargetIOSBased()) 976 return !isIPhoneOSVersionLT(3, 2); 977 else { 978 assert(isTargetMacOSBased() && "unexpected darwin target"); 979 return !isMacosxVersionLT(10, 6); 980 } 981 } 982 983 void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, 984 ArgStringList &CC1Args) const { 985 CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args); 986 } 987 988 void Darwin::AddHIPIncludeArgs(const ArgList &DriverArgs, 989 ArgStringList &CC1Args) const { 990 RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args); 991 } 992 993 // This is just a MachO name translation routine and there's no 994 // way to join this into ARMTargetParser without breaking all 995 // other assumptions. Maybe MachO should consider standardising 996 // their nomenclature. 997 static const char *ArmMachOArchName(StringRef Arch) { 998 return llvm::StringSwitch<const char *>(Arch) 999 .Case("armv6k", "armv6") 1000 .Case("armv6m", "armv6m") 1001 .Case("armv5tej", "armv5") 1002 .Case("xscale", "xscale") 1003 .Case("armv4t", "armv4t") 1004 .Case("armv7", "armv7") 1005 .Cases("armv7a", "armv7-a", "armv7") 1006 .Cases("armv7r", "armv7-r", "armv7") 1007 .Cases("armv7em", "armv7e-m", "armv7em") 1008 .Cases("armv7k", "armv7-k", "armv7k") 1009 .Cases("armv7m", "armv7-m", "armv7m") 1010 .Cases("armv7s", "armv7-s", "armv7s") 1011 .Default(nullptr); 1012 } 1013 1014 static const char *ArmMachOArchNameCPU(StringRef CPU) { 1015 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU); 1016 if (ArchKind == llvm::ARM::ArchKind::INVALID) 1017 return nullptr; 1018 StringRef Arch = llvm::ARM::getArchName(ArchKind); 1019 1020 // FIXME: Make sure this MachO triple mangling is really necessary. 1021 // ARMv5* normalises to ARMv5. 1022 if (Arch.starts_with("armv5")) 1023 Arch = Arch.substr(0, 5); 1024 // ARMv6*, except ARMv6M, normalises to ARMv6. 1025 else if (Arch.starts_with("armv6") && !Arch.ends_with("6m")) 1026 Arch = Arch.substr(0, 5); 1027 // ARMv7A normalises to ARMv7. 1028 else if (Arch.ends_with("v7a")) 1029 Arch = Arch.substr(0, 5); 1030 return Arch.data(); 1031 } 1032 1033 StringRef MachO::getMachOArchName(const ArgList &Args) const { 1034 switch (getTriple().getArch()) { 1035 default: 1036 return getDefaultUniversalArchName(); 1037 1038 case llvm::Triple::aarch64_32: 1039 return "arm64_32"; 1040 1041 case llvm::Triple::aarch64: { 1042 if (getTriple().isArm64e()) 1043 return "arm64e"; 1044 return "arm64"; 1045 } 1046 1047 case llvm::Triple::thumb: 1048 case llvm::Triple::arm: 1049 if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) 1050 if (const char *Arch = ArmMachOArchName(A->getValue())) 1051 return Arch; 1052 1053 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 1054 if (const char *Arch = ArmMachOArchNameCPU(A->getValue())) 1055 return Arch; 1056 1057 return "arm"; 1058 } 1059 } 1060 1061 VersionTuple MachO::getLinkerVersion(const llvm::opt::ArgList &Args) const { 1062 if (LinkerVersion) { 1063 #ifndef NDEBUG 1064 VersionTuple NewLinkerVersion; 1065 if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) 1066 (void)NewLinkerVersion.tryParse(A->getValue()); 1067 assert(NewLinkerVersion == LinkerVersion); 1068 #endif 1069 return *LinkerVersion; 1070 } 1071 1072 VersionTuple NewLinkerVersion; 1073 if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) 1074 if (NewLinkerVersion.tryParse(A->getValue())) 1075 getDriver().Diag(diag::err_drv_invalid_version_number) 1076 << A->getAsString(Args); 1077 1078 LinkerVersion = NewLinkerVersion; 1079 return *LinkerVersion; 1080 } 1081 1082 Darwin::~Darwin() {} 1083 1084 MachO::~MachO() {} 1085 1086 std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 1087 types::ID InputType) const { 1088 llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 1089 1090 // If the target isn't initialized (e.g., an unknown Darwin platform, return 1091 // the default triple). 1092 if (!isTargetInitialized()) 1093 return Triple.getTriple(); 1094 1095 SmallString<16> Str; 1096 if (isTargetWatchOSBased()) 1097 Str += "watchos"; 1098 else if (isTargetTvOSBased()) 1099 Str += "tvos"; 1100 else if (isTargetDriverKit()) 1101 Str += "driverkit"; 1102 else if (isTargetIOSBased() || isTargetMacCatalyst()) 1103 Str += "ios"; 1104 else if (isTargetXROS()) 1105 Str += llvm::Triple::getOSTypeName(llvm::Triple::XROS); 1106 else 1107 Str += "macosx"; 1108 Str += getTripleTargetVersion().getAsString(); 1109 Triple.setOSName(Str); 1110 1111 return Triple.getTriple(); 1112 } 1113 1114 Tool *MachO::getTool(Action::ActionClass AC) const { 1115 switch (AC) { 1116 case Action::LipoJobClass: 1117 if (!Lipo) 1118 Lipo.reset(new tools::darwin::Lipo(*this)); 1119 return Lipo.get(); 1120 case Action::DsymutilJobClass: 1121 if (!Dsymutil) 1122 Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 1123 return Dsymutil.get(); 1124 case Action::VerifyDebugInfoJobClass: 1125 if (!VerifyDebug) 1126 VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 1127 return VerifyDebug.get(); 1128 default: 1129 return ToolChain::getTool(AC); 1130 } 1131 } 1132 1133 Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); } 1134 1135 Tool *MachO::buildStaticLibTool() const { 1136 return new tools::darwin::StaticLibTool(*this); 1137 } 1138 1139 Tool *MachO::buildAssembler() const { 1140 return new tools::darwin::Assembler(*this); 1141 } 1142 1143 DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, 1144 const ArgList &Args) 1145 : Darwin(D, Triple, Args) {} 1146 1147 void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { 1148 // Always error about undefined 'TARGET_OS_*' macros. 1149 CC1Args.push_back("-Wundef-prefix=TARGET_OS_"); 1150 CC1Args.push_back("-Werror=undef-prefix"); 1151 1152 // For modern targets, promote certain warnings to errors. 1153 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { 1154 // Always enable -Wdeprecated-objc-isa-usage and promote it 1155 // to an error. 1156 CC1Args.push_back("-Wdeprecated-objc-isa-usage"); 1157 CC1Args.push_back("-Werror=deprecated-objc-isa-usage"); 1158 1159 // For iOS and watchOS, also error about implicit function declarations, 1160 // as that can impact calling conventions. 1161 if (!isTargetMacOS()) 1162 CC1Args.push_back("-Werror=implicit-function-declaration"); 1163 } 1164 } 1165 1166 /// Take a path that speculatively points into Xcode and return the 1167 /// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path 1168 /// otherwise. 1169 static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) { 1170 static constexpr llvm::StringLiteral XcodeAppSuffix( 1171 ".app/Contents/Developer"); 1172 size_t Index = PathIntoXcode.find(XcodeAppSuffix); 1173 if (Index == StringRef::npos) 1174 return ""; 1175 return PathIntoXcode.take_front(Index + XcodeAppSuffix.size()); 1176 } 1177 1178 void DarwinClang::AddLinkARCArgs(const ArgList &Args, 1179 ArgStringList &CmdArgs) const { 1180 // Avoid linking compatibility stubs on i386 mac. 1181 if (isTargetMacOSBased() && getArch() == llvm::Triple::x86) 1182 return; 1183 if (isTargetAppleSiliconMac()) 1184 return; 1185 // ARC runtime is supported everywhere on arm64e. 1186 if (getTriple().isArm64e()) 1187 return; 1188 if (isTargetXROS()) 1189 return; 1190 1191 ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); 1192 1193 if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) && 1194 runtime.hasSubscripting()) 1195 return; 1196 1197 SmallString<128> P(getDriver().ClangExecutable); 1198 llvm::sys::path::remove_filename(P); // 'clang' 1199 llvm::sys::path::remove_filename(P); // 'bin' 1200 llvm::sys::path::append(P, "lib", "arc"); 1201 1202 // 'libarclite' usually lives in the same toolchain as 'clang'. However, the 1203 // Swift open source toolchains for macOS distribute Clang without libarclite. 1204 // In that case, to allow the linker to find 'libarclite', we point to the 1205 // 'libarclite' in the XcodeDefault toolchain instead. 1206 if (!getVFS().exists(P)) { 1207 auto updatePath = [&](const Arg *A) { 1208 // Try to infer the path to 'libarclite' in the toolchain from the 1209 // specified SDK path. 1210 StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue()); 1211 if (XcodePathForSDK.empty()) 1212 return false; 1213 1214 P = XcodePathForSDK; 1215 llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr", 1216 "lib", "arc"); 1217 return getVFS().exists(P); 1218 }; 1219 1220 bool updated = false; 1221 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) 1222 updated = updatePath(A); 1223 1224 if (!updated) { 1225 if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) 1226 updatePath(A); 1227 } 1228 } 1229 1230 CmdArgs.push_back("-force_load"); 1231 llvm::sys::path::append(P, "libarclite_"); 1232 // Mash in the platform. 1233 if (isTargetWatchOSSimulator()) 1234 P += "watchsimulator"; 1235 else if (isTargetWatchOS()) 1236 P += "watchos"; 1237 else if (isTargetTvOSSimulator()) 1238 P += "appletvsimulator"; 1239 else if (isTargetTvOS()) 1240 P += "appletvos"; 1241 else if (isTargetIOSSimulator()) 1242 P += "iphonesimulator"; 1243 else if (isTargetIPhoneOS()) 1244 P += "iphoneos"; 1245 else 1246 P += "macosx"; 1247 P += ".a"; 1248 1249 if (!getVFS().exists(P)) 1250 getDriver().Diag(clang::diag::err_drv_darwin_sdk_missing_arclite) << P; 1251 1252 CmdArgs.push_back(Args.MakeArgString(P)); 1253 } 1254 1255 unsigned DarwinClang::GetDefaultDwarfVersion() const { 1256 // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower. 1257 if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) || 1258 (isTargetIOSBased() && isIPhoneOSVersionLT(9))) 1259 return 2; 1260 // Default to use DWARF 4 on OS X 10.11 - macOS 14 / iOS 9 - iOS 17. 1261 if ((isTargetMacOSBased() && isMacosxVersionLT(15)) || 1262 (isTargetIOSBased() && isIPhoneOSVersionLT(18)) || 1263 (isTargetWatchOSBased() && TargetVersion < llvm::VersionTuple(11)) || 1264 (isTargetXROS() && TargetVersion < llvm::VersionTuple(2)) || 1265 (isTargetDriverKit() && TargetVersion < llvm::VersionTuple(24)) || 1266 (isTargetMacOSBased() && 1267 TargetVersion.empty())) // apple-darwin, no version. 1268 return 4; 1269 return 5; 1270 } 1271 1272 void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, 1273 StringRef Component, RuntimeLinkOptions Opts, 1274 bool IsShared) const { 1275 std::string P = getCompilerRT( 1276 Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static); 1277 1278 // For now, allow missing resource libraries to support developers who may 1279 // not have compiler-rt checked out or integrated into their build (unless 1280 // we explicitly force linking with this library). 1281 if ((Opts & RLO_AlwaysLink) || getVFS().exists(P)) { 1282 const char *LibArg = Args.MakeArgString(P); 1283 CmdArgs.push_back(LibArg); 1284 } 1285 1286 // Adding the rpaths might negatively interact when other rpaths are involved, 1287 // so we should make sure we add the rpaths last, after all user-specified 1288 // rpaths. This is currently true from this place, but we need to be 1289 // careful if this function is ever called before user's rpaths are emitted. 1290 if (Opts & RLO_AddRPath) { 1291 assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library"); 1292 1293 // Add @executable_path to rpath to support having the dylib copied with 1294 // the executable. 1295 CmdArgs.push_back("-rpath"); 1296 CmdArgs.push_back("@executable_path"); 1297 1298 // Add the compiler-rt library's directory to rpath to support using the 1299 // dylib from the default location without copying. 1300 CmdArgs.push_back("-rpath"); 1301 CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P))); 1302 } 1303 } 1304 1305 std::string MachO::getCompilerRT(const ArgList &, StringRef Component, 1306 FileType Type) const { 1307 assert(Type != ToolChain::FT_Object && 1308 "it doesn't make sense to ask for the compiler-rt library name as an " 1309 "object file"); 1310 SmallString<64> MachOLibName = StringRef("libclang_rt"); 1311 // On MachO, the builtins component is not in the library name 1312 if (Component != "builtins") { 1313 MachOLibName += '.'; 1314 MachOLibName += Component; 1315 } 1316 MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a"; 1317 1318 SmallString<128> FullPath(getDriver().ResourceDir); 1319 llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded", 1320 MachOLibName); 1321 return std::string(FullPath); 1322 } 1323 1324 std::string Darwin::getCompilerRT(const ArgList &, StringRef Component, 1325 FileType Type) const { 1326 assert(Type != ToolChain::FT_Object && 1327 "it doesn't make sense to ask for the compiler-rt library name as an " 1328 "object file"); 1329 SmallString<64> DarwinLibName = StringRef("libclang_rt."); 1330 // On Darwin, the builtins component is not in the library name 1331 if (Component != "builtins") { 1332 DarwinLibName += Component; 1333 DarwinLibName += '_'; 1334 } 1335 DarwinLibName += getOSLibraryNameSuffix(); 1336 DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a"; 1337 1338 SmallString<128> FullPath(getDriver().ResourceDir); 1339 llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName); 1340 return std::string(FullPath); 1341 } 1342 1343 StringRef Darwin::getPlatformFamily() const { 1344 switch (TargetPlatform) { 1345 case DarwinPlatformKind::MacOS: 1346 return "MacOSX"; 1347 case DarwinPlatformKind::IPhoneOS: 1348 if (TargetEnvironment == MacCatalyst) 1349 return "MacOSX"; 1350 return "iPhone"; 1351 case DarwinPlatformKind::TvOS: 1352 return "AppleTV"; 1353 case DarwinPlatformKind::WatchOS: 1354 return "Watch"; 1355 case DarwinPlatformKind::DriverKit: 1356 return "DriverKit"; 1357 case DarwinPlatformKind::XROS: 1358 return "XR"; 1359 } 1360 llvm_unreachable("Unsupported platform"); 1361 } 1362 1363 StringRef Darwin::getSDKName(StringRef isysroot) { 1364 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk 1365 auto BeginSDK = llvm::sys::path::rbegin(isysroot); 1366 auto EndSDK = llvm::sys::path::rend(isysroot); 1367 for (auto IT = BeginSDK; IT != EndSDK; ++IT) { 1368 StringRef SDK = *IT; 1369 if (SDK.ends_with(".sdk")) 1370 return SDK.slice(0, SDK.size() - 4); 1371 } 1372 return ""; 1373 } 1374 1375 StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const { 1376 switch (TargetPlatform) { 1377 case DarwinPlatformKind::MacOS: 1378 return "osx"; 1379 case DarwinPlatformKind::IPhoneOS: 1380 if (TargetEnvironment == MacCatalyst) 1381 return "osx"; 1382 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "ios" 1383 : "iossim"; 1384 case DarwinPlatformKind::TvOS: 1385 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "tvos" 1386 : "tvossim"; 1387 case DarwinPlatformKind::WatchOS: 1388 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos" 1389 : "watchossim"; 1390 case DarwinPlatformKind::XROS: 1391 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "xros" 1392 : "xrossim"; 1393 case DarwinPlatformKind::DriverKit: 1394 return "driverkit"; 1395 } 1396 llvm_unreachable("Unsupported platform"); 1397 } 1398 1399 /// Check if the link command contains a symbol export directive. 1400 static bool hasExportSymbolDirective(const ArgList &Args) { 1401 for (Arg *A : Args) { 1402 if (A->getOption().matches(options::OPT_exported__symbols__list)) 1403 return true; 1404 if (!A->getOption().matches(options::OPT_Wl_COMMA) && 1405 !A->getOption().matches(options::OPT_Xlinker)) 1406 continue; 1407 if (A->containsValue("-exported_symbols_list") || 1408 A->containsValue("-exported_symbol")) 1409 return true; 1410 } 1411 return false; 1412 } 1413 1414 /// Add an export directive for \p Symbol to the link command. 1415 static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) { 1416 CmdArgs.push_back("-exported_symbol"); 1417 CmdArgs.push_back(Symbol); 1418 } 1419 1420 /// Add a sectalign directive for \p Segment and \p Section to the maximum 1421 /// expected page size for Darwin. 1422 /// 1423 /// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K. 1424 /// Use a common alignment constant (16K) for now, and reduce the alignment on 1425 /// macOS if it proves important. 1426 static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs, 1427 StringRef Segment, StringRef Section) { 1428 for (const char *A : {"-sectalign", Args.MakeArgString(Segment), 1429 Args.MakeArgString(Section), "0x4000"}) 1430 CmdArgs.push_back(A); 1431 } 1432 1433 void Darwin::addProfileRTLibs(const ArgList &Args, 1434 ArgStringList &CmdArgs) const { 1435 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args)) 1436 return; 1437 1438 AddLinkRuntimeLib(Args, CmdArgs, "profile", 1439 RuntimeLinkOptions(RLO_AlwaysLink)); 1440 1441 bool ForGCOV = needsGCovInstrumentation(Args); 1442 1443 // If we have a symbol export directive and we're linking in the profile 1444 // runtime, automatically export symbols necessary to implement some of the 1445 // runtime's functionality. 1446 if (hasExportSymbolDirective(Args) && ForGCOV) { 1447 addExportedSymbol(CmdArgs, "___gcov_dump"); 1448 addExportedSymbol(CmdArgs, "___gcov_reset"); 1449 addExportedSymbol(CmdArgs, "_writeout_fn_list"); 1450 addExportedSymbol(CmdArgs, "_reset_fn_list"); 1451 } 1452 1453 // Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page 1454 // alignment. This allows profile counters to be mmap()'d to disk. Note that 1455 // it's not enough to just page-align __llvm_prf_cnts: the following section 1456 // must also be page-aligned so that its data is not clobbered by mmap(). 1457 // 1458 // The section alignment is only needed when continuous profile sync is 1459 // enabled, but this is expected to be the default in Xcode. Specifying the 1460 // extra alignment also allows the same binary to be used with/without sync 1461 // enabled. 1462 if (!ForGCOV) { 1463 for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_bitmap, llvm::IPSK_data}) { 1464 addSectalignToPage( 1465 Args, CmdArgs, "__DATA", 1466 llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO, 1467 /*AddSegmentInfo=*/false)); 1468 } 1469 } 1470 } 1471 1472 void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, 1473 ArgStringList &CmdArgs, 1474 StringRef Sanitizer, 1475 bool Shared) const { 1476 auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U)); 1477 AddLinkRuntimeLib(Args, CmdArgs, Sanitizer, RLO, Shared); 1478 } 1479 1480 ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( 1481 const ArgList &Args) const { 1482 if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) { 1483 StringRef Value = A->getValue(); 1484 if (Value != "compiler-rt" && Value != "platform") 1485 getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform) 1486 << Value << "darwin"; 1487 } 1488 1489 return ToolChain::RLT_CompilerRT; 1490 } 1491 1492 void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 1493 ArgStringList &CmdArgs, 1494 bool ForceLinkBuiltinRT) const { 1495 // Call once to ensure diagnostic is printed if wrong value was specified 1496 GetRuntimeLibType(Args); 1497 1498 // Darwin doesn't support real static executables, don't link any runtime 1499 // libraries with -static. 1500 if (Args.hasArg(options::OPT_static) || 1501 Args.hasArg(options::OPT_fapple_kext) || 1502 Args.hasArg(options::OPT_mkernel)) { 1503 if (ForceLinkBuiltinRT) 1504 AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 1505 return; 1506 } 1507 1508 // Reject -static-libgcc for now, we can deal with this when and if someone 1509 // cares. This is useful in situations where someone wants to statically link 1510 // something like libstdc++, and needs its runtime support routines. 1511 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 1512 getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); 1513 return; 1514 } 1515 1516 const SanitizerArgs &Sanitize = getSanitizerArgs(Args); 1517 1518 if (!Sanitize.needsSharedRt()) { 1519 const char *sanitizer = nullptr; 1520 if (Sanitize.needsUbsanRt()) { 1521 sanitizer = "UndefinedBehaviorSanitizer"; 1522 } else if (Sanitize.needsAsanRt()) { 1523 sanitizer = "AddressSanitizer"; 1524 } else if (Sanitize.needsTsanRt()) { 1525 sanitizer = "ThreadSanitizer"; 1526 } 1527 if (sanitizer) { 1528 getDriver().Diag(diag::err_drv_unsupported_static_sanitizer_darwin) 1529 << sanitizer; 1530 return; 1531 } 1532 } 1533 1534 if (Sanitize.linkRuntimes()) { 1535 if (Sanitize.needsAsanRt()) { 1536 if (Sanitize.needsStableAbi()) { 1537 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan_abi", /*shared=*/false); 1538 } else { 1539 assert(Sanitize.needsSharedRt() && 1540 "Static sanitizer runtimes not supported"); 1541 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); 1542 } 1543 } 1544 if (Sanitize.needsLsanRt()) 1545 AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan"); 1546 if (Sanitize.needsUbsanRt()) { 1547 assert(Sanitize.needsSharedRt() && 1548 "Static sanitizer runtimes not supported"); 1549 AddLinkSanitizerLibArgs( 1550 Args, CmdArgs, 1551 Sanitize.requiresMinimalRuntime() ? "ubsan_minimal" : "ubsan"); 1552 } 1553 if (Sanitize.needsTsanRt()) { 1554 assert(Sanitize.needsSharedRt() && 1555 "Static sanitizer runtimes not supported"); 1556 AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); 1557 } 1558 if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) { 1559 AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false); 1560 1561 // Libfuzzer is written in C++ and requires libcxx. 1562 AddCXXStdlibLibArgs(Args, CmdArgs); 1563 } 1564 if (Sanitize.needsStatsRt()) { 1565 AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink); 1566 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); 1567 } 1568 } 1569 1570 const XRayArgs &XRay = getXRayArgs(); 1571 if (XRay.needsXRayRt()) { 1572 AddLinkRuntimeLib(Args, CmdArgs, "xray"); 1573 AddLinkRuntimeLib(Args, CmdArgs, "xray-basic"); 1574 AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr"); 1575 } 1576 1577 if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) { 1578 CmdArgs.push_back("-framework"); 1579 CmdArgs.push_back("DriverKit"); 1580 } 1581 1582 // Otherwise link libSystem, then the dynamic runtime library, and finally any 1583 // target specific static runtime library. 1584 if (!isTargetDriverKit()) 1585 CmdArgs.push_back("-lSystem"); 1586 1587 // Select the dynamic runtime library and the target specific static library. 1588 if (isTargetIOSBased()) { 1589 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 1590 // it never went into the SDK. 1591 // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 1592 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() && 1593 getTriple().getArch() != llvm::Triple::aarch64) 1594 CmdArgs.push_back("-lgcc_s.1"); 1595 } 1596 AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 1597 } 1598 1599 /// Returns the most appropriate macOS target version for the current process. 1600 /// 1601 /// If the macOS SDK version is the same or earlier than the system version, 1602 /// then the SDK version is returned. Otherwise the system version is returned. 1603 static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) { 1604 llvm::Triple SystemTriple(llvm::sys::getProcessTriple()); 1605 if (!SystemTriple.isMacOSX()) 1606 return std::string(MacOSSDKVersion); 1607 VersionTuple SystemVersion; 1608 SystemTriple.getMacOSXVersion(SystemVersion); 1609 1610 unsigned Major, Minor, Micro; 1611 bool HadExtra; 1612 if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro, 1613 HadExtra)) 1614 return std::string(MacOSSDKVersion); 1615 VersionTuple SDKVersion(Major, Minor, Micro); 1616 1617 if (SDKVersion > SystemVersion) 1618 return SystemVersion.getAsString(); 1619 return std::string(MacOSSDKVersion); 1620 } 1621 1622 namespace { 1623 1624 /// The Darwin OS that was selected or inferred from arguments / environment. 1625 struct DarwinPlatform { 1626 enum SourceKind { 1627 /// The OS was specified using the -target argument. 1628 TargetArg, 1629 /// The OS was specified using the -mtargetos= argument. 1630 MTargetOSArg, 1631 /// The OS was specified using the -m<os>-version-min argument. 1632 OSVersionArg, 1633 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment. 1634 DeploymentTargetEnv, 1635 /// The OS was inferred from the SDK. 1636 InferredFromSDK, 1637 /// The OS was inferred from the -arch. 1638 InferredFromArch 1639 }; 1640 1641 using DarwinPlatformKind = Darwin::DarwinPlatformKind; 1642 using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind; 1643 1644 DarwinPlatformKind getPlatform() const { return Platform; } 1645 1646 DarwinEnvironmentKind getEnvironment() const { return Environment; } 1647 1648 void setEnvironment(DarwinEnvironmentKind Kind) { 1649 Environment = Kind; 1650 InferSimulatorFromArch = false; 1651 } 1652 1653 StringRef getOSVersion() const { 1654 if (Kind == OSVersionArg) 1655 return Argument->getValue(); 1656 return OSVersion; 1657 } 1658 1659 void setOSVersion(StringRef S) { 1660 assert(Kind == TargetArg && "Unexpected kind!"); 1661 OSVersion = std::string(S); 1662 } 1663 1664 bool hasOSVersion() const { return HasOSVersion; } 1665 1666 VersionTuple getNativeTargetVersion() const { 1667 assert(Environment == DarwinEnvironmentKind::MacCatalyst && 1668 "native target version is specified only for Mac Catalyst"); 1669 return NativeTargetVersion; 1670 } 1671 1672 /// Returns true if the target OS was explicitly specified. 1673 bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; } 1674 1675 /// Returns true if the simulator environment can be inferred from the arch. 1676 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; } 1677 1678 const std::optional<llvm::Triple> &getTargetVariantTriple() const { 1679 return TargetVariantTriple; 1680 } 1681 1682 /// Adds the -m<os>-version-min argument to the compiler invocation. 1683 void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) { 1684 if (Argument) 1685 return; 1686 assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg && 1687 "Invalid kind"); 1688 options::ID Opt; 1689 switch (Platform) { 1690 case DarwinPlatformKind::MacOS: 1691 Opt = options::OPT_mmacos_version_min_EQ; 1692 break; 1693 case DarwinPlatformKind::IPhoneOS: 1694 Opt = options::OPT_mios_version_min_EQ; 1695 break; 1696 case DarwinPlatformKind::TvOS: 1697 Opt = options::OPT_mtvos_version_min_EQ; 1698 break; 1699 case DarwinPlatformKind::WatchOS: 1700 Opt = options::OPT_mwatchos_version_min_EQ; 1701 break; 1702 case DarwinPlatformKind::XROS: 1703 // xrOS always explicitly provides a version in the triple. 1704 return; 1705 case DarwinPlatformKind::DriverKit: 1706 // DriverKit always explicitly provides a version in the triple. 1707 return; 1708 } 1709 Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion); 1710 Args.append(Argument); 1711 } 1712 1713 /// Returns the OS version with the argument / environment variable that 1714 /// specified it. 1715 std::string getAsString(DerivedArgList &Args, const OptTable &Opts) { 1716 switch (Kind) { 1717 case TargetArg: 1718 case MTargetOSArg: 1719 case OSVersionArg: 1720 case InferredFromSDK: 1721 case InferredFromArch: 1722 assert(Argument && "OS version argument not yet inferred"); 1723 return Argument->getAsString(Args); 1724 case DeploymentTargetEnv: 1725 return (llvm::Twine(EnvVarName) + "=" + OSVersion).str(); 1726 } 1727 llvm_unreachable("Unsupported Darwin Source Kind"); 1728 } 1729 1730 void setEnvironment(llvm::Triple::EnvironmentType EnvType, 1731 const VersionTuple &OSVersion, 1732 const std::optional<DarwinSDKInfo> &SDKInfo) { 1733 switch (EnvType) { 1734 case llvm::Triple::Simulator: 1735 Environment = DarwinEnvironmentKind::Simulator; 1736 break; 1737 case llvm::Triple::MacABI: { 1738 Environment = DarwinEnvironmentKind::MacCatalyst; 1739 // The minimum native macOS target for MacCatalyst is macOS 10.15. 1740 NativeTargetVersion = VersionTuple(10, 15); 1741 if (HasOSVersion && SDKInfo) { 1742 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping( 1743 DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) { 1744 if (auto MacOSVersion = MacCatalystToMacOSMapping->map( 1745 OSVersion, NativeTargetVersion, std::nullopt)) { 1746 NativeTargetVersion = *MacOSVersion; 1747 } 1748 } 1749 } 1750 // In a zippered build, we could be building for a macOS target that's 1751 // lower than the version that's implied by the OS version. In that case 1752 // we need to use the minimum version as the native target version. 1753 if (TargetVariantTriple) { 1754 auto TargetVariantVersion = TargetVariantTriple->getOSVersion(); 1755 if (TargetVariantVersion.getMajor()) { 1756 if (TargetVariantVersion < NativeTargetVersion) 1757 NativeTargetVersion = TargetVariantVersion; 1758 } 1759 } 1760 break; 1761 } 1762 default: 1763 break; 1764 } 1765 } 1766 1767 static DarwinPlatform 1768 createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A, 1769 std::optional<llvm::Triple> TargetVariantTriple, 1770 const std::optional<DarwinSDKInfo> &SDKInfo) { 1771 DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion, 1772 A); 1773 VersionTuple OsVersion = TT.getOSVersion(); 1774 if (OsVersion.getMajor() == 0) 1775 Result.HasOSVersion = false; 1776 Result.TargetVariantTriple = TargetVariantTriple; 1777 Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo); 1778 return Result; 1779 } 1780 static DarwinPlatform 1781 createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion, 1782 llvm::Triple::EnvironmentType Environment, Arg *A, 1783 const std::optional<DarwinSDKInfo> &SDKInfo) { 1784 DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), 1785 OSVersion.getAsString(), A); 1786 Result.InferSimulatorFromArch = false; 1787 Result.setEnvironment(Environment, OSVersion, SDKInfo); 1788 return Result; 1789 } 1790 static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A, 1791 bool IsSimulator) { 1792 DarwinPlatform Result{OSVersionArg, Platform, A}; 1793 if (IsSimulator) 1794 Result.Environment = DarwinEnvironmentKind::Simulator; 1795 return Result; 1796 } 1797 static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform, 1798 StringRef EnvVarName, 1799 StringRef Value) { 1800 DarwinPlatform Result(DeploymentTargetEnv, Platform, Value); 1801 Result.EnvVarName = EnvVarName; 1802 return Result; 1803 } 1804 static DarwinPlatform createFromSDK(DarwinPlatformKind Platform, 1805 StringRef Value, 1806 bool IsSimulator = false) { 1807 DarwinPlatform Result(InferredFromSDK, Platform, Value); 1808 if (IsSimulator) 1809 Result.Environment = DarwinEnvironmentKind::Simulator; 1810 Result.InferSimulatorFromArch = false; 1811 return Result; 1812 } 1813 static DarwinPlatform createFromArch(llvm::Triple::OSType OS, 1814 StringRef Value) { 1815 return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value); 1816 } 1817 1818 /// Constructs an inferred SDKInfo value based on the version inferred from 1819 /// the SDK path itself. Only works for values that were created by inferring 1820 /// the platform from the SDKPath. 1821 DarwinSDKInfo inferSDKInfo() { 1822 assert(Kind == InferredFromSDK && "can infer SDK info only"); 1823 llvm::VersionTuple Version; 1824 bool IsValid = !Version.tryParse(OSVersion); 1825 (void)IsValid; 1826 assert(IsValid && "invalid SDK version"); 1827 return DarwinSDKInfo( 1828 Version, 1829 /*MaximumDeploymentTarget=*/VersionTuple(Version.getMajor(), 0, 99)); 1830 } 1831 1832 private: 1833 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) 1834 : Kind(Kind), Platform(Platform), Argument(Argument) {} 1835 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value, 1836 Arg *Argument = nullptr) 1837 : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {} 1838 1839 static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) { 1840 switch (OS) { 1841 case llvm::Triple::Darwin: 1842 case llvm::Triple::MacOSX: 1843 return DarwinPlatformKind::MacOS; 1844 case llvm::Triple::IOS: 1845 return DarwinPlatformKind::IPhoneOS; 1846 case llvm::Triple::TvOS: 1847 return DarwinPlatformKind::TvOS; 1848 case llvm::Triple::WatchOS: 1849 return DarwinPlatformKind::WatchOS; 1850 case llvm::Triple::XROS: 1851 return DarwinPlatformKind::XROS; 1852 case llvm::Triple::DriverKit: 1853 return DarwinPlatformKind::DriverKit; 1854 default: 1855 llvm_unreachable("Unable to infer Darwin variant"); 1856 } 1857 } 1858 1859 SourceKind Kind; 1860 DarwinPlatformKind Platform; 1861 DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment; 1862 VersionTuple NativeTargetVersion; 1863 std::string OSVersion; 1864 bool HasOSVersion = true, InferSimulatorFromArch = true; 1865 Arg *Argument; 1866 StringRef EnvVarName; 1867 std::optional<llvm::Triple> TargetVariantTriple; 1868 }; 1869 1870 /// Returns the deployment target that's specified using the -m<os>-version-min 1871 /// argument. 1872 std::optional<DarwinPlatform> 1873 getDeploymentTargetFromOSVersionArg(DerivedArgList &Args, 1874 const Driver &TheDriver) { 1875 Arg *macOSVersion = Args.getLastArg(options::OPT_mmacos_version_min_EQ); 1876 Arg *iOSVersion = Args.getLastArg(options::OPT_mios_version_min_EQ, 1877 options::OPT_mios_simulator_version_min_EQ); 1878 Arg *TvOSVersion = 1879 Args.getLastArg(options::OPT_mtvos_version_min_EQ, 1880 options::OPT_mtvos_simulator_version_min_EQ); 1881 Arg *WatchOSVersion = 1882 Args.getLastArg(options::OPT_mwatchos_version_min_EQ, 1883 options::OPT_mwatchos_simulator_version_min_EQ); 1884 if (macOSVersion) { 1885 if (iOSVersion || TvOSVersion || WatchOSVersion) { 1886 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1887 << macOSVersion->getAsString(Args) 1888 << (iOSVersion ? iOSVersion 1889 : TvOSVersion ? TvOSVersion : WatchOSVersion) 1890 ->getAsString(Args); 1891 } 1892 return DarwinPlatform::createOSVersionArg(Darwin::MacOS, macOSVersion, 1893 /*IsSimulator=*/false); 1894 } else if (iOSVersion) { 1895 if (TvOSVersion || WatchOSVersion) { 1896 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1897 << iOSVersion->getAsString(Args) 1898 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args); 1899 } 1900 return DarwinPlatform::createOSVersionArg( 1901 Darwin::IPhoneOS, iOSVersion, 1902 iOSVersion->getOption().getID() == 1903 options::OPT_mios_simulator_version_min_EQ); 1904 } else if (TvOSVersion) { 1905 if (WatchOSVersion) { 1906 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1907 << TvOSVersion->getAsString(Args) 1908 << WatchOSVersion->getAsString(Args); 1909 } 1910 return DarwinPlatform::createOSVersionArg( 1911 Darwin::TvOS, TvOSVersion, 1912 TvOSVersion->getOption().getID() == 1913 options::OPT_mtvos_simulator_version_min_EQ); 1914 } else if (WatchOSVersion) 1915 return DarwinPlatform::createOSVersionArg( 1916 Darwin::WatchOS, WatchOSVersion, 1917 WatchOSVersion->getOption().getID() == 1918 options::OPT_mwatchos_simulator_version_min_EQ); 1919 return std::nullopt; 1920 } 1921 1922 /// Returns the deployment target that's specified using the 1923 /// OS_DEPLOYMENT_TARGET environment variable. 1924 std::optional<DarwinPlatform> 1925 getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver, 1926 const llvm::Triple &Triple) { 1927 std::string Targets[Darwin::LastDarwinPlatform + 1]; 1928 const char *EnvVars[] = { 1929 "MACOSX_DEPLOYMENT_TARGET", 1930 "IPHONEOS_DEPLOYMENT_TARGET", 1931 "TVOS_DEPLOYMENT_TARGET", 1932 "WATCHOS_DEPLOYMENT_TARGET", 1933 "DRIVERKIT_DEPLOYMENT_TARGET", 1934 "XROS_DEPLOYMENT_TARGET" 1935 }; 1936 static_assert(std::size(EnvVars) == Darwin::LastDarwinPlatform + 1, 1937 "Missing platform"); 1938 for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) { 1939 if (char *Env = ::getenv(I.value())) 1940 Targets[I.index()] = Env; 1941 } 1942 1943 // Allow conflicts among OSX and iOS for historical reasons, but choose the 1944 // default platform. 1945 if (!Targets[Darwin::MacOS].empty() && 1946 (!Targets[Darwin::IPhoneOS].empty() || 1947 !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty() || 1948 !Targets[Darwin::XROS].empty())) { 1949 if (Triple.getArch() == llvm::Triple::arm || 1950 Triple.getArch() == llvm::Triple::aarch64 || 1951 Triple.getArch() == llvm::Triple::thumb) 1952 Targets[Darwin::MacOS] = ""; 1953 else 1954 Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] = 1955 Targets[Darwin::TvOS] = Targets[Darwin::XROS] = ""; 1956 } else { 1957 // Don't allow conflicts in any other platform. 1958 unsigned FirstTarget = std::size(Targets); 1959 for (unsigned I = 0; I != std::size(Targets); ++I) { 1960 if (Targets[I].empty()) 1961 continue; 1962 if (FirstTarget == std::size(Targets)) 1963 FirstTarget = I; 1964 else 1965 TheDriver.Diag(diag::err_drv_conflicting_deployment_targets) 1966 << Targets[FirstTarget] << Targets[I]; 1967 } 1968 } 1969 1970 for (const auto &Target : llvm::enumerate(llvm::ArrayRef(Targets))) { 1971 if (!Target.value().empty()) 1972 return DarwinPlatform::createDeploymentTargetEnv( 1973 (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()], 1974 Target.value()); 1975 } 1976 return std::nullopt; 1977 } 1978 1979 /// Returns the SDK name without the optional prefix that ends with a '.' or an 1980 /// empty string otherwise. 1981 static StringRef dropSDKNamePrefix(StringRef SDKName) { 1982 size_t PrefixPos = SDKName.find('.'); 1983 if (PrefixPos == StringRef::npos) 1984 return ""; 1985 return SDKName.substr(PrefixPos + 1); 1986 } 1987 1988 /// Tries to infer the deployment target from the SDK specified by -isysroot 1989 /// (or SDKROOT). Uses the version specified in the SDKSettings.json file if 1990 /// it's available. 1991 std::optional<DarwinPlatform> 1992 inferDeploymentTargetFromSDK(DerivedArgList &Args, 1993 const std::optional<DarwinSDKInfo> &SDKInfo) { 1994 const Arg *A = Args.getLastArg(options::OPT_isysroot); 1995 if (!A) 1996 return std::nullopt; 1997 StringRef isysroot = A->getValue(); 1998 StringRef SDK = Darwin::getSDKName(isysroot); 1999 if (!SDK.size()) 2000 return std::nullopt; 2001 2002 std::string Version; 2003 if (SDKInfo) { 2004 // Get the version from the SDKSettings.json if it's available. 2005 Version = SDKInfo->getVersion().getAsString(); 2006 } else { 2007 // Slice the version number out. 2008 // Version number is between the first and the last number. 2009 size_t StartVer = SDK.find_first_of("0123456789"); 2010 size_t EndVer = SDK.find_last_of("0123456789"); 2011 if (StartVer != StringRef::npos && EndVer > StartVer) 2012 Version = std::string(SDK.slice(StartVer, EndVer + 1)); 2013 } 2014 if (Version.empty()) 2015 return std::nullopt; 2016 2017 auto CreatePlatformFromSDKName = 2018 [&](StringRef SDK) -> std::optional<DarwinPlatform> { 2019 if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator")) 2020 return DarwinPlatform::createFromSDK( 2021 Darwin::IPhoneOS, Version, 2022 /*IsSimulator=*/SDK.starts_with("iPhoneSimulator")); 2023 else if (SDK.starts_with("MacOSX")) 2024 return DarwinPlatform::createFromSDK(Darwin::MacOS, 2025 getSystemOrSDKMacOSVersion(Version)); 2026 else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator")) 2027 return DarwinPlatform::createFromSDK( 2028 Darwin::WatchOS, Version, 2029 /*IsSimulator=*/SDK.starts_with("WatchSimulator")); 2030 else if (SDK.starts_with("AppleTVOS") || 2031 SDK.starts_with("AppleTVSimulator")) 2032 return DarwinPlatform::createFromSDK( 2033 Darwin::TvOS, Version, 2034 /*IsSimulator=*/SDK.starts_with("AppleTVSimulator")); 2035 else if (SDK.starts_with("XR")) 2036 return DarwinPlatform::createFromSDK( 2037 Darwin::XROS, Version, 2038 /*IsSimulator=*/SDK.contains("Simulator")); 2039 else if (SDK.starts_with("DriverKit")) 2040 return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version); 2041 return std::nullopt; 2042 }; 2043 if (auto Result = CreatePlatformFromSDKName(SDK)) 2044 return Result; 2045 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`. 2046 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK)); 2047 } 2048 2049 std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple, 2050 const Driver &TheDriver) { 2051 VersionTuple OsVersion; 2052 llvm::Triple SystemTriple(llvm::sys::getProcessTriple()); 2053 switch (OS) { 2054 case llvm::Triple::Darwin: 2055 case llvm::Triple::MacOSX: 2056 // If there is no version specified on triple, and both host and target are 2057 // macos, use the host triple to infer OS version. 2058 if (Triple.isMacOSX() && SystemTriple.isMacOSX() && 2059 !Triple.getOSMajorVersion()) 2060 SystemTriple.getMacOSXVersion(OsVersion); 2061 else if (!Triple.getMacOSXVersion(OsVersion)) 2062 TheDriver.Diag(diag::err_drv_invalid_darwin_version) 2063 << Triple.getOSName(); 2064 break; 2065 case llvm::Triple::IOS: 2066 if (Triple.isMacCatalystEnvironment() && !Triple.getOSMajorVersion()) { 2067 OsVersion = VersionTuple(13, 1); 2068 } else 2069 OsVersion = Triple.getiOSVersion(); 2070 break; 2071 case llvm::Triple::TvOS: 2072 OsVersion = Triple.getOSVersion(); 2073 break; 2074 case llvm::Triple::WatchOS: 2075 OsVersion = Triple.getWatchOSVersion(); 2076 break; 2077 case llvm::Triple::XROS: 2078 OsVersion = Triple.getOSVersion(); 2079 if (!OsVersion.getMajor()) 2080 OsVersion = OsVersion.withMajorReplaced(1); 2081 break; 2082 case llvm::Triple::DriverKit: 2083 OsVersion = Triple.getDriverKitVersion(); 2084 break; 2085 default: 2086 llvm_unreachable("Unexpected OS type"); 2087 break; 2088 } 2089 2090 std::string OSVersion; 2091 llvm::raw_string_ostream(OSVersion) 2092 << OsVersion.getMajor() << '.' << OsVersion.getMinor().value_or(0) << '.' 2093 << OsVersion.getSubminor().value_or(0); 2094 return OSVersion; 2095 } 2096 2097 /// Tries to infer the target OS from the -arch. 2098 std::optional<DarwinPlatform> 2099 inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, 2100 const llvm::Triple &Triple, 2101 const Driver &TheDriver) { 2102 llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; 2103 2104 StringRef MachOArchName = Toolchain.getMachOArchName(Args); 2105 if (MachOArchName == "arm64" || MachOArchName == "arm64e") 2106 OSTy = llvm::Triple::MacOSX; 2107 else if (MachOArchName == "armv7" || MachOArchName == "armv7s") 2108 OSTy = llvm::Triple::IOS; 2109 else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32") 2110 OSTy = llvm::Triple::WatchOS; 2111 else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && 2112 MachOArchName != "armv7em") 2113 OSTy = llvm::Triple::MacOSX; 2114 if (OSTy == llvm::Triple::UnknownOS) 2115 return std::nullopt; 2116 return DarwinPlatform::createFromArch(OSTy, 2117 getOSVersion(OSTy, Triple, TheDriver)); 2118 } 2119 2120 /// Returns the deployment target that's specified using the -target option. 2121 std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg( 2122 DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver, 2123 const std::optional<DarwinSDKInfo> &SDKInfo) { 2124 if (!Args.hasArg(options::OPT_target)) 2125 return std::nullopt; 2126 if (Triple.getOS() == llvm::Triple::Darwin || 2127 Triple.getOS() == llvm::Triple::UnknownOS) 2128 return std::nullopt; 2129 std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver); 2130 std::optional<llvm::Triple> TargetVariantTriple; 2131 for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) { 2132 llvm::Triple TVT(A->getValue()); 2133 // Find a matching <arch>-<vendor> target variant triple that can be used. 2134 if ((Triple.getArch() == llvm::Triple::aarch64 || 2135 TVT.getArchName() == Triple.getArchName()) && 2136 TVT.getArch() == Triple.getArch() && 2137 TVT.getSubArch() == Triple.getSubArch() && 2138 TVT.getVendor() == Triple.getVendor()) { 2139 if (TargetVariantTriple) 2140 continue; 2141 A->claim(); 2142 // Accept a -target-variant triple when compiling code that may run on 2143 // macOS or Mac Catalyst. 2144 if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS && 2145 TVT.isMacCatalystEnvironment()) || 2146 (TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS && 2147 Triple.isMacCatalystEnvironment())) { 2148 TargetVariantTriple = TVT; 2149 continue; 2150 } 2151 TheDriver.Diag(diag::err_drv_target_variant_invalid) 2152 << A->getSpelling() << A->getValue(); 2153 } 2154 } 2155 return DarwinPlatform::createFromTarget(Triple, OSVersion, 2156 Args.getLastArg(options::OPT_target), 2157 TargetVariantTriple, SDKInfo); 2158 } 2159 2160 /// Returns the deployment target that's specified using the -mtargetos option. 2161 std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg( 2162 DerivedArgList &Args, const Driver &TheDriver, 2163 const std::optional<DarwinSDKInfo> &SDKInfo) { 2164 auto *A = Args.getLastArg(options::OPT_mtargetos_EQ); 2165 if (!A) 2166 return std::nullopt; 2167 llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue()); 2168 switch (TT.getOS()) { 2169 case llvm::Triple::MacOSX: 2170 case llvm::Triple::IOS: 2171 case llvm::Triple::TvOS: 2172 case llvm::Triple::WatchOS: 2173 case llvm::Triple::XROS: 2174 break; 2175 default: 2176 TheDriver.Diag(diag::err_drv_invalid_os_in_arg) 2177 << TT.getOSName() << A->getAsString(Args); 2178 return std::nullopt; 2179 } 2180 2181 VersionTuple Version = TT.getOSVersion(); 2182 if (!Version.getMajor()) { 2183 TheDriver.Diag(diag::err_drv_invalid_version_number) 2184 << A->getAsString(Args); 2185 return std::nullopt; 2186 } 2187 return DarwinPlatform::createFromMTargetOS(TT.getOS(), Version, 2188 TT.getEnvironment(), A, SDKInfo); 2189 } 2190 2191 std::optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS, 2192 const ArgList &Args, 2193 const Driver &TheDriver) { 2194 const Arg *A = Args.getLastArg(options::OPT_isysroot); 2195 if (!A) 2196 return std::nullopt; 2197 StringRef isysroot = A->getValue(); 2198 auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot); 2199 if (!SDKInfoOrErr) { 2200 llvm::consumeError(SDKInfoOrErr.takeError()); 2201 TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings); 2202 return std::nullopt; 2203 } 2204 return *SDKInfoOrErr; 2205 } 2206 2207 } // namespace 2208 2209 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 2210 const OptTable &Opts = getDriver().getOpts(); 2211 2212 // Support allowing the SDKROOT environment variable used by xcrun and other 2213 // Xcode tools to define the default sysroot, by making it the default for 2214 // isysroot. 2215 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2216 // Warn if the path does not exist. 2217 if (!getVFS().exists(A->getValue())) 2218 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 2219 } else { 2220 if (char *env = ::getenv("SDKROOT")) { 2221 // We only use this value as the default if it is an absolute path, 2222 // exists, and it is not the root path. 2223 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) && 2224 StringRef(env) != "/") { 2225 Args.append(Args.MakeSeparateArg( 2226 nullptr, Opts.getOption(options::OPT_isysroot), env)); 2227 } 2228 } 2229 } 2230 2231 // Read the SDKSettings.json file for more information, like the SDK version 2232 // that we can pass down to the compiler. 2233 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver()); 2234 2235 // The OS and the version can be specified using the -target argument. 2236 std::optional<DarwinPlatform> OSTarget = 2237 getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo); 2238 if (OSTarget) { 2239 // Disallow mixing -target and -mtargetos=. 2240 if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) { 2241 std::string TargetArgStr = OSTarget->getAsString(Args, Opts); 2242 std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args); 2243 getDriver().Diag(diag::err_drv_cannot_mix_options) 2244 << TargetArgStr << MTargetOSArgStr; 2245 } 2246 std::optional<DarwinPlatform> OSVersionArgTarget = 2247 getDeploymentTargetFromOSVersionArg(Args, getDriver()); 2248 if (OSVersionArgTarget) { 2249 unsigned TargetMajor, TargetMinor, TargetMicro; 2250 bool TargetExtra; 2251 unsigned ArgMajor, ArgMinor, ArgMicro; 2252 bool ArgExtra; 2253 if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() || 2254 (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor, 2255 TargetMinor, TargetMicro, TargetExtra) && 2256 Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(), 2257 ArgMajor, ArgMinor, ArgMicro, ArgExtra) && 2258 (VersionTuple(TargetMajor, TargetMinor, TargetMicro) != 2259 VersionTuple(ArgMajor, ArgMinor, ArgMicro) || 2260 TargetExtra != ArgExtra))) { 2261 // Select the OS version from the -m<os>-version-min argument when 2262 // the -target does not include an OS version. 2263 if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() && 2264 !OSTarget->hasOSVersion()) { 2265 OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion()); 2266 } else { 2267 // Warn about -m<os>-version-min that doesn't match the OS version 2268 // that's specified in the target. 2269 std::string OSVersionArg = 2270 OSVersionArgTarget->getAsString(Args, Opts); 2271 std::string TargetArg = OSTarget->getAsString(Args, Opts); 2272 getDriver().Diag(clang::diag::warn_drv_overriding_option) 2273 << OSVersionArg << TargetArg; 2274 } 2275 } 2276 } 2277 } else if ((OSTarget = getDeploymentTargetFromMTargetOSArg(Args, getDriver(), 2278 SDKInfo))) { 2279 // The OS target can be specified using the -mtargetos= argument. 2280 // Disallow mixing -mtargetos= and -m<os>version-min=. 2281 std::optional<DarwinPlatform> OSVersionArgTarget = 2282 getDeploymentTargetFromOSVersionArg(Args, getDriver()); 2283 if (OSVersionArgTarget) { 2284 std::string MTargetOSArgStr = OSTarget->getAsString(Args, Opts); 2285 std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts); 2286 getDriver().Diag(diag::err_drv_cannot_mix_options) 2287 << MTargetOSArgStr << OSVersionArgStr; 2288 } 2289 } else { 2290 // The OS target can be specified using the -m<os>version-min argument. 2291 OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver()); 2292 // If no deployment target was specified on the command line, check for 2293 // environment defines. 2294 if (!OSTarget) { 2295 OSTarget = 2296 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); 2297 if (OSTarget) { 2298 // Don't infer simulator from the arch when the SDK is also specified. 2299 std::optional<DarwinPlatform> SDKTarget = 2300 inferDeploymentTargetFromSDK(Args, SDKInfo); 2301 if (SDKTarget) 2302 OSTarget->setEnvironment(SDKTarget->getEnvironment()); 2303 } 2304 } 2305 // If there is no command-line argument to specify the Target version and 2306 // no environment variable defined, see if we can set the default based 2307 // on -isysroot using SDKSettings.json if it exists. 2308 if (!OSTarget) { 2309 OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo); 2310 /// If the target was successfully constructed from the SDK path, try to 2311 /// infer the SDK info if the SDK doesn't have it. 2312 if (OSTarget && !SDKInfo) 2313 SDKInfo = OSTarget->inferSDKInfo(); 2314 } 2315 // If no OS targets have been specified, try to guess platform from -target 2316 // or arch name and compute the version from the triple. 2317 if (!OSTarget) 2318 OSTarget = 2319 inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); 2320 } 2321 2322 assert(OSTarget && "Unable to infer Darwin variant"); 2323 OSTarget->addOSVersionMinArgument(Args, Opts); 2324 DarwinPlatformKind Platform = OSTarget->getPlatform(); 2325 2326 unsigned Major, Minor, Micro; 2327 bool HadExtra; 2328 // The major version should not be over this number. 2329 const unsigned MajorVersionLimit = 1000; 2330 // Set the tool chain target information. 2331 if (Platform == MacOS) { 2332 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2333 Micro, HadExtra) || 2334 HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 || 2335 Micro >= 100) 2336 getDriver().Diag(diag::err_drv_invalid_version_number) 2337 << OSTarget->getAsString(Args, Opts); 2338 } else if (Platform == IPhoneOS) { 2339 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2340 Micro, HadExtra) || 2341 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100) 2342 getDriver().Diag(diag::err_drv_invalid_version_number) 2343 << OSTarget->getAsString(Args, Opts); 2344 ; 2345 if (OSTarget->getEnvironment() == MacCatalyst && 2346 (Major < 13 || (Major == 13 && Minor < 1))) { 2347 getDriver().Diag(diag::err_drv_invalid_version_number) 2348 << OSTarget->getAsString(Args, Opts); 2349 Major = 13; 2350 Minor = 1; 2351 Micro = 0; 2352 } 2353 // For 32-bit targets, the deployment target for iOS has to be earlier than 2354 // iOS 11. 2355 if (getTriple().isArch32Bit() && Major >= 11) { 2356 // If the deployment target is explicitly specified, print a diagnostic. 2357 if (OSTarget->isExplicitlySpecified()) { 2358 if (OSTarget->getEnvironment() == MacCatalyst) 2359 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target); 2360 else 2361 getDriver().Diag(diag::warn_invalid_ios_deployment_target) 2362 << OSTarget->getAsString(Args, Opts); 2363 // Otherwise, set it to 10.99.99. 2364 } else { 2365 Major = 10; 2366 Minor = 99; 2367 Micro = 99; 2368 } 2369 } 2370 } else if (Platform == TvOS) { 2371 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2372 Micro, HadExtra) || 2373 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100) 2374 getDriver().Diag(diag::err_drv_invalid_version_number) 2375 << OSTarget->getAsString(Args, Opts); 2376 } else if (Platform == WatchOS) { 2377 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2378 Micro, HadExtra) || 2379 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100) 2380 getDriver().Diag(diag::err_drv_invalid_version_number) 2381 << OSTarget->getAsString(Args, Opts); 2382 } else if (Platform == DriverKit) { 2383 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2384 Micro, HadExtra) || 2385 HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 || 2386 Micro >= 100) 2387 getDriver().Diag(diag::err_drv_invalid_version_number) 2388 << OSTarget->getAsString(Args, Opts); 2389 } else if (Platform == XROS) { 2390 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 2391 Micro, HadExtra) || 2392 HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 || 2393 Micro >= 100) 2394 getDriver().Diag(diag::err_drv_invalid_version_number) 2395 << OSTarget->getAsString(Args, Opts); 2396 } else 2397 llvm_unreachable("unknown kind of Darwin platform"); 2398 2399 DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); 2400 // Recognize iOS targets with an x86 architecture as the iOS simulator. 2401 if (Environment == NativeEnvironment && Platform != MacOS && 2402 Platform != DriverKit && OSTarget->canInferSimulatorFromArch() && 2403 getTriple().isX86()) 2404 Environment = Simulator; 2405 2406 VersionTuple NativeTargetVersion; 2407 if (Environment == MacCatalyst) 2408 NativeTargetVersion = OSTarget->getNativeTargetVersion(); 2409 setTarget(Platform, Environment, Major, Minor, Micro, NativeTargetVersion); 2410 TargetVariantTriple = OSTarget->getTargetVariantTriple(); 2411 2412 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2413 StringRef SDK = getSDKName(A->getValue()); 2414 if (SDK.size() > 0) { 2415 size_t StartVer = SDK.find_first_of("0123456789"); 2416 StringRef SDKName = SDK.slice(0, StartVer); 2417 if (!SDKName.starts_with(getPlatformFamily()) && 2418 !dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily())) 2419 getDriver().Diag(diag::warn_incompatible_sysroot) 2420 << SDKName << getPlatformFamily(); 2421 } 2422 } 2423 } 2424 2425 // For certain platforms/environments almost all resources (e.g., headers) are 2426 // located in sub-directories, e.g., for DriverKit they live in 2427 // <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include). 2428 static void AppendPlatformPrefix(SmallString<128> &Path, 2429 const llvm::Triple &T) { 2430 if (T.isDriverKit()) { 2431 llvm::sys::path::append(Path, "System", "DriverKit"); 2432 } 2433 } 2434 2435 // Returns the effective sysroot from either -isysroot or --sysroot, plus the 2436 // platform prefix (if any). 2437 llvm::SmallString<128> 2438 DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const { 2439 llvm::SmallString<128> Path("/"); 2440 if (DriverArgs.hasArg(options::OPT_isysroot)) 2441 Path = DriverArgs.getLastArgValue(options::OPT_isysroot); 2442 else if (!getDriver().SysRoot.empty()) 2443 Path = getDriver().SysRoot; 2444 2445 if (hasEffectiveTriple()) { 2446 AppendPlatformPrefix(Path, getEffectiveTriple()); 2447 } 2448 return Path; 2449 } 2450 2451 void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 2452 llvm::opt::ArgStringList &CC1Args) const { 2453 const Driver &D = getDriver(); 2454 2455 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs); 2456 2457 bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc); 2458 bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc); 2459 bool NoBuiltinInc = DriverArgs.hasFlag( 2460 options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false); 2461 bool ForceBuiltinInc = DriverArgs.hasFlag( 2462 options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false); 2463 2464 // Add <sysroot>/usr/local/include 2465 if (!NoStdInc && !NoStdlibInc) { 2466 SmallString<128> P(Sysroot); 2467 llvm::sys::path::append(P, "usr", "local", "include"); 2468 addSystemInclude(DriverArgs, CC1Args, P); 2469 } 2470 2471 // Add the Clang builtin headers (<resource>/include) 2472 if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) { 2473 SmallString<128> P(D.ResourceDir); 2474 llvm::sys::path::append(P, "include"); 2475 addSystemInclude(DriverArgs, CC1Args, P); 2476 } 2477 2478 if (NoStdInc || NoStdlibInc) 2479 return; 2480 2481 // Check for configure-time C include directories. 2482 llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); 2483 if (!CIncludeDirs.empty()) { 2484 llvm::SmallVector<llvm::StringRef, 5> dirs; 2485 CIncludeDirs.split(dirs, ":"); 2486 for (llvm::StringRef dir : dirs) { 2487 llvm::StringRef Prefix = 2488 llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot); 2489 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 2490 } 2491 } else { 2492 // Otherwise, add <sysroot>/usr/include. 2493 SmallString<128> P(Sysroot); 2494 llvm::sys::path::append(P, "usr", "include"); 2495 addExternCSystemInclude(DriverArgs, CC1Args, P.str()); 2496 } 2497 } 2498 2499 bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 2500 llvm::opt::ArgStringList &CC1Args, 2501 llvm::SmallString<128> Base, 2502 llvm::StringRef Version, 2503 llvm::StringRef ArchDir, 2504 llvm::StringRef BitDir) const { 2505 llvm::sys::path::append(Base, Version); 2506 2507 // Add the base dir 2508 addSystemInclude(DriverArgs, CC1Args, Base); 2509 2510 // Add the multilib dirs 2511 { 2512 llvm::SmallString<128> P = Base; 2513 if (!ArchDir.empty()) 2514 llvm::sys::path::append(P, ArchDir); 2515 if (!BitDir.empty()) 2516 llvm::sys::path::append(P, BitDir); 2517 addSystemInclude(DriverArgs, CC1Args, P); 2518 } 2519 2520 // Add the backward dir 2521 { 2522 llvm::SmallString<128> P = Base; 2523 llvm::sys::path::append(P, "backward"); 2524 addSystemInclude(DriverArgs, CC1Args, P); 2525 } 2526 2527 return getVFS().exists(Base); 2528 } 2529 2530 void DarwinClang::AddClangCXXStdlibIncludeArgs( 2531 const llvm::opt::ArgList &DriverArgs, 2532 llvm::opt::ArgStringList &CC1Args) const { 2533 // The implementation from a base class will pass through the -stdlib to 2534 // CC1Args. 2535 // FIXME: this should not be necessary, remove usages in the frontend 2536 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib. 2537 // Also check whether this is used for setting library search paths. 2538 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args); 2539 2540 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc, 2541 options::OPT_nostdincxx)) 2542 return; 2543 2544 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs); 2545 2546 switch (GetCXXStdlibType(DriverArgs)) { 2547 case ToolChain::CST_Libcxx: { 2548 // On Darwin, libc++ can be installed in one of the following places: 2549 // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1 2550 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1 2551 // 2552 // The precedence of paths is as listed above, i.e. we take the first path 2553 // that exists. Note that we never include libc++ twice -- we take the first 2554 // path that exists and don't send the other paths to CC1 (otherwise 2555 // include_next could break). 2556 2557 // Check for (1) 2558 // Get from '<install>/bin' to '<install>/include/c++/v1'. 2559 // Note that InstallBin can be relative, so we use '..' instead of 2560 // parent_path. 2561 llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin 2562 llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1"); 2563 if (getVFS().exists(InstallBin)) { 2564 addSystemInclude(DriverArgs, CC1Args, InstallBin); 2565 return; 2566 } else if (DriverArgs.hasArg(options::OPT_v)) { 2567 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin 2568 << "\"\n"; 2569 } 2570 2571 // Otherwise, check for (2) 2572 llvm::SmallString<128> SysrootUsr = Sysroot; 2573 llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); 2574 if (getVFS().exists(SysrootUsr)) { 2575 addSystemInclude(DriverArgs, CC1Args, SysrootUsr); 2576 return; 2577 } else if (DriverArgs.hasArg(options::OPT_v)) { 2578 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr 2579 << "\"\n"; 2580 } 2581 2582 // Otherwise, don't add any path. 2583 break; 2584 } 2585 2586 case ToolChain::CST_Libstdcxx: 2587 llvm::SmallString<128> UsrIncludeCxx = Sysroot; 2588 llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); 2589 2590 llvm::Triple::ArchType arch = getTriple().getArch(); 2591 bool IsBaseFound = true; 2592 switch (arch) { 2593 default: break; 2594 2595 case llvm::Triple::x86: 2596 case llvm::Triple::x86_64: 2597 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2598 "4.2.1", 2599 "i686-apple-darwin10", 2600 arch == llvm::Triple::x86_64 ? "x86_64" : ""); 2601 IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2602 "4.0.0", "i686-apple-darwin8", 2603 ""); 2604 break; 2605 2606 case llvm::Triple::arm: 2607 case llvm::Triple::thumb: 2608 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2609 "4.2.1", 2610 "arm-apple-darwin10", 2611 "v7"); 2612 IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2613 "4.2.1", 2614 "arm-apple-darwin10", 2615 "v6"); 2616 break; 2617 2618 case llvm::Triple::aarch64: 2619 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2620 "4.2.1", 2621 "arm64-apple-darwin10", 2622 ""); 2623 break; 2624 } 2625 2626 if (!IsBaseFound) { 2627 getDriver().Diag(diag::warn_drv_libstdcxx_not_found); 2628 } 2629 2630 break; 2631 } 2632 } 2633 2634 void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 2635 ArgStringList &CmdArgs) const { 2636 CXXStdlibType Type = GetCXXStdlibType(Args); 2637 2638 switch (Type) { 2639 case ToolChain::CST_Libcxx: 2640 CmdArgs.push_back("-lc++"); 2641 if (Args.hasArg(options::OPT_fexperimental_library)) 2642 CmdArgs.push_back("-lc++experimental"); 2643 break; 2644 2645 case ToolChain::CST_Libstdcxx: 2646 // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 2647 // it was previously found in the gcc lib dir. However, for all the Darwin 2648 // platforms we care about it was -lstdc++.6, so we search for that 2649 // explicitly if we can't see an obvious -lstdc++ candidate. 2650 2651 // Check in the sysroot first. 2652 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2653 SmallString<128> P(A->getValue()); 2654 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 2655 2656 if (!getVFS().exists(P)) { 2657 llvm::sys::path::remove_filename(P); 2658 llvm::sys::path::append(P, "libstdc++.6.dylib"); 2659 if (getVFS().exists(P)) { 2660 CmdArgs.push_back(Args.MakeArgString(P)); 2661 return; 2662 } 2663 } 2664 } 2665 2666 // Otherwise, look in the root. 2667 // FIXME: This should be removed someday when we don't have to care about 2668 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 2669 if (!getVFS().exists("/usr/lib/libstdc++.dylib") && 2670 getVFS().exists("/usr/lib/libstdc++.6.dylib")) { 2671 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 2672 return; 2673 } 2674 2675 // Otherwise, let the linker search. 2676 CmdArgs.push_back("-lstdc++"); 2677 break; 2678 } 2679 } 2680 2681 void DarwinClang::AddCCKextLibArgs(const ArgList &Args, 2682 ArgStringList &CmdArgs) const { 2683 // For Darwin platforms, use the compiler-rt-based support library 2684 // instead of the gcc-provided one (which is also incidentally 2685 // only present in the gcc lib dir, which makes it hard to find). 2686 2687 SmallString<128> P(getDriver().ResourceDir); 2688 llvm::sys::path::append(P, "lib", "darwin"); 2689 2690 // Use the newer cc_kext for iOS ARM after 6.0. 2691 if (isTargetWatchOS()) { 2692 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a"); 2693 } else if (isTargetTvOS()) { 2694 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); 2695 } else if (isTargetIPhoneOS()) { 2696 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); 2697 } else if (isTargetDriverKit()) { 2698 // DriverKit doesn't want extra runtime support. 2699 } else if (isTargetXROSDevice()) { 2700 llvm::sys::path::append( 2701 P, llvm::Twine("libclang_rt.cc_kext_") + 2702 llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a"); 2703 } else { 2704 llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 2705 } 2706 2707 // For now, allow missing resource libraries to support developers who may 2708 // not have compiler-rt checked out or integrated into their build. 2709 if (getVFS().exists(P)) 2710 CmdArgs.push_back(Args.MakeArgString(P)); 2711 } 2712 2713 DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, 2714 StringRef BoundArch, 2715 Action::OffloadKind) const { 2716 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 2717 const OptTable &Opts = getDriver().getOpts(); 2718 2719 // FIXME: We really want to get out of the tool chain level argument 2720 // translation business, as it makes the driver functionality much 2721 // more opaque. For now, we follow gcc closely solely for the 2722 // purpose of easily achieving feature parity & testability. Once we 2723 // have something that works, we should reevaluate each translation 2724 // and try to push it down into tool specific logic. 2725 2726 for (Arg *A : Args) { 2727 if (A->getOption().matches(options::OPT_Xarch__)) { 2728 // Skip this argument unless the architecture matches either the toolchain 2729 // triple arch, or the arch being bound. 2730 StringRef XarchArch = A->getValue(0); 2731 if (!(XarchArch == getArchName() || 2732 (!BoundArch.empty() && XarchArch == BoundArch))) 2733 continue; 2734 2735 Arg *OriginalArg = A; 2736 TranslateXarchArgs(Args, A, DAL); 2737 2738 // Linker input arguments require custom handling. The problem is that we 2739 // have already constructed the phase actions, so we can not treat them as 2740 // "input arguments". 2741 if (A->getOption().hasFlag(options::LinkerInput)) { 2742 // Convert the argument into individual Zlinker_input_args. 2743 for (const char *Value : A->getValues()) { 2744 DAL->AddSeparateArg( 2745 OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); 2746 } 2747 continue; 2748 } 2749 } 2750 2751 // Sob. These is strictly gcc compatible for the time being. Apple 2752 // gcc translates options twice, which means that self-expanding 2753 // options add duplicates. 2754 switch ((options::ID)A->getOption().getID()) { 2755 default: 2756 DAL->append(A); 2757 break; 2758 2759 case options::OPT_mkernel: 2760 case options::OPT_fapple_kext: 2761 DAL->append(A); 2762 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 2763 break; 2764 2765 case options::OPT_dependency_file: 2766 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); 2767 break; 2768 2769 case options::OPT_gfull: 2770 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2771 DAL->AddFlagArg( 2772 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 2773 break; 2774 2775 case options::OPT_gused: 2776 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2777 DAL->AddFlagArg( 2778 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 2779 break; 2780 2781 case options::OPT_shared: 2782 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 2783 break; 2784 2785 case options::OPT_fconstant_cfstrings: 2786 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 2787 break; 2788 2789 case options::OPT_fno_constant_cfstrings: 2790 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 2791 break; 2792 2793 case options::OPT_Wnonportable_cfstrings: 2794 DAL->AddFlagArg(A, 2795 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 2796 break; 2797 2798 case options::OPT_Wno_nonportable_cfstrings: 2799 DAL->AddFlagArg( 2800 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 2801 break; 2802 } 2803 } 2804 2805 // Add the arch options based on the particular spelling of -arch, to match 2806 // how the driver works. 2807 if (!BoundArch.empty()) { 2808 StringRef Name = BoundArch; 2809 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 2810 const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ); 2811 2812 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 2813 // which defines the list of which architectures we accept. 2814 if (Name == "ppc") 2815 ; 2816 else if (Name == "ppc601") 2817 DAL->AddJoinedArg(nullptr, MCpu, "601"); 2818 else if (Name == "ppc603") 2819 DAL->AddJoinedArg(nullptr, MCpu, "603"); 2820 else if (Name == "ppc604") 2821 DAL->AddJoinedArg(nullptr, MCpu, "604"); 2822 else if (Name == "ppc604e") 2823 DAL->AddJoinedArg(nullptr, MCpu, "604e"); 2824 else if (Name == "ppc750") 2825 DAL->AddJoinedArg(nullptr, MCpu, "750"); 2826 else if (Name == "ppc7400") 2827 DAL->AddJoinedArg(nullptr, MCpu, "7400"); 2828 else if (Name == "ppc7450") 2829 DAL->AddJoinedArg(nullptr, MCpu, "7450"); 2830 else if (Name == "ppc970") 2831 DAL->AddJoinedArg(nullptr, MCpu, "970"); 2832 2833 else if (Name == "ppc64" || Name == "ppc64le") 2834 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2835 2836 else if (Name == "i386") 2837 ; 2838 else if (Name == "i486") 2839 DAL->AddJoinedArg(nullptr, MArch, "i486"); 2840 else if (Name == "i586") 2841 DAL->AddJoinedArg(nullptr, MArch, "i586"); 2842 else if (Name == "i686") 2843 DAL->AddJoinedArg(nullptr, MArch, "i686"); 2844 else if (Name == "pentium") 2845 DAL->AddJoinedArg(nullptr, MArch, "pentium"); 2846 else if (Name == "pentium2") 2847 DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2848 else if (Name == "pentpro") 2849 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro"); 2850 else if (Name == "pentIIm3") 2851 DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2852 2853 else if (Name == "x86_64" || Name == "x86_64h") 2854 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2855 2856 else if (Name == "arm") 2857 DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2858 else if (Name == "armv4t") 2859 DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2860 else if (Name == "armv5") 2861 DAL->AddJoinedArg(nullptr, MArch, "armv5tej"); 2862 else if (Name == "xscale") 2863 DAL->AddJoinedArg(nullptr, MArch, "xscale"); 2864 else if (Name == "armv6") 2865 DAL->AddJoinedArg(nullptr, MArch, "armv6k"); 2866 else if (Name == "armv6m") 2867 DAL->AddJoinedArg(nullptr, MArch, "armv6m"); 2868 else if (Name == "armv7") 2869 DAL->AddJoinedArg(nullptr, MArch, "armv7a"); 2870 else if (Name == "armv7em") 2871 DAL->AddJoinedArg(nullptr, MArch, "armv7em"); 2872 else if (Name == "armv7k") 2873 DAL->AddJoinedArg(nullptr, MArch, "armv7k"); 2874 else if (Name == "armv7m") 2875 DAL->AddJoinedArg(nullptr, MArch, "armv7m"); 2876 else if (Name == "armv7s") 2877 DAL->AddJoinedArg(nullptr, MArch, "armv7s"); 2878 } 2879 2880 return DAL; 2881 } 2882 2883 void MachO::AddLinkRuntimeLibArgs(const ArgList &Args, 2884 ArgStringList &CmdArgs, 2885 bool ForceLinkBuiltinRT) const { 2886 // Embedded targets are simple at the moment, not supporting sanitizers and 2887 // with different libraries for each member of the product { static, PIC } x 2888 // { hard-float, soft-float } 2889 llvm::SmallString<32> CompilerRT = StringRef(""); 2890 CompilerRT += 2891 (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard) 2892 ? "hard" 2893 : "soft"; 2894 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static"; 2895 2896 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded); 2897 } 2898 2899 bool Darwin::isAlignedAllocationUnavailable() const { 2900 llvm::Triple::OSType OS; 2901 2902 if (isTargetMacCatalyst()) 2903 return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX); 2904 switch (TargetPlatform) { 2905 case MacOS: // Earlier than 10.13. 2906 OS = llvm::Triple::MacOSX; 2907 break; 2908 case IPhoneOS: 2909 OS = llvm::Triple::IOS; 2910 break; 2911 case TvOS: // Earlier than 11.0. 2912 OS = llvm::Triple::TvOS; 2913 break; 2914 case WatchOS: // Earlier than 4.0. 2915 OS = llvm::Triple::WatchOS; 2916 break; 2917 case XROS: // Always available. 2918 return false; 2919 case DriverKit: // Always available. 2920 return false; 2921 } 2922 2923 return TargetVersion < alignedAllocMinVersion(OS); 2924 } 2925 2926 static bool sdkSupportsBuiltinModules( 2927 const Darwin::DarwinPlatformKind &TargetPlatform, 2928 const Darwin::DarwinEnvironmentKind &TargetEnvironment, 2929 const std::optional<DarwinSDKInfo> &SDKInfo) { 2930 if (TargetEnvironment == Darwin::NativeEnvironment || 2931 TargetEnvironment == Darwin::Simulator || 2932 TargetEnvironment == Darwin::MacCatalyst) { 2933 // Standard xnu/Mach/Darwin based environments 2934 // depend on the SDK version. 2935 } else { 2936 // All other environments support builtin modules from the start. 2937 return true; 2938 } 2939 2940 if (!SDKInfo) 2941 // If there is no SDK info, assume this is building against a 2942 // pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those 2943 // don't support modules anyway, but the headers definitely 2944 // don't support builtin modules either. It might also be some 2945 // kind of degenerate build environment, err on the side of 2946 // the old behavior which is to not use builtin modules. 2947 return false; 2948 2949 VersionTuple SDKVersion = SDKInfo->getVersion(); 2950 switch (TargetPlatform) { 2951 // Existing SDKs added support for builtin modules in the fall 2952 // 2024 major releases. 2953 case Darwin::MacOS: 2954 return SDKVersion >= VersionTuple(15U); 2955 case Darwin::IPhoneOS: 2956 switch (TargetEnvironment) { 2957 case Darwin::MacCatalyst: 2958 // Mac Catalyst uses `-target arm64-apple-ios18.0-macabi` so the platform 2959 // is iOS, but it builds with the macOS SDK, so it's the macOS SDK version 2960 // that's relevant. 2961 return SDKVersion >= VersionTuple(15U); 2962 default: 2963 return SDKVersion >= VersionTuple(18U); 2964 } 2965 case Darwin::TvOS: 2966 return SDKVersion >= VersionTuple(18U); 2967 case Darwin::WatchOS: 2968 return SDKVersion >= VersionTuple(11U); 2969 case Darwin::XROS: 2970 return SDKVersion >= VersionTuple(2U); 2971 2972 // New SDKs support builtin modules from the start. 2973 default: 2974 return true; 2975 } 2976 } 2977 2978 static inline llvm::VersionTuple 2979 sizedDeallocMinVersion(llvm::Triple::OSType OS) { 2980 switch (OS) { 2981 default: 2982 break; 2983 case llvm::Triple::Darwin: 2984 case llvm::Triple::MacOSX: // Earliest supporting version is 10.12. 2985 return llvm::VersionTuple(10U, 12U); 2986 case llvm::Triple::IOS: 2987 case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0. 2988 return llvm::VersionTuple(10U); 2989 case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0. 2990 return llvm::VersionTuple(3U); 2991 } 2992 2993 llvm_unreachable("Unexpected OS"); 2994 } 2995 2996 bool Darwin::isSizedDeallocationUnavailable() const { 2997 llvm::Triple::OSType OS; 2998 2999 if (isTargetMacCatalyst()) 3000 return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX); 3001 switch (TargetPlatform) { 3002 case MacOS: // Earlier than 10.12. 3003 OS = llvm::Triple::MacOSX; 3004 break; 3005 case IPhoneOS: 3006 OS = llvm::Triple::IOS; 3007 break; 3008 case TvOS: // Earlier than 10.0. 3009 OS = llvm::Triple::TvOS; 3010 break; 3011 case WatchOS: // Earlier than 3.0. 3012 OS = llvm::Triple::WatchOS; 3013 break; 3014 case DriverKit: 3015 case XROS: 3016 // Always available. 3017 return false; 3018 } 3019 3020 return TargetVersion < sizedDeallocMinVersion(OS); 3021 } 3022 3023 void Darwin::addClangTargetOptions( 3024 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, 3025 Action::OffloadKind DeviceOffloadKind) const { 3026 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually 3027 // enabled or disabled aligned allocations. 3028 if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, 3029 options::OPT_fno_aligned_allocation) && 3030 isAlignedAllocationUnavailable()) 3031 CC1Args.push_back("-faligned-alloc-unavailable"); 3032 3033 // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled 3034 // or disabled sized deallocations. 3035 if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation, 3036 options::OPT_fno_sized_deallocation) && 3037 isSizedDeallocationUnavailable()) 3038 CC1Args.push_back("-fno-sized-deallocation"); 3039 3040 addClangCC1ASTargetOptions(DriverArgs, CC1Args); 3041 3042 // Enable compatibility mode for NSItemProviderCompletionHandler in 3043 // Foundation/NSItemProvider.h. 3044 CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking"); 3045 3046 // Give static local variables in inline functions hidden visibility when 3047 // -fvisibility-inlines-hidden is enabled. 3048 if (!DriverArgs.getLastArgNoClaim( 3049 options::OPT_fvisibility_inlines_hidden_static_local_var, 3050 options::OPT_fno_visibility_inlines_hidden_static_local_var)) 3051 CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var"); 3052 3053 // Earlier versions of the darwin SDK have the C standard library headers 3054 // all together in the Darwin module. That leads to module cycles with 3055 // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>. 3056 // The builtin <stdint.h> include-nexts <stdint.h>. When both of those 3057 // darwin headers are in the Darwin module, there's a module cycle Darwin -> 3058 // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) -> 3059 // stdint.h (darwin)). This is fixed in later versions of the darwin SDK, 3060 // but until then, the builtin headers need to join the system modules. 3061 // i.e. when the builtin stdint.h is in the Darwin module too, the cycle 3062 // goes away. Note that -fbuiltin-headers-in-system-modules does nothing 3063 // to fix the same problem with C++ headers, and is generally fragile. 3064 if (!sdkSupportsBuiltinModules(TargetPlatform, TargetEnvironment, SDKInfo)) 3065 CC1Args.push_back("-fbuiltin-headers-in-system-modules"); 3066 3067 if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros, 3068 options::OPT_fno_define_target_os_macros)) 3069 CC1Args.push_back("-fdefine-target-os-macros"); 3070 } 3071 3072 void Darwin::addClangCC1ASTargetOptions( 3073 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const { 3074 if (TargetVariantTriple) { 3075 CC1ASArgs.push_back("-darwin-target-variant-triple"); 3076 CC1ASArgs.push_back(Args.MakeArgString(TargetVariantTriple->getTriple())); 3077 } 3078 3079 if (SDKInfo) { 3080 /// Pass the SDK version to the compiler when the SDK information is 3081 /// available. 3082 auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) { 3083 std::string Arg; 3084 llvm::raw_string_ostream OS(Arg); 3085 OS << "-target-sdk-version=" << V; 3086 CC1ASArgs.push_back(Args.MakeArgString(Arg)); 3087 }; 3088 3089 if (isTargetMacCatalyst()) { 3090 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping( 3091 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) { 3092 std::optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map( 3093 SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(), 3094 std::nullopt); 3095 EmitTargetSDKVersionArg( 3096 SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget()); 3097 } 3098 } else { 3099 EmitTargetSDKVersionArg(SDKInfo->getVersion()); 3100 } 3101 3102 /// Pass the target variant SDK version to the compiler when the SDK 3103 /// information is available and is required for target variant. 3104 if (TargetVariantTriple) { 3105 if (isTargetMacCatalyst()) { 3106 std::string Arg; 3107 llvm::raw_string_ostream OS(Arg); 3108 OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion(); 3109 CC1ASArgs.push_back(Args.MakeArgString(Arg)); 3110 } else if (const auto *MacOStoMacCatalystMapping = 3111 SDKInfo->getVersionMapping( 3112 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) { 3113 if (std::optional<VersionTuple> SDKVersion = 3114 MacOStoMacCatalystMapping->map( 3115 SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(), 3116 std::nullopt)) { 3117 std::string Arg; 3118 llvm::raw_string_ostream OS(Arg); 3119 OS << "-darwin-target-variant-sdk-version=" << *SDKVersion; 3120 CC1ASArgs.push_back(Args.MakeArgString(Arg)); 3121 } 3122 } 3123 } 3124 } 3125 } 3126 3127 DerivedArgList * 3128 Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, 3129 Action::OffloadKind DeviceOffloadKind) const { 3130 // First get the generic Apple args, before moving onto Darwin-specific ones. 3131 DerivedArgList *DAL = 3132 MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); 3133 3134 // If no architecture is bound, none of the translations here are relevant. 3135 if (BoundArch.empty()) 3136 return DAL; 3137 3138 // Add an explicit version min argument for the deployment target. We do this 3139 // after argument translation because -Xarch_ arguments may add a version min 3140 // argument. 3141 AddDeploymentTarget(*DAL); 3142 3143 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 3144 // FIXME: It would be far better to avoid inserting those -static arguments, 3145 // but we can't check the deployment target in the translation code until 3146 // it is set here. 3147 if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS() || 3148 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) { 3149 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 3150 Arg *A = *it; 3151 ++it; 3152 if (A->getOption().getID() != options::OPT_mkernel && 3153 A->getOption().getID() != options::OPT_fapple_kext) 3154 continue; 3155 assert(it != ie && "unexpected argument translation"); 3156 A = *it; 3157 assert(A->getOption().getID() == options::OPT_static && 3158 "missing expected -static argument"); 3159 *it = nullptr; 3160 ++it; 3161 } 3162 } 3163 3164 auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch); 3165 if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) { 3166 if (Args.hasFlag(options::OPT_fomit_frame_pointer, 3167 options::OPT_fno_omit_frame_pointer, false)) 3168 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target) 3169 << "-fomit-frame-pointer" << BoundArch; 3170 } 3171 3172 return DAL; 3173 } 3174 3175 ToolChain::UnwindTableLevel MachO::getDefaultUnwindTableLevel(const ArgList &Args) const { 3176 // Unwind tables are not emitted if -fno-exceptions is supplied (except when 3177 // targeting x86_64). 3178 if (getArch() == llvm::Triple::x86_64 || 3179 (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj && 3180 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, 3181 true))) 3182 return (getArch() == llvm::Triple::aarch64 || 3183 getArch() == llvm::Triple::aarch64_32) 3184 ? UnwindTableLevel::Synchronous 3185 : UnwindTableLevel::Asynchronous; 3186 3187 return UnwindTableLevel::None; 3188 } 3189 3190 bool MachO::UseDwarfDebugFlags() const { 3191 if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 3192 return S[0] != '\0'; 3193 return false; 3194 } 3195 3196 std::string MachO::GetGlobalDebugPathRemapping() const { 3197 if (const char *S = ::getenv("RC_DEBUG_PREFIX_MAP")) 3198 return S; 3199 return {}; 3200 } 3201 3202 llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const { 3203 // Darwin uses SjLj exceptions on ARM. 3204 if (getTriple().getArch() != llvm::Triple::arm && 3205 getTriple().getArch() != llvm::Triple::thumb) 3206 return llvm::ExceptionHandling::None; 3207 3208 // Only watchOS uses the new DWARF/Compact unwinding method. 3209 llvm::Triple Triple(ComputeLLVMTriple(Args)); 3210 if (Triple.isWatchABI()) 3211 return llvm::ExceptionHandling::DwarfCFI; 3212 3213 return llvm::ExceptionHandling::SjLj; 3214 } 3215 3216 bool Darwin::SupportsEmbeddedBitcode() const { 3217 assert(TargetInitialized && "Target not initialized!"); 3218 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0)) 3219 return false; 3220 return true; 3221 } 3222 3223 bool MachO::isPICDefault() const { return true; } 3224 3225 bool MachO::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; } 3226 3227 bool MachO::isPICDefaultForced() const { 3228 return (getArch() == llvm::Triple::x86_64 || 3229 getArch() == llvm::Triple::aarch64); 3230 } 3231 3232 bool MachO::SupportsProfiling() const { 3233 // Profiling instrumentation is only supported on x86. 3234 return getTriple().isX86(); 3235 } 3236 3237 void Darwin::addMinVersionArgs(const ArgList &Args, 3238 ArgStringList &CmdArgs) const { 3239 VersionTuple TargetVersion = getTripleTargetVersion(); 3240 3241 assert(!isTargetXROS() && "xrOS always uses -platform-version"); 3242 3243 if (isTargetWatchOS()) 3244 CmdArgs.push_back("-watchos_version_min"); 3245 else if (isTargetWatchOSSimulator()) 3246 CmdArgs.push_back("-watchos_simulator_version_min"); 3247 else if (isTargetTvOS()) 3248 CmdArgs.push_back("-tvos_version_min"); 3249 else if (isTargetTvOSSimulator()) 3250 CmdArgs.push_back("-tvos_simulator_version_min"); 3251 else if (isTargetDriverKit()) 3252 CmdArgs.push_back("-driverkit_version_min"); 3253 else if (isTargetIOSSimulator()) 3254 CmdArgs.push_back("-ios_simulator_version_min"); 3255 else if (isTargetIOSBased()) 3256 CmdArgs.push_back("-iphoneos_version_min"); 3257 else if (isTargetMacCatalyst()) 3258 CmdArgs.push_back("-maccatalyst_version_min"); 3259 else { 3260 assert(isTargetMacOS() && "unexpected target"); 3261 CmdArgs.push_back("-macosx_version_min"); 3262 } 3263 3264 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion(); 3265 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) 3266 TargetVersion = MinTgtVers; 3267 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 3268 if (TargetVariantTriple) { 3269 assert(isTargetMacOSBased() && "unexpected target"); 3270 VersionTuple VariantTargetVersion; 3271 if (TargetVariantTriple->isMacOSX()) { 3272 CmdArgs.push_back("-macosx_version_min"); 3273 TargetVariantTriple->getMacOSXVersion(VariantTargetVersion); 3274 } else { 3275 assert(TargetVariantTriple->isiOS() && 3276 TargetVariantTriple->isMacCatalystEnvironment() && 3277 "unexpected target variant triple"); 3278 CmdArgs.push_back("-maccatalyst_version_min"); 3279 VariantTargetVersion = TargetVariantTriple->getiOSVersion(); 3280 } 3281 VersionTuple MinTgtVers = 3282 TargetVariantTriple->getMinimumSupportedOSVersion(); 3283 if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion) 3284 VariantTargetVersion = MinTgtVers; 3285 CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString())); 3286 } 3287 } 3288 3289 static const char *getPlatformName(Darwin::DarwinPlatformKind Platform, 3290 Darwin::DarwinEnvironmentKind Environment) { 3291 switch (Platform) { 3292 case Darwin::MacOS: 3293 return "macos"; 3294 case Darwin::IPhoneOS: 3295 if (Environment == Darwin::MacCatalyst) 3296 return "mac catalyst"; 3297 return "ios"; 3298 case Darwin::TvOS: 3299 return "tvos"; 3300 case Darwin::WatchOS: 3301 return "watchos"; 3302 case Darwin::XROS: 3303 return "xros"; 3304 case Darwin::DriverKit: 3305 return "driverkit"; 3306 } 3307 llvm_unreachable("invalid platform"); 3308 } 3309 3310 void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args, 3311 llvm::opt::ArgStringList &CmdArgs) const { 3312 auto EmitPlatformVersionArg = 3313 [&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform, 3314 Darwin::DarwinEnvironmentKind TargetEnvironment, 3315 const llvm::Triple &TT) { 3316 // -platform_version <platform> <target_version> <sdk_version> 3317 // Both the target and SDK version support only up to 3 components. 3318 CmdArgs.push_back("-platform_version"); 3319 std::string PlatformName = 3320 getPlatformName(TargetPlatform, TargetEnvironment); 3321 if (TargetEnvironment == Darwin::Simulator) 3322 PlatformName += "-simulator"; 3323 CmdArgs.push_back(Args.MakeArgString(PlatformName)); 3324 VersionTuple TargetVersion = TV.withoutBuild(); 3325 if ((TargetPlatform == Darwin::IPhoneOS || 3326 TargetPlatform == Darwin::TvOS) && 3327 getTriple().getArchName() == "arm64e" && 3328 TargetVersion.getMajor() < 14) { 3329 // arm64e slice is supported on iOS/tvOS 14+ only. 3330 TargetVersion = VersionTuple(14, 0); 3331 } 3332 VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion(); 3333 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) 3334 TargetVersion = MinTgtVers; 3335 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 3336 3337 if (TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst) { 3338 // Mac Catalyst programs must use the appropriate iOS SDK version 3339 // that corresponds to the macOS SDK version used for the compilation. 3340 std::optional<VersionTuple> iOSSDKVersion; 3341 if (SDKInfo) { 3342 if (const auto *MacOStoMacCatalystMapping = 3343 SDKInfo->getVersionMapping( 3344 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) { 3345 iOSSDKVersion = MacOStoMacCatalystMapping->map( 3346 SDKInfo->getVersion().withoutBuild(), 3347 minimumMacCatalystDeploymentTarget(), std::nullopt); 3348 } 3349 } 3350 CmdArgs.push_back(Args.MakeArgString( 3351 (iOSSDKVersion ? *iOSSDKVersion 3352 : minimumMacCatalystDeploymentTarget()) 3353 .getAsString())); 3354 return; 3355 } 3356 3357 if (SDKInfo) { 3358 VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild(); 3359 if (!SDKVersion.getMinor()) 3360 SDKVersion = VersionTuple(SDKVersion.getMajor(), 0); 3361 CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString())); 3362 } else { 3363 // Use an SDK version that's matching the deployment target if the SDK 3364 // version is missing. This is preferred over an empty SDK version 3365 // (0.0.0) as the system's runtime might expect the linked binary to 3366 // contain a valid SDK version in order for the binary to work 3367 // correctly. It's reasonable to use the deployment target version as 3368 // a proxy for the SDK version because older SDKs don't guarantee 3369 // support for deployment targets newer than the SDK versions, so that 3370 // rules out using some predetermined older SDK version, which leaves 3371 // the deployment target version as the only reasonable choice. 3372 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 3373 } 3374 }; 3375 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform, 3376 TargetEnvironment, getEffectiveTriple()); 3377 if (!TargetVariantTriple) 3378 return; 3379 Darwin::DarwinPlatformKind Platform; 3380 Darwin::DarwinEnvironmentKind Environment; 3381 VersionTuple TargetVariantVersion; 3382 if (TargetVariantTriple->isMacOSX()) { 3383 TargetVariantTriple->getMacOSXVersion(TargetVariantVersion); 3384 Platform = Darwin::MacOS; 3385 Environment = Darwin::NativeEnvironment; 3386 } else { 3387 assert(TargetVariantTriple->isiOS() && 3388 TargetVariantTriple->isMacCatalystEnvironment() && 3389 "unexpected target variant triple"); 3390 TargetVariantVersion = TargetVariantTriple->getiOSVersion(); 3391 Platform = Darwin::IPhoneOS; 3392 Environment = Darwin::MacCatalyst; 3393 } 3394 EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment, 3395 *TargetVariantTriple); 3396 } 3397 3398 // Add additional link args for the -dynamiclib option. 3399 static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, 3400 ArgStringList &CmdArgs) { 3401 // Derived from darwin_dylib1 spec. 3402 if (D.isTargetIPhoneOS()) { 3403 if (D.isIPhoneOSVersionLT(3, 1)) 3404 CmdArgs.push_back("-ldylib1.o"); 3405 return; 3406 } 3407 3408 if (!D.isTargetMacOS()) 3409 return; 3410 if (D.isMacosxVersionLT(10, 5)) 3411 CmdArgs.push_back("-ldylib1.o"); 3412 else if (D.isMacosxVersionLT(10, 6)) 3413 CmdArgs.push_back("-ldylib1.10.5.o"); 3414 } 3415 3416 // Add additional link args for the -bundle option. 3417 static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, 3418 ArgStringList &CmdArgs) { 3419 if (Args.hasArg(options::OPT_static)) 3420 return; 3421 // Derived from darwin_bundle1 spec. 3422 if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) || 3423 (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6))) 3424 CmdArgs.push_back("-lbundle1.o"); 3425 } 3426 3427 // Add additional link args for the -pg option. 3428 static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, 3429 ArgStringList &CmdArgs) { 3430 if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) { 3431 if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) || 3432 Args.hasArg(options::OPT_preload)) { 3433 CmdArgs.push_back("-lgcrt0.o"); 3434 } else { 3435 CmdArgs.push_back("-lgcrt1.o"); 3436 3437 // darwin_crt2 spec is empty. 3438 } 3439 // By default on OS X 10.8 and later, we don't link with a crt1.o 3440 // file and the linker knows to use _main as the entry point. But, 3441 // when compiling with -pg, we need to link with the gcrt1.o file, 3442 // so pass the -no_new_main option to tell the linker to use the 3443 // "start" symbol as the entry point. 3444 if (!D.isMacosxVersionLT(10, 8)) 3445 CmdArgs.push_back("-no_new_main"); 3446 } else { 3447 D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) 3448 << D.isTargetMacOSBased(); 3449 } 3450 } 3451 3452 static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args, 3453 ArgStringList &CmdArgs) { 3454 // Derived from darwin_crt1 spec. 3455 if (D.isTargetIPhoneOS()) { 3456 if (D.getArch() == llvm::Triple::aarch64) 3457 ; // iOS does not need any crt1 files for arm64 3458 else if (D.isIPhoneOSVersionLT(3, 1)) 3459 CmdArgs.push_back("-lcrt1.o"); 3460 else if (D.isIPhoneOSVersionLT(6, 0)) 3461 CmdArgs.push_back("-lcrt1.3.1.o"); 3462 return; 3463 } 3464 3465 if (!D.isTargetMacOS()) 3466 return; 3467 if (D.isMacosxVersionLT(10, 5)) 3468 CmdArgs.push_back("-lcrt1.o"); 3469 else if (D.isMacosxVersionLT(10, 6)) 3470 CmdArgs.push_back("-lcrt1.10.5.o"); 3471 else if (D.isMacosxVersionLT(10, 8)) 3472 CmdArgs.push_back("-lcrt1.10.6.o"); 3473 // darwin_crt2 spec is empty. 3474 } 3475 3476 void Darwin::addStartObjectFileArgs(const ArgList &Args, 3477 ArgStringList &CmdArgs) const { 3478 // Derived from startfile spec. 3479 if (Args.hasArg(options::OPT_dynamiclib)) 3480 addDynamicLibLinkArgs(*this, Args, CmdArgs); 3481 else if (Args.hasArg(options::OPT_bundle)) 3482 addBundleLinkArgs(*this, Args, CmdArgs); 3483 else if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) 3484 addPgProfilingLinkArgs(*this, Args, CmdArgs); 3485 else if (Args.hasArg(options::OPT_static) || 3486 Args.hasArg(options::OPT_object) || 3487 Args.hasArg(options::OPT_preload)) 3488 CmdArgs.push_back("-lcrt0.o"); 3489 else 3490 addDefaultCRTLinkArgs(*this, Args, CmdArgs); 3491 3492 if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) && 3493 isMacosxVersionLT(10, 5)) { 3494 const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); 3495 CmdArgs.push_back(Str); 3496 } 3497 } 3498 3499 void Darwin::CheckObjCARC() const { 3500 if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() || 3501 (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))) 3502 return; 3503 getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 3504 } 3505 3506 SanitizerMask Darwin::getSupportedSanitizers() const { 3507 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 3508 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64; 3509 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 3510 Res |= SanitizerKind::Address; 3511 Res |= SanitizerKind::PointerCompare; 3512 Res |= SanitizerKind::PointerSubtract; 3513 Res |= SanitizerKind::Leak; 3514 Res |= SanitizerKind::Fuzzer; 3515 Res |= SanitizerKind::FuzzerNoLink; 3516 Res |= SanitizerKind::ObjCCast; 3517 3518 // Prior to 10.9, macOS shipped a version of the C++ standard library without 3519 // C++11 support. The same is true of iOS prior to version 5. These OS'es are 3520 // incompatible with -fsanitize=vptr. 3521 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) && 3522 !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))) 3523 Res |= SanitizerKind::Vptr; 3524 3525 if ((IsX86_64 || IsAArch64) && 3526 (isTargetMacOSBased() || isTargetIOSSimulator() || 3527 isTargetTvOSSimulator() || isTargetWatchOSSimulator())) { 3528 Res |= SanitizerKind::Thread; 3529 } 3530 3531 if (IsX86_64) 3532 Res |= SanitizerKind::NumericalStability; 3533 3534 return Res; 3535 } 3536 3537 void Darwin::printVerboseInfo(raw_ostream &OS) const { 3538 CudaInstallation->print(OS); 3539 RocmInstallation->print(OS); 3540 } 3541