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