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 const 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 -m<os>-version-min argument. 1383 OSVersionArg, 1384 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment. 1385 DeploymentTargetEnv, 1386 /// The OS was inferred from the SDK. 1387 InferredFromSDK, 1388 /// The OS was inferred from the -arch. 1389 InferredFromArch 1390 }; 1391 1392 using DarwinPlatformKind = Darwin::DarwinPlatformKind; 1393 using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind; 1394 1395 DarwinPlatformKind getPlatform() const { return Platform; } 1396 1397 DarwinEnvironmentKind getEnvironment() const { return Environment; } 1398 1399 void setEnvironment(DarwinEnvironmentKind Kind) { 1400 Environment = Kind; 1401 InferSimulatorFromArch = false; 1402 } 1403 1404 StringRef getOSVersion() const { 1405 if (Kind == OSVersionArg) 1406 return Argument->getValue(); 1407 return OSVersion; 1408 } 1409 1410 void setOSVersion(StringRef S) { 1411 assert(Kind == TargetArg && "Unexpected kind!"); 1412 OSVersion = std::string(S); 1413 } 1414 1415 bool hasOSVersion() const { return HasOSVersion; } 1416 1417 VersionTuple getNativeTargetVersion() const { 1418 assert(Environment == DarwinEnvironmentKind::MacCatalyst && 1419 "native target version is specified only for Mac Catalyst"); 1420 return NativeTargetVersion; 1421 } 1422 1423 /// Returns true if the target OS was explicitly specified. 1424 bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; } 1425 1426 /// Returns true if the simulator environment can be inferred from the arch. 1427 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; } 1428 1429 /// Adds the -m<os>-version-min argument to the compiler invocation. 1430 void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) { 1431 if (Argument) 1432 return; 1433 assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind"); 1434 options::ID Opt; 1435 switch (Platform) { 1436 case DarwinPlatformKind::MacOS: 1437 Opt = options::OPT_mmacosx_version_min_EQ; 1438 break; 1439 case DarwinPlatformKind::IPhoneOS: 1440 Opt = options::OPT_miphoneos_version_min_EQ; 1441 break; 1442 case DarwinPlatformKind::TvOS: 1443 Opt = options::OPT_mtvos_version_min_EQ; 1444 break; 1445 case DarwinPlatformKind::WatchOS: 1446 Opt = options::OPT_mwatchos_version_min_EQ; 1447 break; 1448 } 1449 Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion); 1450 Args.append(Argument); 1451 } 1452 1453 /// Returns the OS version with the argument / environment variable that 1454 /// specified it. 1455 std::string getAsString(DerivedArgList &Args, const OptTable &Opts) { 1456 switch (Kind) { 1457 case TargetArg: 1458 case OSVersionArg: 1459 case InferredFromSDK: 1460 case InferredFromArch: 1461 assert(Argument && "OS version argument not yet inferred"); 1462 return Argument->getAsString(Args); 1463 case DeploymentTargetEnv: 1464 return (llvm::Twine(EnvVarName) + "=" + OSVersion).str(); 1465 } 1466 llvm_unreachable("Unsupported Darwin Source Kind"); 1467 } 1468 1469 static DarwinPlatform 1470 createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A, 1471 const Optional<DarwinSDKInfo> &SDKInfo) { 1472 DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion, 1473 A); 1474 unsigned Major, Minor, Micro; 1475 TT.getOSVersion(Major, Minor, Micro); 1476 if (Major == 0) 1477 Result.HasOSVersion = false; 1478 1479 switch (TT.getEnvironment()) { 1480 case llvm::Triple::Simulator: 1481 Result.Environment = DarwinEnvironmentKind::Simulator; 1482 break; 1483 case llvm::Triple::MacABI: { 1484 // The minimum native macOS target for MacCatalyst is macOS 10.15. 1485 auto NativeTargetVersion = VersionTuple(10, 15); 1486 if (Result.HasOSVersion && SDKInfo) { 1487 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping( 1488 DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) { 1489 if (auto MacOSVersion = MacCatalystToMacOSMapping->map( 1490 VersionTuple(Major, Minor, Micro), NativeTargetVersion, 1491 None)) { 1492 NativeTargetVersion = *MacOSVersion; 1493 } 1494 } 1495 } 1496 Result.Environment = DarwinEnvironmentKind::MacCatalyst; 1497 Result.NativeTargetVersion = NativeTargetVersion; 1498 break; 1499 } 1500 default: 1501 break; 1502 } 1503 return Result; 1504 } 1505 static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, 1506 Arg *A) { 1507 return DarwinPlatform(OSVersionArg, Platform, A); 1508 } 1509 static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform, 1510 StringRef EnvVarName, 1511 StringRef Value) { 1512 DarwinPlatform Result(DeploymentTargetEnv, Platform, Value); 1513 Result.EnvVarName = EnvVarName; 1514 return Result; 1515 } 1516 static DarwinPlatform createFromSDK(DarwinPlatformKind Platform, 1517 StringRef Value, 1518 bool IsSimulator = false) { 1519 DarwinPlatform Result(InferredFromSDK, Platform, Value); 1520 if (IsSimulator) 1521 Result.Environment = DarwinEnvironmentKind::Simulator; 1522 Result.InferSimulatorFromArch = false; 1523 return Result; 1524 } 1525 static DarwinPlatform createFromArch(llvm::Triple::OSType OS, 1526 StringRef Value) { 1527 return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value); 1528 } 1529 1530 /// Constructs an inferred SDKInfo value based on the version inferred from 1531 /// the SDK path itself. Only works for values that were created by inferring 1532 /// the platform from the SDKPath. 1533 DarwinSDKInfo inferSDKInfo() { 1534 assert(Kind == InferredFromSDK && "can infer SDK info only"); 1535 llvm::VersionTuple Version; 1536 bool IsValid = !Version.tryParse(OSVersion); 1537 (void)IsValid; 1538 assert(IsValid && "invalid SDK version"); 1539 return DarwinSDKInfo( 1540 Version, 1541 /*MaximumDeploymentTarget=*/VersionTuple(Version.getMajor(), 0, 99)); 1542 } 1543 1544 private: 1545 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) 1546 : Kind(Kind), Platform(Platform), Argument(Argument) {} 1547 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value, 1548 Arg *Argument = nullptr) 1549 : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {} 1550 1551 static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) { 1552 switch (OS) { 1553 case llvm::Triple::Darwin: 1554 case llvm::Triple::MacOSX: 1555 return DarwinPlatformKind::MacOS; 1556 case llvm::Triple::IOS: 1557 return DarwinPlatformKind::IPhoneOS; 1558 case llvm::Triple::TvOS: 1559 return DarwinPlatformKind::TvOS; 1560 case llvm::Triple::WatchOS: 1561 return DarwinPlatformKind::WatchOS; 1562 default: 1563 llvm_unreachable("Unable to infer Darwin variant"); 1564 } 1565 } 1566 1567 SourceKind Kind; 1568 DarwinPlatformKind Platform; 1569 DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment; 1570 VersionTuple NativeTargetVersion; 1571 std::string OSVersion; 1572 bool HasOSVersion = true, InferSimulatorFromArch = true; 1573 Arg *Argument; 1574 StringRef EnvVarName; 1575 }; 1576 1577 /// Returns the deployment target that's specified using the -m<os>-version-min 1578 /// argument. 1579 Optional<DarwinPlatform> 1580 getDeploymentTargetFromOSVersionArg(DerivedArgList &Args, 1581 const Driver &TheDriver) { 1582 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 1583 Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ, 1584 options::OPT_mios_simulator_version_min_EQ); 1585 Arg *TvOSVersion = 1586 Args.getLastArg(options::OPT_mtvos_version_min_EQ, 1587 options::OPT_mtvos_simulator_version_min_EQ); 1588 Arg *WatchOSVersion = 1589 Args.getLastArg(options::OPT_mwatchos_version_min_EQ, 1590 options::OPT_mwatchos_simulator_version_min_EQ); 1591 if (OSXVersion) { 1592 if (iOSVersion || TvOSVersion || WatchOSVersion) { 1593 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1594 << OSXVersion->getAsString(Args) 1595 << (iOSVersion ? iOSVersion 1596 : TvOSVersion ? TvOSVersion : WatchOSVersion) 1597 ->getAsString(Args); 1598 } 1599 return DarwinPlatform::createOSVersionArg(Darwin::MacOS, OSXVersion); 1600 } else if (iOSVersion) { 1601 if (TvOSVersion || WatchOSVersion) { 1602 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1603 << iOSVersion->getAsString(Args) 1604 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args); 1605 } 1606 return DarwinPlatform::createOSVersionArg(Darwin::IPhoneOS, iOSVersion); 1607 } else if (TvOSVersion) { 1608 if (WatchOSVersion) { 1609 TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1610 << TvOSVersion->getAsString(Args) 1611 << WatchOSVersion->getAsString(Args); 1612 } 1613 return DarwinPlatform::createOSVersionArg(Darwin::TvOS, TvOSVersion); 1614 } else if (WatchOSVersion) 1615 return DarwinPlatform::createOSVersionArg(Darwin::WatchOS, WatchOSVersion); 1616 return None; 1617 } 1618 1619 /// Returns the deployment target that's specified using the 1620 /// OS_DEPLOYMENT_TARGET environment variable. 1621 Optional<DarwinPlatform> 1622 getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver, 1623 const llvm::Triple &Triple) { 1624 std::string Targets[Darwin::LastDarwinPlatform + 1]; 1625 const char *EnvVars[] = { 1626 "MACOSX_DEPLOYMENT_TARGET", 1627 "IPHONEOS_DEPLOYMENT_TARGET", 1628 "TVOS_DEPLOYMENT_TARGET", 1629 "WATCHOS_DEPLOYMENT_TARGET", 1630 }; 1631 static_assert(llvm::array_lengthof(EnvVars) == Darwin::LastDarwinPlatform + 1, 1632 "Missing platform"); 1633 for (const auto &I : llvm::enumerate(llvm::makeArrayRef(EnvVars))) { 1634 if (char *Env = ::getenv(I.value())) 1635 Targets[I.index()] = Env; 1636 } 1637 1638 // Allow conflicts among OSX and iOS for historical reasons, but choose the 1639 // default platform. 1640 if (!Targets[Darwin::MacOS].empty() && 1641 (!Targets[Darwin::IPhoneOS].empty() || 1642 !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty())) { 1643 if (Triple.getArch() == llvm::Triple::arm || 1644 Triple.getArch() == llvm::Triple::aarch64 || 1645 Triple.getArch() == llvm::Triple::thumb) 1646 Targets[Darwin::MacOS] = ""; 1647 else 1648 Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] = 1649 Targets[Darwin::TvOS] = ""; 1650 } else { 1651 // Don't allow conflicts in any other platform. 1652 unsigned FirstTarget = llvm::array_lengthof(Targets); 1653 for (unsigned I = 0; I != llvm::array_lengthof(Targets); ++I) { 1654 if (Targets[I].empty()) 1655 continue; 1656 if (FirstTarget == llvm::array_lengthof(Targets)) 1657 FirstTarget = I; 1658 else 1659 TheDriver.Diag(diag::err_drv_conflicting_deployment_targets) 1660 << Targets[FirstTarget] << Targets[I]; 1661 } 1662 } 1663 1664 for (const auto &Target : llvm::enumerate(llvm::makeArrayRef(Targets))) { 1665 if (!Target.value().empty()) 1666 return DarwinPlatform::createDeploymentTargetEnv( 1667 (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()], 1668 Target.value()); 1669 } 1670 return None; 1671 } 1672 1673 /// Returns the SDK name without the optional prefix that ends with a '.' or an 1674 /// empty string otherwise. 1675 static StringRef dropSDKNamePrefix(StringRef SDKName) { 1676 size_t PrefixPos = SDKName.find('.'); 1677 if (PrefixPos == StringRef::npos) 1678 return ""; 1679 return SDKName.substr(PrefixPos + 1); 1680 } 1681 1682 /// Tries to infer the deployment target from the SDK specified by -isysroot 1683 /// (or SDKROOT). Uses the version specified in the SDKSettings.json file if 1684 /// it's available. 1685 Optional<DarwinPlatform> 1686 inferDeploymentTargetFromSDK(DerivedArgList &Args, 1687 const Optional<DarwinSDKInfo> &SDKInfo) { 1688 const Arg *A = Args.getLastArg(options::OPT_isysroot); 1689 if (!A) 1690 return None; 1691 StringRef isysroot = A->getValue(); 1692 StringRef SDK = Darwin::getSDKName(isysroot); 1693 if (!SDK.size()) 1694 return None; 1695 1696 std::string Version; 1697 if (SDKInfo) { 1698 // Get the version from the SDKSettings.json if it's available. 1699 Version = SDKInfo->getVersion().getAsString(); 1700 } else { 1701 // Slice the version number out. 1702 // Version number is between the first and the last number. 1703 size_t StartVer = SDK.find_first_of("0123456789"); 1704 size_t EndVer = SDK.find_last_of("0123456789"); 1705 if (StartVer != StringRef::npos && EndVer > StartVer) 1706 Version = std::string(SDK.slice(StartVer, EndVer + 1)); 1707 } 1708 if (Version.empty()) 1709 return None; 1710 1711 auto CreatePlatformFromSDKName = 1712 [&](StringRef SDK) -> Optional<DarwinPlatform> { 1713 if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) 1714 return DarwinPlatform::createFromSDK( 1715 Darwin::IPhoneOS, Version, 1716 /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); 1717 else if (SDK.startswith("MacOSX")) 1718 return DarwinPlatform::createFromSDK(Darwin::MacOS, 1719 getSystemOrSDKMacOSVersion(Version)); 1720 else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) 1721 return DarwinPlatform::createFromSDK( 1722 Darwin::WatchOS, Version, 1723 /*IsSimulator=*/SDK.startswith("WatchSimulator")); 1724 else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) 1725 return DarwinPlatform::createFromSDK( 1726 Darwin::TvOS, Version, 1727 /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); 1728 return None; 1729 }; 1730 if (auto Result = CreatePlatformFromSDKName(SDK)) 1731 return Result; 1732 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`. 1733 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK)); 1734 } 1735 1736 std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple, 1737 const Driver &TheDriver) { 1738 unsigned Major, Minor, Micro; 1739 llvm::Triple SystemTriple(llvm::sys::getProcessTriple()); 1740 switch (OS) { 1741 case llvm::Triple::Darwin: 1742 case llvm::Triple::MacOSX: 1743 // If there is no version specified on triple, and both host and target are 1744 // macos, use the host triple to infer OS version. 1745 if (Triple.isMacOSX() && SystemTriple.isMacOSX() && 1746 !Triple.getOSMajorVersion()) 1747 SystemTriple.getMacOSXVersion(Major, Minor, Micro); 1748 else if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 1749 TheDriver.Diag(diag::err_drv_invalid_darwin_version) 1750 << Triple.getOSName(); 1751 break; 1752 case llvm::Triple::IOS: 1753 Triple.getiOSVersion(Major, Minor, Micro); 1754 break; 1755 case llvm::Triple::TvOS: 1756 Triple.getOSVersion(Major, Minor, Micro); 1757 break; 1758 case llvm::Triple::WatchOS: 1759 Triple.getWatchOSVersion(Major, Minor, Micro); 1760 break; 1761 default: 1762 llvm_unreachable("Unexpected OS type"); 1763 break; 1764 } 1765 1766 std::string OSVersion; 1767 llvm::raw_string_ostream(OSVersion) << Major << '.' << Minor << '.' << Micro; 1768 return OSVersion; 1769 } 1770 1771 /// Tries to infer the target OS from the -arch. 1772 Optional<DarwinPlatform> 1773 inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, 1774 const llvm::Triple &Triple, 1775 const Driver &TheDriver) { 1776 llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; 1777 1778 StringRef MachOArchName = Toolchain.getMachOArchName(Args); 1779 if (MachOArchName == "arm64" || MachOArchName == "arm64e") { 1780 #if __arm64__ 1781 // A clang running on an Apple Silicon mac defaults 1782 // to building for mac when building for arm64 rather than 1783 // defaulting to iOS. 1784 OSTy = llvm::Triple::MacOSX; 1785 #else 1786 OSTy = llvm::Triple::IOS; 1787 #endif 1788 } else if (MachOArchName == "armv7" || MachOArchName == "armv7s") 1789 OSTy = llvm::Triple::IOS; 1790 else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32") 1791 OSTy = llvm::Triple::WatchOS; 1792 else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && 1793 MachOArchName != "armv7em") 1794 OSTy = llvm::Triple::MacOSX; 1795 1796 if (OSTy == llvm::Triple::UnknownOS) 1797 return None; 1798 return DarwinPlatform::createFromArch(OSTy, 1799 getOSVersion(OSTy, Triple, TheDriver)); 1800 } 1801 1802 /// Returns the deployment target that's specified using the -target option. 1803 Optional<DarwinPlatform> getDeploymentTargetFromTargetArg( 1804 DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver, 1805 const Optional<DarwinSDKInfo> &SDKInfo) { 1806 if (!Args.hasArg(options::OPT_target)) 1807 return None; 1808 if (Triple.getOS() == llvm::Triple::Darwin || 1809 Triple.getOS() == llvm::Triple::UnknownOS) 1810 return None; 1811 std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver); 1812 return DarwinPlatform::createFromTarget( 1813 Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo); 1814 } 1815 1816 Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS, 1817 const ArgList &Args, 1818 const Driver &TheDriver) { 1819 const Arg *A = Args.getLastArg(options::OPT_isysroot); 1820 if (!A) 1821 return None; 1822 StringRef isysroot = A->getValue(); 1823 auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot); 1824 if (!SDKInfoOrErr) { 1825 llvm::consumeError(SDKInfoOrErr.takeError()); 1826 TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings); 1827 return None; 1828 } 1829 return *SDKInfoOrErr; 1830 } 1831 1832 } // namespace 1833 1834 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 1835 const OptTable &Opts = getDriver().getOpts(); 1836 1837 // Support allowing the SDKROOT environment variable used by xcrun and other 1838 // Xcode tools to define the default sysroot, by making it the default for 1839 // isysroot. 1840 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1841 // Warn if the path does not exist. 1842 if (!getVFS().exists(A->getValue())) 1843 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 1844 } else { 1845 if (char *env = ::getenv("SDKROOT")) { 1846 // We only use this value as the default if it is an absolute path, 1847 // exists, and it is not the root path. 1848 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) && 1849 StringRef(env) != "/") { 1850 Args.append(Args.MakeSeparateArg( 1851 nullptr, Opts.getOption(options::OPT_isysroot), env)); 1852 } 1853 } 1854 } 1855 1856 // Read the SDKSettings.json file for more information, like the SDK version 1857 // that we can pass down to the compiler. 1858 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver()); 1859 1860 // The OS and the version can be specified using the -target argument. 1861 Optional<DarwinPlatform> OSTarget = 1862 getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo); 1863 if (OSTarget) { 1864 Optional<DarwinPlatform> OSVersionArgTarget = 1865 getDeploymentTargetFromOSVersionArg(Args, getDriver()); 1866 if (OSVersionArgTarget) { 1867 unsigned TargetMajor, TargetMinor, TargetMicro; 1868 bool TargetExtra; 1869 unsigned ArgMajor, ArgMinor, ArgMicro; 1870 bool ArgExtra; 1871 if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() || 1872 (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor, 1873 TargetMinor, TargetMicro, TargetExtra) && 1874 Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(), 1875 ArgMajor, ArgMinor, ArgMicro, ArgExtra) && 1876 (VersionTuple(TargetMajor, TargetMinor, TargetMicro) != 1877 VersionTuple(ArgMajor, ArgMinor, ArgMicro) || 1878 TargetExtra != ArgExtra))) { 1879 // Select the OS version from the -m<os>-version-min argument when 1880 // the -target does not include an OS version. 1881 if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() && 1882 !OSTarget->hasOSVersion()) { 1883 OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion()); 1884 } else { 1885 // Warn about -m<os>-version-min that doesn't match the OS version 1886 // that's specified in the target. 1887 std::string OSVersionArg = 1888 OSVersionArgTarget->getAsString(Args, Opts); 1889 std::string TargetArg = OSTarget->getAsString(Args, Opts); 1890 getDriver().Diag(clang::diag::warn_drv_overriding_flag_option) 1891 << OSVersionArg << TargetArg; 1892 } 1893 } 1894 } 1895 } else { 1896 // The OS target can be specified using the -m<os>version-min argument. 1897 OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver()); 1898 // If no deployment target was specified on the command line, check for 1899 // environment defines. 1900 if (!OSTarget) { 1901 OSTarget = 1902 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); 1903 if (OSTarget) { 1904 // Don't infer simulator from the arch when the SDK is also specified. 1905 Optional<DarwinPlatform> SDKTarget = 1906 inferDeploymentTargetFromSDK(Args, SDKInfo); 1907 if (SDKTarget) 1908 OSTarget->setEnvironment(SDKTarget->getEnvironment()); 1909 } 1910 } 1911 // If there is no command-line argument to specify the Target version and 1912 // no environment variable defined, see if we can set the default based 1913 // on -isysroot using SDKSettings.json if it exists. 1914 if (!OSTarget) { 1915 OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo); 1916 /// If the target was successfully constructed from the SDK path, try to 1917 /// infer the SDK info if the SDK doesn't have it. 1918 if (OSTarget && !SDKInfo) 1919 SDKInfo = OSTarget->inferSDKInfo(); 1920 } 1921 // If no OS targets have been specified, try to guess platform from -target 1922 // or arch name and compute the version from the triple. 1923 if (!OSTarget) 1924 OSTarget = 1925 inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); 1926 } 1927 1928 assert(OSTarget && "Unable to infer Darwin variant"); 1929 OSTarget->addOSVersionMinArgument(Args, Opts); 1930 DarwinPlatformKind Platform = OSTarget->getPlatform(); 1931 1932 unsigned Major, Minor, Micro; 1933 bool HadExtra; 1934 // Set the tool chain target information. 1935 if (Platform == MacOS) { 1936 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1937 Micro, HadExtra) || 1938 HadExtra || Major < 10 || Major >= 100 || Minor >= 100 || Micro >= 100) 1939 getDriver().Diag(diag::err_drv_invalid_version_number) 1940 << OSTarget->getAsString(Args, Opts); 1941 } else if (Platform == IPhoneOS) { 1942 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1943 Micro, HadExtra) || 1944 HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) 1945 getDriver().Diag(diag::err_drv_invalid_version_number) 1946 << OSTarget->getAsString(Args, Opts); 1947 ; 1948 if (OSTarget->getEnvironment() == MacCatalyst && 1949 (Major < 13 || (Major == 13 && Minor < 1))) { 1950 getDriver().Diag(diag::err_drv_invalid_version_number) 1951 << OSTarget->getAsString(Args, Opts); 1952 Major = 13; 1953 Minor = 1; 1954 Micro = 0; 1955 } 1956 // For 32-bit targets, the deployment target for iOS has to be earlier than 1957 // iOS 11. 1958 if (getTriple().isArch32Bit() && Major >= 11) { 1959 // If the deployment target is explicitly specified, print a diagnostic. 1960 if (OSTarget->isExplicitlySpecified()) { 1961 if (OSTarget->getEnvironment() == MacCatalyst) 1962 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target); 1963 else 1964 getDriver().Diag(diag::warn_invalid_ios_deployment_target) 1965 << OSTarget->getAsString(Args, Opts); 1966 // Otherwise, set it to 10.99.99. 1967 } else { 1968 Major = 10; 1969 Minor = 99; 1970 Micro = 99; 1971 } 1972 } 1973 } else if (Platform == TvOS) { 1974 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1975 Micro, HadExtra) || 1976 HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) 1977 getDriver().Diag(diag::err_drv_invalid_version_number) 1978 << OSTarget->getAsString(Args, Opts); 1979 } else if (Platform == WatchOS) { 1980 if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1981 Micro, HadExtra) || 1982 HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100) 1983 getDriver().Diag(diag::err_drv_invalid_version_number) 1984 << OSTarget->getAsString(Args, Opts); 1985 } else 1986 llvm_unreachable("unknown kind of Darwin platform"); 1987 1988 DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); 1989 // Recognize iOS targets with an x86 architecture as the iOS simulator. 1990 if (Environment == NativeEnvironment && Platform != MacOS && 1991 OSTarget->canInferSimulatorFromArch() && getTriple().isX86()) 1992 Environment = Simulator; 1993 1994 VersionTuple NativeTargetVersion; 1995 if (Environment == MacCatalyst) 1996 NativeTargetVersion = OSTarget->getNativeTargetVersion(); 1997 setTarget(Platform, Environment, Major, Minor, Micro, NativeTargetVersion); 1998 1999 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2000 StringRef SDK = getSDKName(A->getValue()); 2001 if (SDK.size() > 0) { 2002 size_t StartVer = SDK.find_first_of("0123456789"); 2003 StringRef SDKName = SDK.slice(0, StartVer); 2004 if (!SDKName.startswith(getPlatformFamily()) && 2005 !dropSDKNamePrefix(SDKName).startswith(getPlatformFamily())) 2006 getDriver().Diag(diag::warn_incompatible_sysroot) 2007 << SDKName << getPlatformFamily(); 2008 } 2009 } 2010 } 2011 2012 // Returns the effective header sysroot path to use. This comes either from 2013 // -isysroot or --sysroot. 2014 llvm::StringRef DarwinClang::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { 2015 if(DriverArgs.hasArg(options::OPT_isysroot)) 2016 return DriverArgs.getLastArgValue(options::OPT_isysroot); 2017 if (!getDriver().SysRoot.empty()) 2018 return getDriver().SysRoot; 2019 return "/"; 2020 } 2021 2022 void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 2023 llvm::opt::ArgStringList &CC1Args) const { 2024 const Driver &D = getDriver(); 2025 2026 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); 2027 2028 bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc); 2029 bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc); 2030 bool NoBuiltinInc = DriverArgs.hasFlag( 2031 options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false); 2032 bool ForceBuiltinInc = DriverArgs.hasFlag( 2033 options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false); 2034 2035 // Add <sysroot>/usr/local/include 2036 if (!NoStdInc && !NoStdlibInc) { 2037 SmallString<128> P(Sysroot); 2038 llvm::sys::path::append(P, "usr", "local", "include"); 2039 addSystemInclude(DriverArgs, CC1Args, P); 2040 } 2041 2042 // Add the Clang builtin headers (<resource>/include) 2043 if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) { 2044 SmallString<128> P(D.ResourceDir); 2045 llvm::sys::path::append(P, "include"); 2046 addSystemInclude(DriverArgs, CC1Args, P); 2047 } 2048 2049 if (NoStdInc || NoStdlibInc) 2050 return; 2051 2052 // Check for configure-time C include directories. 2053 llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); 2054 if (!CIncludeDirs.empty()) { 2055 llvm::SmallVector<llvm::StringRef, 5> dirs; 2056 CIncludeDirs.split(dirs, ":"); 2057 for (llvm::StringRef dir : dirs) { 2058 llvm::StringRef Prefix = 2059 llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot); 2060 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 2061 } 2062 } else { 2063 // Otherwise, add <sysroot>/usr/include. 2064 SmallString<128> P(Sysroot); 2065 llvm::sys::path::append(P, "usr", "include"); 2066 addExternCSystemInclude(DriverArgs, CC1Args, P.str()); 2067 } 2068 } 2069 2070 bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 2071 llvm::opt::ArgStringList &CC1Args, 2072 llvm::SmallString<128> Base, 2073 llvm::StringRef Version, 2074 llvm::StringRef ArchDir, 2075 llvm::StringRef BitDir) const { 2076 llvm::sys::path::append(Base, Version); 2077 2078 // Add the base dir 2079 addSystemInclude(DriverArgs, CC1Args, Base); 2080 2081 // Add the multilib dirs 2082 { 2083 llvm::SmallString<128> P = Base; 2084 if (!ArchDir.empty()) 2085 llvm::sys::path::append(P, ArchDir); 2086 if (!BitDir.empty()) 2087 llvm::sys::path::append(P, BitDir); 2088 addSystemInclude(DriverArgs, CC1Args, P); 2089 } 2090 2091 // Add the backward dir 2092 { 2093 llvm::SmallString<128> P = Base; 2094 llvm::sys::path::append(P, "backward"); 2095 addSystemInclude(DriverArgs, CC1Args, P); 2096 } 2097 2098 return getVFS().exists(Base); 2099 } 2100 2101 void DarwinClang::AddClangCXXStdlibIncludeArgs( 2102 const llvm::opt::ArgList &DriverArgs, 2103 llvm::opt::ArgStringList &CC1Args) const { 2104 // The implementation from a base class will pass through the -stdlib to 2105 // CC1Args. 2106 // FIXME: this should not be necessary, remove usages in the frontend 2107 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib. 2108 // Also check whether this is used for setting library search paths. 2109 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args); 2110 2111 if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 2112 DriverArgs.hasArg(options::OPT_nostdincxx)) 2113 return; 2114 2115 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); 2116 2117 switch (GetCXXStdlibType(DriverArgs)) { 2118 case ToolChain::CST_Libcxx: { 2119 // On Darwin, libc++ can be installed in one of the following two places: 2120 // 1. Alongside the compiler in <install>/include/c++/v1 2121 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1 2122 // 2123 // The precendence of paths is as listed above, i.e. we take the first path 2124 // that exists. Also note that we never include libc++ twice -- we take the 2125 // first path that exists and don't send the other paths to CC1 (otherwise 2126 // include_next could break). 2127 2128 // Check for (1) 2129 // Get from '<install>/bin' to '<install>/include/c++/v1'. 2130 // Note that InstallBin can be relative, so we use '..' instead of 2131 // parent_path. 2132 llvm::SmallString<128> InstallBin = 2133 llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin 2134 llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1"); 2135 if (getVFS().exists(InstallBin)) { 2136 addSystemInclude(DriverArgs, CC1Args, InstallBin); 2137 return; 2138 } else if (DriverArgs.hasArg(options::OPT_v)) { 2139 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin 2140 << "\"\n"; 2141 } 2142 2143 // Otherwise, check for (2) 2144 llvm::SmallString<128> SysrootUsr = Sysroot; 2145 llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); 2146 if (getVFS().exists(SysrootUsr)) { 2147 addSystemInclude(DriverArgs, CC1Args, SysrootUsr); 2148 return; 2149 } else if (DriverArgs.hasArg(options::OPT_v)) { 2150 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr 2151 << "\"\n"; 2152 } 2153 2154 // Otherwise, don't add any path. 2155 break; 2156 } 2157 2158 case ToolChain::CST_Libstdcxx: 2159 llvm::SmallString<128> UsrIncludeCxx = Sysroot; 2160 llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); 2161 2162 llvm::Triple::ArchType arch = getTriple().getArch(); 2163 bool IsBaseFound = true; 2164 switch (arch) { 2165 default: break; 2166 2167 case llvm::Triple::ppc: 2168 case llvm::Triple::ppc64: 2169 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2170 "4.2.1", 2171 "powerpc-apple-darwin10", 2172 arch == llvm::Triple::ppc64 ? "ppc64" : ""); 2173 IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2174 "4.0.0", "powerpc-apple-darwin10", 2175 arch == llvm::Triple::ppc64 ? "ppc64" : ""); 2176 break; 2177 2178 case llvm::Triple::x86: 2179 case llvm::Triple::x86_64: 2180 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2181 "4.2.1", 2182 "i686-apple-darwin10", 2183 arch == llvm::Triple::x86_64 ? "x86_64" : ""); 2184 IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2185 "4.0.0", "i686-apple-darwin8", 2186 ""); 2187 break; 2188 2189 case llvm::Triple::arm: 2190 case llvm::Triple::thumb: 2191 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2192 "4.2.1", 2193 "arm-apple-darwin10", 2194 "v7"); 2195 IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2196 "4.2.1", 2197 "arm-apple-darwin10", 2198 "v6"); 2199 break; 2200 2201 case llvm::Triple::aarch64: 2202 IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2203 "4.2.1", 2204 "arm64-apple-darwin10", 2205 ""); 2206 break; 2207 } 2208 2209 if (!IsBaseFound) { 2210 getDriver().Diag(diag::warn_drv_libstdcxx_not_found); 2211 } 2212 2213 break; 2214 } 2215 } 2216 void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 2217 ArgStringList &CmdArgs) const { 2218 CXXStdlibType Type = GetCXXStdlibType(Args); 2219 2220 switch (Type) { 2221 case ToolChain::CST_Libcxx: 2222 CmdArgs.push_back("-lc++"); 2223 break; 2224 2225 case ToolChain::CST_Libstdcxx: 2226 // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 2227 // it was previously found in the gcc lib dir. However, for all the Darwin 2228 // platforms we care about it was -lstdc++.6, so we search for that 2229 // explicitly if we can't see an obvious -lstdc++ candidate. 2230 2231 // Check in the sysroot first. 2232 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2233 SmallString<128> P(A->getValue()); 2234 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 2235 2236 if (!getVFS().exists(P)) { 2237 llvm::sys::path::remove_filename(P); 2238 llvm::sys::path::append(P, "libstdc++.6.dylib"); 2239 if (getVFS().exists(P)) { 2240 CmdArgs.push_back(Args.MakeArgString(P)); 2241 return; 2242 } 2243 } 2244 } 2245 2246 // Otherwise, look in the root. 2247 // FIXME: This should be removed someday when we don't have to care about 2248 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 2249 if (!getVFS().exists("/usr/lib/libstdc++.dylib") && 2250 getVFS().exists("/usr/lib/libstdc++.6.dylib")) { 2251 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 2252 return; 2253 } 2254 2255 // Otherwise, let the linker search. 2256 CmdArgs.push_back("-lstdc++"); 2257 break; 2258 } 2259 } 2260 2261 void DarwinClang::AddCCKextLibArgs(const ArgList &Args, 2262 ArgStringList &CmdArgs) const { 2263 // For Darwin platforms, use the compiler-rt-based support library 2264 // instead of the gcc-provided one (which is also incidentally 2265 // only present in the gcc lib dir, which makes it hard to find). 2266 2267 SmallString<128> P(getDriver().ResourceDir); 2268 llvm::sys::path::append(P, "lib", "darwin"); 2269 2270 // Use the newer cc_kext for iOS ARM after 6.0. 2271 if (isTargetWatchOS()) { 2272 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a"); 2273 } else if (isTargetTvOS()) { 2274 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); 2275 } else if (isTargetIPhoneOS()) { 2276 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); 2277 } else { 2278 llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 2279 } 2280 2281 // For now, allow missing resource libraries to support developers who may 2282 // not have compiler-rt checked out or integrated into their build. 2283 if (getVFS().exists(P)) 2284 CmdArgs.push_back(Args.MakeArgString(P)); 2285 } 2286 2287 DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, 2288 StringRef BoundArch, 2289 Action::OffloadKind) const { 2290 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 2291 const OptTable &Opts = getDriver().getOpts(); 2292 2293 // FIXME: We really want to get out of the tool chain level argument 2294 // translation business, as it makes the driver functionality much 2295 // more opaque. For now, we follow gcc closely solely for the 2296 // purpose of easily achieving feature parity & testability. Once we 2297 // have something that works, we should reevaluate each translation 2298 // and try to push it down into tool specific logic. 2299 2300 for (Arg *A : Args) { 2301 if (A->getOption().matches(options::OPT_Xarch__)) { 2302 // Skip this argument unless the architecture matches either the toolchain 2303 // triple arch, or the arch being bound. 2304 llvm::Triple::ArchType XarchArch = 2305 tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); 2306 if (!(XarchArch == getArch() || 2307 (!BoundArch.empty() && 2308 XarchArch == 2309 tools::darwin::getArchTypeForMachOArchName(BoundArch)))) 2310 continue; 2311 2312 Arg *OriginalArg = A; 2313 TranslateXarchArgs(Args, A, DAL); 2314 2315 // Linker input arguments require custom handling. The problem is that we 2316 // have already constructed the phase actions, so we can not treat them as 2317 // "input arguments". 2318 if (A->getOption().hasFlag(options::LinkerInput)) { 2319 // Convert the argument into individual Zlinker_input_args. 2320 for (const char *Value : A->getValues()) { 2321 DAL->AddSeparateArg( 2322 OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); 2323 } 2324 continue; 2325 } 2326 } 2327 2328 // Sob. These is strictly gcc compatible for the time being. Apple 2329 // gcc translates options twice, which means that self-expanding 2330 // options add duplicates. 2331 switch ((options::ID)A->getOption().getID()) { 2332 default: 2333 DAL->append(A); 2334 break; 2335 2336 case options::OPT_mkernel: 2337 case options::OPT_fapple_kext: 2338 DAL->append(A); 2339 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 2340 break; 2341 2342 case options::OPT_dependency_file: 2343 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); 2344 break; 2345 2346 case options::OPT_gfull: 2347 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2348 DAL->AddFlagArg( 2349 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 2350 break; 2351 2352 case options::OPT_gused: 2353 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2354 DAL->AddFlagArg( 2355 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 2356 break; 2357 2358 case options::OPT_shared: 2359 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 2360 break; 2361 2362 case options::OPT_fconstant_cfstrings: 2363 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 2364 break; 2365 2366 case options::OPT_fno_constant_cfstrings: 2367 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 2368 break; 2369 2370 case options::OPT_Wnonportable_cfstrings: 2371 DAL->AddFlagArg(A, 2372 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 2373 break; 2374 2375 case options::OPT_Wno_nonportable_cfstrings: 2376 DAL->AddFlagArg( 2377 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 2378 break; 2379 2380 case options::OPT_fpascal_strings: 2381 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 2382 break; 2383 2384 case options::OPT_fno_pascal_strings: 2385 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 2386 break; 2387 } 2388 } 2389 2390 // Add the arch options based on the particular spelling of -arch, to match 2391 // how the driver driver works. 2392 if (!BoundArch.empty()) { 2393 StringRef Name = BoundArch; 2394 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 2395 const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ); 2396 2397 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 2398 // which defines the list of which architectures we accept. 2399 if (Name == "ppc") 2400 ; 2401 else if (Name == "ppc601") 2402 DAL->AddJoinedArg(nullptr, MCpu, "601"); 2403 else if (Name == "ppc603") 2404 DAL->AddJoinedArg(nullptr, MCpu, "603"); 2405 else if (Name == "ppc604") 2406 DAL->AddJoinedArg(nullptr, MCpu, "604"); 2407 else if (Name == "ppc604e") 2408 DAL->AddJoinedArg(nullptr, MCpu, "604e"); 2409 else if (Name == "ppc750") 2410 DAL->AddJoinedArg(nullptr, MCpu, "750"); 2411 else if (Name == "ppc7400") 2412 DAL->AddJoinedArg(nullptr, MCpu, "7400"); 2413 else if (Name == "ppc7450") 2414 DAL->AddJoinedArg(nullptr, MCpu, "7450"); 2415 else if (Name == "ppc970") 2416 DAL->AddJoinedArg(nullptr, MCpu, "970"); 2417 2418 else if (Name == "ppc64" || Name == "ppc64le") 2419 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2420 2421 else if (Name == "i386") 2422 ; 2423 else if (Name == "i486") 2424 DAL->AddJoinedArg(nullptr, MArch, "i486"); 2425 else if (Name == "i586") 2426 DAL->AddJoinedArg(nullptr, MArch, "i586"); 2427 else if (Name == "i686") 2428 DAL->AddJoinedArg(nullptr, MArch, "i686"); 2429 else if (Name == "pentium") 2430 DAL->AddJoinedArg(nullptr, MArch, "pentium"); 2431 else if (Name == "pentium2") 2432 DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2433 else if (Name == "pentpro") 2434 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro"); 2435 else if (Name == "pentIIm3") 2436 DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2437 2438 else if (Name == "x86_64" || Name == "x86_64h") 2439 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2440 2441 else if (Name == "arm") 2442 DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2443 else if (Name == "armv4t") 2444 DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2445 else if (Name == "armv5") 2446 DAL->AddJoinedArg(nullptr, MArch, "armv5tej"); 2447 else if (Name == "xscale") 2448 DAL->AddJoinedArg(nullptr, MArch, "xscale"); 2449 else if (Name == "armv6") 2450 DAL->AddJoinedArg(nullptr, MArch, "armv6k"); 2451 else if (Name == "armv6m") 2452 DAL->AddJoinedArg(nullptr, MArch, "armv6m"); 2453 else if (Name == "armv7") 2454 DAL->AddJoinedArg(nullptr, MArch, "armv7a"); 2455 else if (Name == "armv7em") 2456 DAL->AddJoinedArg(nullptr, MArch, "armv7em"); 2457 else if (Name == "armv7k") 2458 DAL->AddJoinedArg(nullptr, MArch, "armv7k"); 2459 else if (Name == "armv7m") 2460 DAL->AddJoinedArg(nullptr, MArch, "armv7m"); 2461 else if (Name == "armv7s") 2462 DAL->AddJoinedArg(nullptr, MArch, "armv7s"); 2463 } 2464 2465 return DAL; 2466 } 2467 2468 void MachO::AddLinkRuntimeLibArgs(const ArgList &Args, 2469 ArgStringList &CmdArgs, 2470 bool ForceLinkBuiltinRT) const { 2471 // Embedded targets are simple at the moment, not supporting sanitizers and 2472 // with different libraries for each member of the product { static, PIC } x 2473 // { hard-float, soft-float } 2474 llvm::SmallString<32> CompilerRT = StringRef(""); 2475 CompilerRT += 2476 (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard) 2477 ? "hard" 2478 : "soft"; 2479 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static"; 2480 2481 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded); 2482 } 2483 2484 bool Darwin::isAlignedAllocationUnavailable() const { 2485 llvm::Triple::OSType OS; 2486 2487 if (isTargetMacCatalyst()) 2488 return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX); 2489 switch (TargetPlatform) { 2490 case MacOS: // Earlier than 10.13. 2491 OS = llvm::Triple::MacOSX; 2492 break; 2493 case IPhoneOS: 2494 OS = llvm::Triple::IOS; 2495 break; 2496 case TvOS: // Earlier than 11.0. 2497 OS = llvm::Triple::TvOS; 2498 break; 2499 case WatchOS: // Earlier than 4.0. 2500 OS = llvm::Triple::WatchOS; 2501 break; 2502 } 2503 2504 return TargetVersion < alignedAllocMinVersion(OS); 2505 } 2506 2507 void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2508 llvm::opt::ArgStringList &CC1Args, 2509 Action::OffloadKind DeviceOffloadKind) const { 2510 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually 2511 // enabled or disabled aligned allocations. 2512 if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, 2513 options::OPT_fno_aligned_allocation) && 2514 isAlignedAllocationUnavailable()) 2515 CC1Args.push_back("-faligned-alloc-unavailable"); 2516 2517 if (SDKInfo) { 2518 /// Pass the SDK version to the compiler when the SDK information is 2519 /// available. 2520 auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) { 2521 std::string Arg; 2522 llvm::raw_string_ostream OS(Arg); 2523 OS << "-target-sdk-version=" << V; 2524 CC1Args.push_back(DriverArgs.MakeArgString(OS.str())); 2525 }; 2526 2527 if (isTargetMacCatalyst()) { 2528 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping( 2529 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) { 2530 Optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map( 2531 SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(), None); 2532 EmitTargetSDKVersionArg( 2533 SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget()); 2534 } 2535 } else { 2536 EmitTargetSDKVersionArg(SDKInfo->getVersion()); 2537 } 2538 } 2539 2540 // Enable compatibility mode for NSItemProviderCompletionHandler in 2541 // Foundation/NSItemProvider.h. 2542 CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking"); 2543 2544 // Give static local variables in inline functions hidden visibility when 2545 // -fvisibility-inlines-hidden is enabled. 2546 if (!DriverArgs.getLastArgNoClaim( 2547 options::OPT_fvisibility_inlines_hidden_static_local_var, 2548 options::OPT_fno_visibility_inlines_hidden_static_local_var)) 2549 CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var"); 2550 } 2551 2552 DerivedArgList * 2553 Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, 2554 Action::OffloadKind DeviceOffloadKind) const { 2555 // First get the generic Apple args, before moving onto Darwin-specific ones. 2556 DerivedArgList *DAL = 2557 MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); 2558 const OptTable &Opts = getDriver().getOpts(); 2559 2560 // If no architecture is bound, none of the translations here are relevant. 2561 if (BoundArch.empty()) 2562 return DAL; 2563 2564 // Add an explicit version min argument for the deployment target. We do this 2565 // after argument translation because -Xarch_ arguments may add a version min 2566 // argument. 2567 AddDeploymentTarget(*DAL); 2568 2569 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 2570 // FIXME: It would be far better to avoid inserting those -static arguments, 2571 // but we can't check the deployment target in the translation code until 2572 // it is set here. 2573 if (isTargetWatchOSBased() || 2574 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) { 2575 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 2576 Arg *A = *it; 2577 ++it; 2578 if (A->getOption().getID() != options::OPT_mkernel && 2579 A->getOption().getID() != options::OPT_fapple_kext) 2580 continue; 2581 assert(it != ie && "unexpected argument translation"); 2582 A = *it; 2583 assert(A->getOption().getID() == options::OPT_static && 2584 "missing expected -static argument"); 2585 *it = nullptr; 2586 ++it; 2587 } 2588 } 2589 2590 if (!Args.getLastArg(options::OPT_stdlib_EQ) && 2591 GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) 2592 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), 2593 "libc++"); 2594 2595 // Validate the C++ standard library choice. 2596 CXXStdlibType Type = GetCXXStdlibType(*DAL); 2597 if (Type == ToolChain::CST_Libcxx) { 2598 // Check whether the target provides libc++. 2599 StringRef where; 2600 2601 // Complain about targeting iOS < 5.0 in any way. 2602 if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0)) 2603 where = "iOS 5.0"; 2604 2605 if (where != StringRef()) { 2606 getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where; 2607 } 2608 } 2609 2610 auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch); 2611 if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) { 2612 if (Args.hasFlag(options::OPT_fomit_frame_pointer, 2613 options::OPT_fno_omit_frame_pointer, false)) 2614 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target) 2615 << "-fomit-frame-pointer" << BoundArch; 2616 } 2617 2618 return DAL; 2619 } 2620 2621 bool MachO::IsUnwindTablesDefault(const ArgList &Args) const { 2622 // Unwind tables are not emitted if -fno-exceptions is supplied (except when 2623 // targeting x86_64). 2624 return getArch() == llvm::Triple::x86_64 || 2625 (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj && 2626 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, 2627 true)); 2628 } 2629 2630 bool MachO::UseDwarfDebugFlags() const { 2631 if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 2632 return S[0] != '\0'; 2633 return false; 2634 } 2635 2636 llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const { 2637 // Darwin uses SjLj exceptions on ARM. 2638 if (getTriple().getArch() != llvm::Triple::arm && 2639 getTriple().getArch() != llvm::Triple::thumb) 2640 return llvm::ExceptionHandling::None; 2641 2642 // Only watchOS uses the new DWARF/Compact unwinding method. 2643 llvm::Triple Triple(ComputeLLVMTriple(Args)); 2644 if (Triple.isWatchABI()) 2645 return llvm::ExceptionHandling::DwarfCFI; 2646 2647 return llvm::ExceptionHandling::SjLj; 2648 } 2649 2650 bool Darwin::SupportsEmbeddedBitcode() const { 2651 assert(TargetInitialized && "Target not initialized!"); 2652 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0)) 2653 return false; 2654 return true; 2655 } 2656 2657 bool MachO::isPICDefault() const { return true; } 2658 2659 bool MachO::isPIEDefault() const { return false; } 2660 2661 bool MachO::isPICDefaultForced() const { 2662 return (getArch() == llvm::Triple::x86_64 || 2663 getArch() == llvm::Triple::aarch64); 2664 } 2665 2666 bool MachO::SupportsProfiling() const { 2667 // Profiling instrumentation is only supported on x86. 2668 return getTriple().isX86(); 2669 } 2670 2671 void Darwin::addMinVersionArgs(const ArgList &Args, 2672 ArgStringList &CmdArgs) const { 2673 VersionTuple TargetVersion = getTripleTargetVersion(); 2674 2675 if (isTargetWatchOS()) 2676 CmdArgs.push_back("-watchos_version_min"); 2677 else if (isTargetWatchOSSimulator()) 2678 CmdArgs.push_back("-watchos_simulator_version_min"); 2679 else if (isTargetTvOS()) 2680 CmdArgs.push_back("-tvos_version_min"); 2681 else if (isTargetTvOSSimulator()) 2682 CmdArgs.push_back("-tvos_simulator_version_min"); 2683 else if (isTargetIOSSimulator()) 2684 CmdArgs.push_back("-ios_simulator_version_min"); 2685 else if (isTargetIOSBased()) 2686 CmdArgs.push_back("-iphoneos_version_min"); 2687 else if (isTargetMacCatalyst()) 2688 CmdArgs.push_back("-maccatalyst_version_min"); 2689 else { 2690 assert(isTargetMacOS() && "unexpected target"); 2691 CmdArgs.push_back("-macosx_version_min"); 2692 } 2693 2694 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion(); 2695 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) 2696 TargetVersion = MinTgtVers; 2697 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 2698 } 2699 2700 static const char *getPlatformName(Darwin::DarwinPlatformKind Platform, 2701 Darwin::DarwinEnvironmentKind Environment) { 2702 switch (Platform) { 2703 case Darwin::MacOS: 2704 return "macos"; 2705 case Darwin::IPhoneOS: 2706 if (Environment == Darwin::MacCatalyst) 2707 return "mac catalyst"; 2708 return "ios"; 2709 case Darwin::TvOS: 2710 return "tvos"; 2711 case Darwin::WatchOS: 2712 return "watchos"; 2713 } 2714 llvm_unreachable("invalid platform"); 2715 } 2716 2717 void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args, 2718 llvm::opt::ArgStringList &CmdArgs) const { 2719 // -platform_version <platform> <target_version> <sdk_version> 2720 // Both the target and SDK version support only up to 3 components. 2721 CmdArgs.push_back("-platform_version"); 2722 std::string PlatformName = getPlatformName(TargetPlatform, TargetEnvironment); 2723 if (TargetEnvironment == Darwin::Simulator) 2724 PlatformName += "-simulator"; 2725 CmdArgs.push_back(Args.MakeArgString(PlatformName)); 2726 VersionTuple TargetVersion = getTripleTargetVersion().withoutBuild(); 2727 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion(); 2728 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) 2729 TargetVersion = MinTgtVers; 2730 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 2731 2732 if (isTargetMacCatalyst()) { 2733 // Mac Catalyst programs must use the appropriate iOS SDK version 2734 // that corresponds to the macOS SDK version used for the compilation. 2735 Optional<VersionTuple> iOSSDKVersion; 2736 if (SDKInfo) { 2737 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping( 2738 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) { 2739 iOSSDKVersion = MacOStoMacCatalystMapping->map( 2740 SDKInfo->getVersion().withoutBuild(), 2741 minimumMacCatalystDeploymentTarget(), None); 2742 } 2743 } 2744 CmdArgs.push_back(Args.MakeArgString( 2745 (iOSSDKVersion ? *iOSSDKVersion : minimumMacCatalystDeploymentTarget()) 2746 .getAsString())); 2747 return; 2748 } 2749 2750 if (SDKInfo) { 2751 VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild(); 2752 CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString())); 2753 } else { 2754 // Use an SDK version that's matching the deployment target if the SDK 2755 // version is missing. This is preferred over an empty SDK version (0.0.0) 2756 // as the system's runtime might expect the linked binary to contain a 2757 // valid SDK version in order for the binary to work correctly. It's 2758 // reasonable to use the deployment target version as a proxy for the 2759 // SDK version because older SDKs don't guarantee support for deployment 2760 // targets newer than the SDK versions, so that rules out using some 2761 // predetermined older SDK version, which leaves the deployment target 2762 // version as the only reasonable choice. 2763 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 2764 } 2765 } 2766 2767 // Add additional link args for the -dynamiclib option. 2768 static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, 2769 ArgStringList &CmdArgs) { 2770 // Derived from darwin_dylib1 spec. 2771 if (D.isTargetIPhoneOS()) { 2772 if (D.isIPhoneOSVersionLT(3, 1)) 2773 CmdArgs.push_back("-ldylib1.o"); 2774 return; 2775 } 2776 2777 if (!D.isTargetMacOS()) 2778 return; 2779 if (D.isMacosxVersionLT(10, 5)) 2780 CmdArgs.push_back("-ldylib1.o"); 2781 else if (D.isMacosxVersionLT(10, 6)) 2782 CmdArgs.push_back("-ldylib1.10.5.o"); 2783 } 2784 2785 // Add additional link args for the -bundle option. 2786 static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, 2787 ArgStringList &CmdArgs) { 2788 if (Args.hasArg(options::OPT_static)) 2789 return; 2790 // Derived from darwin_bundle1 spec. 2791 if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) || 2792 (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6))) 2793 CmdArgs.push_back("-lbundle1.o"); 2794 } 2795 2796 // Add additional link args for the -pg option. 2797 static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, 2798 ArgStringList &CmdArgs) { 2799 if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) { 2800 if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) || 2801 Args.hasArg(options::OPT_preload)) { 2802 CmdArgs.push_back("-lgcrt0.o"); 2803 } else { 2804 CmdArgs.push_back("-lgcrt1.o"); 2805 2806 // darwin_crt2 spec is empty. 2807 } 2808 // By default on OS X 10.8 and later, we don't link with a crt1.o 2809 // file and the linker knows to use _main as the entry point. But, 2810 // when compiling with -pg, we need to link with the gcrt1.o file, 2811 // so pass the -no_new_main option to tell the linker to use the 2812 // "start" symbol as the entry point. 2813 if (!D.isMacosxVersionLT(10, 8)) 2814 CmdArgs.push_back("-no_new_main"); 2815 } else { 2816 D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) 2817 << D.isTargetMacOSBased(); 2818 } 2819 } 2820 2821 static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args, 2822 ArgStringList &CmdArgs) { 2823 // Derived from darwin_crt1 spec. 2824 if (D.isTargetIPhoneOS()) { 2825 if (D.getArch() == llvm::Triple::aarch64) 2826 ; // iOS does not need any crt1 files for arm64 2827 else if (D.isIPhoneOSVersionLT(3, 1)) 2828 CmdArgs.push_back("-lcrt1.o"); 2829 else if (D.isIPhoneOSVersionLT(6, 0)) 2830 CmdArgs.push_back("-lcrt1.3.1.o"); 2831 return; 2832 } 2833 2834 if (!D.isTargetMacOS()) 2835 return; 2836 if (D.isMacosxVersionLT(10, 5)) 2837 CmdArgs.push_back("-lcrt1.o"); 2838 else if (D.isMacosxVersionLT(10, 6)) 2839 CmdArgs.push_back("-lcrt1.10.5.o"); 2840 else if (D.isMacosxVersionLT(10, 8)) 2841 CmdArgs.push_back("-lcrt1.10.6.o"); 2842 // darwin_crt2 spec is empty. 2843 } 2844 2845 void Darwin::addStartObjectFileArgs(const ArgList &Args, 2846 ArgStringList &CmdArgs) const { 2847 // Derived from startfile spec. 2848 if (Args.hasArg(options::OPT_dynamiclib)) 2849 addDynamicLibLinkArgs(*this, Args, CmdArgs); 2850 else if (Args.hasArg(options::OPT_bundle)) 2851 addBundleLinkArgs(*this, Args, CmdArgs); 2852 else if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) 2853 addPgProfilingLinkArgs(*this, Args, CmdArgs); 2854 else if (Args.hasArg(options::OPT_static) || 2855 Args.hasArg(options::OPT_object) || 2856 Args.hasArg(options::OPT_preload)) 2857 CmdArgs.push_back("-lcrt0.o"); 2858 else 2859 addDefaultCRTLinkArgs(*this, Args, CmdArgs); 2860 2861 if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) && 2862 isMacosxVersionLT(10, 5)) { 2863 const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); 2864 CmdArgs.push_back(Str); 2865 } 2866 } 2867 2868 void Darwin::CheckObjCARC() const { 2869 if (isTargetIOSBased() || isTargetWatchOSBased() || 2870 (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))) 2871 return; 2872 getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 2873 } 2874 2875 SanitizerMask Darwin::getSupportedSanitizers() const { 2876 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 2877 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64; 2878 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 2879 Res |= SanitizerKind::Address; 2880 Res |= SanitizerKind::PointerCompare; 2881 Res |= SanitizerKind::PointerSubtract; 2882 Res |= SanitizerKind::Leak; 2883 Res |= SanitizerKind::Fuzzer; 2884 Res |= SanitizerKind::FuzzerNoLink; 2885 Res |= SanitizerKind::Function; 2886 Res |= SanitizerKind::ObjCCast; 2887 2888 // Prior to 10.9, macOS shipped a version of the C++ standard library without 2889 // C++11 support. The same is true of iOS prior to version 5. These OS'es are 2890 // incompatible with -fsanitize=vptr. 2891 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) && 2892 !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))) 2893 Res |= SanitizerKind::Vptr; 2894 2895 if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) { 2896 Res |= SanitizerKind::Thread; 2897 } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) { 2898 if (IsX86_64) 2899 Res |= SanitizerKind::Thread; 2900 } 2901 return Res; 2902 } 2903 2904 void Darwin::printVerboseInfo(raw_ostream &OS) const { 2905 CudaInstallation.print(OS); 2906 RocmInstallation.print(OS); 2907 } 2908