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