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