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