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