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