brintos

brintos / llvm-project-archived public Read only

0
0
Text · 145.7 KiB · fc3cd90 Raw
3793 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Darwin.h"10#include "Arch/ARM.h"11#include "clang/Basic/AlignedAllocation.h"12#include "clang/Basic/ObjCRuntime.h"13#include "clang/Config/config.h"14#include "clang/Driver/CommonArgs.h"15#include "clang/Driver/Compilation.h"16#include "clang/Driver/Driver.h"17#include "clang/Driver/SanitizerArgs.h"18#include "clang/Options/Options.h"19#include "llvm/ADT/StringSwitch.h"20#include "llvm/Option/ArgList.h"21#include "llvm/ProfileData/InstrProf.h"22#include "llvm/ProfileData/MemProf.h"23#include "llvm/Support/Path.h"24#include "llvm/Support/Threading.h"25#include "llvm/Support/VirtualFileSystem.h"26#include "llvm/TargetParser/TargetParser.h"27#include "llvm/TargetParser/Triple.h"28#include <cstdlib> // ::getenv29 30using namespace clang::driver;31using namespace clang::driver::tools;32using namespace clang::driver::toolchains;33using namespace clang;34using namespace llvm::opt;35 36static VersionTuple minimumMacCatalystDeploymentTarget() {37  return VersionTuple(13, 1);38}39 40llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {41  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for42  // archs which Darwin doesn't use.43 44  // The matching this routine does is fairly pointless, since it is neither the45  // complete architecture list, nor a reasonable subset. The problem is that46  // historically the driver accepts this and also ties its -march=47  // handling to the architecture name, so we need to be careful before removing48  // support for it.49 50  // This code must be kept in sync with Clang's Darwin specific argument51  // translation.52 53  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)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.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 ArgList &Args) {75  const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);76  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str);77  T.setArch(Arch);78  if (Arch != llvm::Triple::UnknownArch)79    T.setArchName(Str);80 81  if (ArchKind == llvm::ARM::ArchKind::ARMV6M ||82      ArchKind == llvm::ARM::ArchKind::ARMV7M ||83      ArchKind == llvm::ARM::ArchKind::ARMV7EM) {84    // Don't reject these -version-min= if we have the appropriate triple.85    if (T.getOS() == llvm::Triple::IOS)86      for (Arg *A : Args.filtered(options::OPT_mios_version_min_EQ))87        A->ignoreTargetSpecific();88    if (T.getOS() == llvm::Triple::WatchOS)89      for (Arg *A : Args.filtered(options::OPT_mwatchos_version_min_EQ))90        A->ignoreTargetSpecific();91    if (T.getOS() == llvm::Triple::TvOS)92      for (Arg *A : Args.filtered(options::OPT_mtvos_version_min_EQ))93        A->ignoreTargetSpecific();94 95    T.setOS(llvm::Triple::UnknownOS);96    T.setObjectFormat(llvm::Triple::MachO);97  }98}99 100void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA,101                                     const InputInfo &Output,102                                     const InputInfoList &Inputs,103                                     const ArgList &Args,104                                     const char *LinkingOutput) const {105  const llvm::Triple &T(getToolChain().getTriple());106 107  ArgStringList CmdArgs;108 109  assert(Inputs.size() == 1 && "Unexpected number of inputs.");110  const InputInfo &Input = Inputs[0];111 112  // Determine the original source input.113  const Action *SourceAction = &JA;114  while (SourceAction->getKind() != Action::InputClass) {115    assert(!SourceAction->getInputs().empty() && "unexpected root action!");116    SourceAction = SourceAction->getInputs()[0];117  }118 119  // If -fno-integrated-as is used add -Q to the darwin assembler driver to make120  // sure it runs its system assembler not clang's integrated assembler.121  // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.122  // FIXME: at run-time detect assembler capabilities or rely on version123  // information forwarded by -target-assembler-version.124  if (Args.hasArg(options::OPT_fno_integrated_as)) {125    if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))126      CmdArgs.push_back("-Q");127  }128 129  // Forward -g, assuming we are dealing with an actual assembly file.130  if (SourceAction->getType() == types::TY_Asm ||131      SourceAction->getType() == types::TY_PP_Asm) {132    if (Args.hasArg(options::OPT_gstabs))133      CmdArgs.push_back("--gstabs");134    else if (Args.hasArg(options::OPT_g_Group))135      CmdArgs.push_back("-g");136  }137 138  // Derived from asm spec.139  AddMachOArch(Args, CmdArgs);140 141  // Use -force_cpusubtype_ALL on x86 by default.142  if (T.isX86() || Args.hasArg(options::OPT_force__cpusubtype__ALL))143    CmdArgs.push_back("-force_cpusubtype_ALL");144 145  if (getToolChain().getArch() != llvm::Triple::x86_64 &&146      (((Args.hasArg(options::OPT_mkernel) ||147         Args.hasArg(options::OPT_fapple_kext)) &&148        getMachOToolChain().isKernelStatic()) ||149       Args.hasArg(options::OPT_static)))150    CmdArgs.push_back("-static");151 152  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);153 154  assert(Output.isFilename() && "Unexpected lipo output.");155  CmdArgs.push_back("-o");156  CmdArgs.push_back(Output.getFilename());157 158  assert(Input.isFilename() && "Invalid input.");159  CmdArgs.push_back(Input.getFilename());160 161  // asm_final spec is empty.162 163  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));164  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),165                                         Exec, CmdArgs, Inputs, Output));166}167 168void darwin::MachOTool::anchor() {}169 170void darwin::MachOTool::AddMachOArch(const ArgList &Args,171                                     ArgStringList &CmdArgs) const {172  StringRef ArchName = getMachOToolChain().getMachOArchName(Args);173 174  // Derived from darwin_arch spec.175  CmdArgs.push_back("-arch");176  CmdArgs.push_back(Args.MakeArgString(ArchName));177 178  // FIXME: Is this needed anymore?179  if (ArchName == "arm")180    CmdArgs.push_back("-force_cpusubtype_ALL");181}182 183bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {184  // We only need to generate a temp path for LTO if we aren't compiling object185  // files. When compiling source files, we run 'dsymutil' after linking. We186  // don't run 'dsymutil' when compiling object files.187  for (const auto &Input : Inputs)188    if (Input.getType() != types::TY_Object)189      return true;190 191  return false;192}193 194/// Pass -no_deduplicate to ld64 under certain conditions:195///196/// - Either -O0 or -O1 is explicitly specified197/// - No -O option is specified *and* this is a compile+link (implicit -O0)198///199/// Also do *not* add -no_deduplicate when no -O option is specified and this200/// is just a link (we can't imply -O0)201static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {202  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {203    if (A->getOption().matches(options::OPT_O0))204      return true;205    if (A->getOption().matches(options::OPT_O))206      return llvm::StringSwitch<bool>(A->getValue())207                    .Case("1", true)208                    .Default(false);209    return false; // OPT_Ofast & OPT_O4210  }211 212  if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.213    return true;214  return false;215}216 217void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,218                                 ArgStringList &CmdArgs,219                                 const InputInfoList &Inputs,220                                 VersionTuple Version, bool LinkerIsLLD,221                                 bool UsePlatformVersion) const {222  const Driver &D = getToolChain().getDriver();223  const toolchains::MachO &MachOTC = getMachOToolChain();224 225  // Newer linkers support -demangle. Pass it if supported and not disabled by226  // the user.227  if ((Version >= VersionTuple(100) || LinkerIsLLD) &&228      !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))229    CmdArgs.push_back("-demangle");230 231  if (Args.hasArg(options::OPT_rdynamic) &&232      (Version >= VersionTuple(137) || LinkerIsLLD))233    CmdArgs.push_back("-export_dynamic");234 235  // If we are using App Extension restrictions, pass a flag to the linker236  // telling it that the compiled code has been audited.237  if (Args.hasFlag(options::OPT_fapplication_extension,238                   options::OPT_fno_application_extension, false))239    CmdArgs.push_back("-application_extension");240 241  if (D.isUsingLTO() && (Version >= VersionTuple(116) || LinkerIsLLD) &&242      NeedsTempPath(Inputs)) {243    std::string TmpPathName;244    if (D.getLTOMode() == LTOK_Full) {245      // If we are using full LTO, then automatically create a temporary file246      // path for the linker to use, so that it's lifetime will extend past a247      // possible dsymutil step.248      TmpPathName =249          D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object));250    } else if (D.getLTOMode() == LTOK_Thin)251      // If we are using thin LTO, then create a directory instead.252      TmpPathName = D.GetTemporaryDirectory("thinlto");253 254    if (!TmpPathName.empty()) {255      auto *TmpPath = C.getArgs().MakeArgString(TmpPathName);256      C.addTempFile(TmpPath);257      CmdArgs.push_back("-object_path_lto");258      CmdArgs.push_back(TmpPath);259    }260  }261 262  // Use -lto_library option to specify the libLTO.dylib path. Try to find263  // it in clang installed libraries. ld64 will only look at this argument264  // when it actually uses LTO, so libLTO.dylib only needs to exist at link265  // time if ld64 decides that it needs to use LTO.266  // Since this is passed unconditionally, ld64 will never look for libLTO.dylib267  // next to it. That's ok since ld64 using a libLTO.dylib not matching the268  // clang version won't work anyways.269  // lld is built at the same revision as clang and statically links in270  // LLVM libraries, so it doesn't need libLTO.dylib.271  if (Version >= VersionTuple(133) && !LinkerIsLLD) {272    // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib273    StringRef P = llvm::sys::path::parent_path(D.Dir);274    SmallString<128> LibLTOPath(P);275    llvm::sys::path::append(LibLTOPath, "lib");276    llvm::sys::path::append(LibLTOPath, "libLTO.dylib");277    CmdArgs.push_back("-lto_library");278    CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));279  }280 281  // ld64 version 262 and above runs the deduplicate pass by default.282  // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe`283  //        if `!shouldLinkerNotDedup()` if LinkerIsLLD here?284  if (Version >= VersionTuple(262) &&285      shouldLinkerNotDedup(C.getJobs().empty(), Args))286    CmdArgs.push_back("-no_deduplicate");287 288  // Derived from the "link" spec.289  Args.AddAllArgs(CmdArgs, options::OPT_static);290  if (!Args.hasArg(options::OPT_static))291    CmdArgs.push_back("-dynamic");292  if (Args.hasArg(options::OPT_fgnu_runtime)) {293    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu294    // here. How do we wish to handle such things?295  }296 297  if (!Args.hasArg(options::OPT_dynamiclib)) {298    AddMachOArch(Args, CmdArgs);299    // FIXME: Why do this only on this path?300    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);301 302    Args.AddLastArg(CmdArgs, options::OPT_bundle);303    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);304    Args.AddAllArgs(CmdArgs, options::OPT_client__name);305 306    Arg *A;307    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||308        (A = Args.getLastArg(options::OPT_current__version)) ||309        (A = Args.getLastArg(options::OPT_install__name)))310      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)311                                                       << "-dynamiclib";312 313    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);314    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);315    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);316  } else {317    CmdArgs.push_back("-dylib");318 319    Arg *A;320    if ((A = Args.getLastArg(options::OPT_bundle)) ||321        (A = Args.getLastArg(options::OPT_bundle__loader)) ||322        (A = Args.getLastArg(options::OPT_client__name)) ||323        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||324        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||325        (A = Args.getLastArg(options::OPT_private__bundle)))326      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)327                                                      << "-dynamiclib";328 329    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,330                              "-dylib_compatibility_version");331    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,332                              "-dylib_current_version");333 334    AddMachOArch(Args, CmdArgs);335 336    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,337                              "-dylib_install_name");338  }339 340  Args.AddLastArg(CmdArgs, options::OPT_all__load);341  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);342  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);343  if (MachOTC.isTargetIOSBased())344    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);345  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);346  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);347  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);348  Args.AddLastArg(CmdArgs, options::OPT_dynamic);349  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);350  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);351  Args.AddAllArgs(CmdArgs, options::OPT_force__load);352  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);353  Args.AddAllArgs(CmdArgs, options::OPT_image__base);354  Args.AddAllArgs(CmdArgs, options::OPT_init);355 356  // Add the deployment target.357  if (Version >= VersionTuple(520) || LinkerIsLLD || UsePlatformVersion)358    MachOTC.addPlatformVersionArgs(Args, CmdArgs);359  else360    MachOTC.addMinVersionArgs(Args, CmdArgs);361 362  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);363  Args.AddLastArg(CmdArgs, options::OPT_multi__module);364  Args.AddLastArg(CmdArgs, options::OPT_single__module);365  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);366  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);367 368  if (const Arg *A =369          Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,370                          options::OPT_fno_pie, options::OPT_fno_PIE)) {371    if (A->getOption().matches(options::OPT_fpie) ||372        A->getOption().matches(options::OPT_fPIE))373      CmdArgs.push_back("-pie");374    else375      CmdArgs.push_back("-no_pie");376  }377 378  // for embed-bitcode, use -bitcode_bundle in linker command379  if (C.getDriver().embedBitcodeEnabled()) {380    // Check if the toolchain supports bitcode build flow.381    if (MachOTC.SupportsEmbeddedBitcode()) {382      CmdArgs.push_back("-bitcode_bundle");383      // FIXME: Pass this if LinkerIsLLD too, once it implements this flag.384      if (C.getDriver().embedBitcodeMarkerOnly() &&385          Version >= VersionTuple(278)) {386        CmdArgs.push_back("-bitcode_process_mode");387        CmdArgs.push_back("marker");388      }389    } else390      D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);391  }392 393  // If GlobalISel is enabled, pass it through to LLVM.394  if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,395                               options::OPT_fno_global_isel)) {396    if (A->getOption().matches(options::OPT_fglobal_isel)) {397      CmdArgs.push_back("-mllvm");398      CmdArgs.push_back("-global-isel");399      // Disable abort and fall back to SDAG silently.400      CmdArgs.push_back("-mllvm");401      CmdArgs.push_back("-global-isel-abort=0");402    }403  }404 405  if (Args.hasArg(options::OPT_mkernel) ||406      Args.hasArg(options::OPT_fapple_kext) ||407      Args.hasArg(options::OPT_ffreestanding)) {408    CmdArgs.push_back("-mllvm");409    CmdArgs.push_back("-disable-atexit-based-global-dtor-lowering");410  }411 412  Args.AddLastArg(CmdArgs, options::OPT_prebind);413  Args.AddLastArg(CmdArgs, options::OPT_noprebind);414  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);415  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);416  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);417  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);418  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);419  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);420  Args.AddAllArgs(CmdArgs, options::OPT_segprot);421  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);422  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);423  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);424  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);425  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);426  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);427  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);428 429  // Give --sysroot= preference, over the Apple specific behavior to also use430  // --isysroot as the syslibroot.431  // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we432  // prioritise command line arguments over configuration of `DEFAULT_SYSROOT`.433  if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) {434    CmdArgs.push_back("-syslibroot");435    CmdArgs.push_back(A->getValue());436  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {437    CmdArgs.push_back("-syslibroot");438    CmdArgs.push_back(A->getValue());439  } else if (StringRef sysroot = C.getSysRoot(); sysroot != "") {440    CmdArgs.push_back("-syslibroot");441    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));442  }443 444  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);445  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);446  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);447  Args.AddAllArgs(CmdArgs, options::OPT_undefined);448  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);449  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);450  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);451  Args.AddAllArgs(CmdArgs, options::OPT_y);452  Args.AddLastArg(CmdArgs, options::OPT_w);453  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);454  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);455  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);456  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);457  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);458  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);459  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);460  Args.AddLastArg(CmdArgs, options::OPT_why_load);461  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);462  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);463  Args.AddLastArg(CmdArgs, options::OPT_dylinker);464  Args.AddLastArg(CmdArgs, options::OPT_Mach);465 466  if (LinkerIsLLD) {467    if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {468      SmallString<128> Path(CSPGOGenerateArg->getNumValues() == 0469                                ? ""470                                : CSPGOGenerateArg->getValue());471      llvm::sys::path::append(Path, "default_%m.profraw");472      CmdArgs.push_back("--cs-profile-generate");473      CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));474    } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {475      SmallString<128> Path(476          ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());477      if (Path.empty() || llvm::sys::fs::is_directory(Path))478        llvm::sys::path::append(Path, "default.profdata");479      CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));480    }481 482    auto *CodeGenDataGenArg =483        Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);484    if (CodeGenDataGenArg)485      CmdArgs.push_back(486          Args.MakeArgString(Twine("--codegen-data-generate-path=") +487                             CodeGenDataGenArg->getValue()));488  }489}490 491/// Determine whether we are linking the ObjC runtime.492static bool isObjCRuntimeLinked(const ArgList &Args) {493  if (isObjCAutoRefCount(Args)) {494    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);495    return true;496  }497  return Args.hasArg(options::OPT_fobjc_link_runtime);498}499 500static bool checkRemarksOptions(const Driver &D, const ArgList &Args,501                                const llvm::Triple &Triple) {502  // When enabling remarks, we need to error if:503  // * The remark file is specified but we're targeting multiple architectures,504  // which means more than one remark file is being generated.505  bool hasMultipleInvocations =506      Args.getAllArgValues(options::OPT_arch).size() > 1;507  bool hasExplicitOutputFile =508      Args.getLastArg(options::OPT_foptimization_record_file_EQ);509  if (hasMultipleInvocations && hasExplicitOutputFile) {510    D.Diag(diag::err_drv_invalid_output_with_multiple_archs)511        << "-foptimization-record-file";512    return false;513  }514  return true;515}516 517static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,518                                 const llvm::Triple &Triple,519                                 const InputInfo &Output, const JobAction &JA) {520  StringRef Format = "yaml";521  if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))522    Format = A->getValue();523 524  CmdArgs.push_back("-mllvm");525  CmdArgs.push_back("-lto-pass-remarks-output");526  CmdArgs.push_back("-mllvm");527 528  const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);529  if (A) {530    CmdArgs.push_back(A->getValue());531  } else {532    assert(Output.isFilename() && "Unexpected ld output.");533    SmallString<128> F;534    F = Output.getFilename();535    F += ".opt.";536    F += Format;537 538    CmdArgs.push_back(Args.MakeArgString(F));539  }540 541  if (const Arg *A =542          Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {543    CmdArgs.push_back("-mllvm");544    std::string Passes =545        std::string("-lto-pass-remarks-filter=") + A->getValue();546    CmdArgs.push_back(Args.MakeArgString(Passes));547  }548 549  if (!Format.empty()) {550    CmdArgs.push_back("-mllvm");551    Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format;552    CmdArgs.push_back(Args.MakeArgString(FormatArg));553  }554 555  if (getLastProfileUseArg(Args)) {556    CmdArgs.push_back("-mllvm");557    CmdArgs.push_back("-lto-pass-remarks-with-hotness");558 559    if (const Arg *A =560            Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {561      CmdArgs.push_back("-mllvm");562      std::string Opt =563          std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue();564      CmdArgs.push_back(Args.MakeArgString(Opt));565    }566  }567}568 569static void AppendPlatformPrefix(SmallString<128> &Path, const llvm::Triple &T);570 571void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,572                                  const InputInfo &Output,573                                  const InputInfoList &Inputs,574                                  const ArgList &Args,575                                  const char *LinkingOutput) const {576  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");577 578  // If the number of arguments surpasses the system limits, we will encode the579  // input files in a separate file, shortening the command line. To this end,580  // build a list of input file names that can be passed via a file with the581  // -filelist linker option.582  llvm::opt::ArgStringList InputFileList;583 584  // The logic here is derived from gcc's behavior; most of which585  // comes from specs (starting with link_command). Consult gcc for586  // more information.587  ArgStringList CmdArgs;588 589  VersionTuple Version = getMachOToolChain().getLinkerVersion(Args);590 591  bool LinkerIsLLD;592  const char *Exec =593      Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD));594 595  // xrOS always uses -platform-version.596  bool UsePlatformVersion = getToolChain().getTriple().isXROS();597 598  // I'm not sure why this particular decomposition exists in gcc, but599  // we follow suite for ease of comparison.600  AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD,601              UsePlatformVersion);602 603  if (willEmitRemarks(Args) &&604      checkRemarksOptions(getToolChain().getDriver(), Args,605                          getToolChain().getTriple()))606    renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA);607 608  // Propagate the -moutline flag to the linker in LTO.609  if (Arg *A =610          Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) {611    if (A->getOption().matches(options::OPT_moutline)) {612      if (getMachOToolChain().getMachOArchName(Args) == "arm64") {613        CmdArgs.push_back("-mllvm");614        CmdArgs.push_back("-enable-machine-outliner");615      }616    } else {617      // Disable all outlining behaviour if we have mno-outline. We need to do618      // this explicitly, because targets which support default outlining will619      // try to do work if we don't.620      CmdArgs.push_back("-mllvm");621      CmdArgs.push_back("-enable-machine-outliner=never");622    }623  }624 625  // Outline from linkonceodr functions by default in LTO, whenever the outliner626  // is enabled.  Note that the target may enable the machine outliner627  // independently of -moutline.628  CmdArgs.push_back("-mllvm");629  CmdArgs.push_back("-enable-linkonceodr-outlining");630 631  // Propagate codegen data flags to the linker for the LLVM backend.632  auto *CodeGenDataGenArg =633      Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);634  auto *CodeGenDataUseArg = Args.getLastArg(options::OPT_fcodegen_data_use_EQ);635 636  // We only allow one of them to be specified.637  const Driver &D = getToolChain().getDriver();638  if (CodeGenDataGenArg && CodeGenDataUseArg)639    D.Diag(diag::err_drv_argument_not_allowed_with)640        << CodeGenDataGenArg->getAsString(Args)641        << CodeGenDataUseArg->getAsString(Args);642 643  // For codegen data gen, the output file is passed to the linker644  // while a boolean flag is passed to the LLVM backend.645  if (CodeGenDataGenArg) {646    CmdArgs.push_back("-mllvm");647    CmdArgs.push_back("-codegen-data-generate");648  }649 650  // For codegen data use, the input file is passed to the LLVM backend.651  if (CodeGenDataUseArg) {652    CmdArgs.push_back("-mllvm");653    CmdArgs.push_back(Args.MakeArgString(Twine("-codegen-data-use-path=") +654                                         CodeGenDataUseArg->getValue()));655  }656 657  // Setup statistics file output.658  SmallString<128> StatsFile =659      getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());660  if (!StatsFile.empty()) {661    CmdArgs.push_back("-mllvm");662    CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str()));663  }664 665  // It seems that the 'e' option is completely ignored for dynamic executables666  // (the default), and with static executables, the last one wins, as expected.667  Args.addAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,668                            options::OPT_Z_Flag, options::OPT_u_Group});669 670  // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading671  // members of static archive libraries which implement Objective-C classes or672  // categories.673  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))674    CmdArgs.push_back("-ObjC");675 676  CmdArgs.push_back("-o");677  CmdArgs.push_back(Output.getFilename());678 679  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))680    getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);681 682  Args.AddAllArgs(CmdArgs, options::OPT_L);683 684  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);685  // Build the input file for -filelist (list of linker input files) in case we686  // need it later687  for (const auto &II : Inputs) {688    if (!II.isFilename()) {689      // This is a linker input argument.690      // We cannot mix input arguments and file names in a -filelist input, thus691      // we prematurely stop our list (remaining files shall be passed as692      // arguments).693      if (InputFileList.size() > 0)694        break;695 696      continue;697    }698 699    InputFileList.push_back(II.getFilename());700  }701 702  // Additional linker set-up and flags for Fortran. This is required in order703  // to generate executables.704  if (getToolChain().getDriver().IsFlangMode() &&705      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {706    getToolChain().addFortranRuntimeLibraryPath(Args, CmdArgs);707    getToolChain().addFortranRuntimeLibs(Args, CmdArgs);708  }709 710  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))711    addOpenMPRuntime(C, CmdArgs, getToolChain(), Args);712 713  if (isObjCRuntimeLinked(Args) &&714      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {715    // We use arclite library for both ARC and subscripting support.716    getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);717 718    CmdArgs.push_back("-framework");719    CmdArgs.push_back("Foundation");720    // Link libobj.721    CmdArgs.push_back("-lobjc");722  }723 724  if (LinkingOutput) {725    CmdArgs.push_back("-arch_multiple");726    CmdArgs.push_back("-final_output");727    CmdArgs.push_back(LinkingOutput);728  }729 730  if (Args.hasArg(options::OPT_fnested_functions))731    CmdArgs.push_back("-allow_stack_execute");732 733  getMachOToolChain().addProfileRTLibs(Args, CmdArgs);734 735  StringRef Parallelism = getLTOParallelism(Args, getToolChain().getDriver());736  if (!Parallelism.empty()) {737    CmdArgs.push_back("-mllvm");738    unsigned NumThreads =739        llvm::get_threadpool_strategy(Parallelism)->compute_thread_count();740    CmdArgs.push_back(Args.MakeArgString("-threads=" + Twine(NumThreads)));741  }742 743  if (getToolChain().ShouldLinkCXXStdlib(Args))744    getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);745 746  bool NoStdOrDefaultLibs =747      Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);748  bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib);749  if (!NoStdOrDefaultLibs || ForceLinkBuiltins) {750    // link_ssp spec is empty.751 752    // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then753    // we just want to link the builtins, not the other libs like libSystem.754    if (NoStdOrDefaultLibs && ForceLinkBuiltins) {755      getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins");756    } else {757      // Let the tool chain choose which runtime library to link.758      getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs,759                                                ForceLinkBuiltins);760 761      // No need to do anything for pthreads. Claim argument to avoid warning.762      Args.ClaimAllArgs(options::OPT_pthread);763      Args.ClaimAllArgs(options::OPT_pthreads);764    }765  }766 767  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {768    // endfile_spec is empty.769  }770 771  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);772  Args.AddAllArgs(CmdArgs, options::OPT_F);773 774  // -iframework should be forwarded as -F.775  for (const Arg *A : Args.filtered(options::OPT_iframework))776    CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));777 778  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {779    if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {780      if (A->getValue() == StringRef("Accelerate")) {781        CmdArgs.push_back("-framework");782        CmdArgs.push_back("Accelerate");783      }784    }785  }786 787  // Add non-standard, platform-specific search paths, e.g., for DriverKit:788  //  -L<sysroot>/System/DriverKit/usr/lib789  //  -F<sysroot>/System/DriverKit/System/Library/Framework790  {791    bool NonStandardSearchPath = false;792    const auto &Triple = getToolChain().getTriple();793    if (Triple.isDriverKit()) {794      // ld64 fixed the implicit -F and -L paths in ld64-605.1+.795      NonStandardSearchPath =796          Version.getMajor() < 605 ||797          (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1);798    }799 800    if (NonStandardSearchPath) {801      if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) {802        auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) {803          SmallString<128> P(Sysroot->getValue());804          AppendPlatformPrefix(P, Triple);805          llvm::sys::path::append(P, SearchPath);806          if (getToolChain().getVFS().exists(P)) {807            CmdArgs.push_back(Args.MakeArgString(Flag + P));808          }809        };810        AddSearchPath("-L", "/usr/lib");811        AddSearchPath("-F", "/System/Library/Frameworks");812      }813    }814  }815 816  ResponseFileSupport ResponseSupport;817  if (Version >= VersionTuple(705) || LinkerIsLLD) {818    ResponseSupport = ResponseFileSupport::AtFileUTF8();819  } else {820    // For older versions of the linker, use the legacy filelist method instead.821    ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8,822                       "-filelist"};823  }824 825  std::unique_ptr<Command> Cmd = std::make_unique<Command>(826      JA, *this, ResponseSupport, Exec, CmdArgs, Inputs, Output);827  Cmd->setInputFileList(std::move(InputFileList));828  C.addCommand(std::move(Cmd));829}830 831void darwin::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA,832                                         const InputInfo &Output,833                                         const InputInfoList &Inputs,834                                         const ArgList &Args,835                                         const char *LinkingOutput) const {836  const Driver &D = getToolChain().getDriver();837 838  // Silence warning for "clang -g foo.o -o foo"839  Args.ClaimAllArgs(options::OPT_g_Group);840  // and "clang -emit-llvm foo.o -o foo"841  Args.ClaimAllArgs(options::OPT_emit_llvm);842  // and for "clang -w foo.o -o foo". Other warning options are already843  // handled somewhere else.844  Args.ClaimAllArgs(options::OPT_w);845  // Silence warnings when linking C code with a C++ '-stdlib' argument.846  Args.ClaimAllArgs(options::OPT_stdlib_EQ);847 848  // libtool <options> <output_file> <input_files>849  ArgStringList CmdArgs;850  // Create and insert file members with a deterministic index.851  CmdArgs.push_back("-static");852  CmdArgs.push_back("-D");853  CmdArgs.push_back("-no_warning_for_no_symbols");854  CmdArgs.push_back("-o");855  CmdArgs.push_back(Output.getFilename());856 857  for (const auto &II : Inputs) {858    if (II.isFilename()) {859      CmdArgs.push_back(II.getFilename());860    }861  }862 863  // Delete old output archive file if it already exists before generating a new864  // archive file.865  const auto *OutputFileName = Output.getFilename();866  if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {867    if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {868      D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();869      return;870    }871  }872 873  const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());874  C.addCommand(std::make_unique<Command>(JA, *this,875                                         ResponseFileSupport::AtFileUTF8(),876                                         Exec, CmdArgs, Inputs, Output));877}878 879void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,880                                const InputInfo &Output,881                                const InputInfoList &Inputs,882                                const ArgList &Args,883                                const char *LinkingOutput) const {884  ArgStringList CmdArgs;885 886  CmdArgs.push_back("-create");887  assert(Output.isFilename() && "Unexpected lipo output.");888 889  CmdArgs.push_back("-output");890  CmdArgs.push_back(Output.getFilename());891 892  for (const auto &II : Inputs) {893    assert(II.isFilename() && "Unexpected lipo input.");894    CmdArgs.push_back(II.getFilename());895  }896 897  StringRef LipoName = Args.getLastArgValue(options::OPT_fuse_lipo_EQ, "lipo");898  const char *Exec =899      Args.MakeArgString(getToolChain().GetProgramPath(LipoName.data()));900  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),901                                         Exec, CmdArgs, Inputs, Output));902}903 904void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,905                                    const InputInfo &Output,906                                    const InputInfoList &Inputs,907                                    const ArgList &Args,908                                    const char *LinkingOutput) const {909  ArgStringList CmdArgs;910 911  CmdArgs.push_back("-o");912  CmdArgs.push_back(Output.getFilename());913 914  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");915  const InputInfo &Input = Inputs[0];916  assert(Input.isFilename() && "Unexpected dsymutil input.");917  CmdArgs.push_back(Input.getFilename());918 919  const char *Exec =920      Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));921  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),922                                         Exec, CmdArgs, Inputs, Output));923}924 925void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,926                                       const InputInfo &Output,927                                       const InputInfoList &Inputs,928                                       const ArgList &Args,929                                       const char *LinkingOutput) const {930  ArgStringList CmdArgs;931  CmdArgs.push_back("--verify");932  CmdArgs.push_back("--debug-info");933  CmdArgs.push_back("--eh-frame");934  CmdArgs.push_back("--quiet");935 936  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");937  const InputInfo &Input = Inputs[0];938  assert(Input.isFilename() && "Unexpected verify input");939 940  // Grabbing the output of the earlier dsymutil run.941  CmdArgs.push_back(Input.getFilename());942 943  const char *Exec =944      Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));945  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),946                                         Exec, CmdArgs, Inputs, Output));947}948 949MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)950    : ToolChain(D, Triple, Args) {951  // We expect 'as', 'ld', etc. to be adjacent to our install dir.952  getProgramPaths().push_back(getDriver().Dir);953}954 955AppleMachO::AppleMachO(const Driver &D, const llvm::Triple &Triple,956                       const ArgList &Args)957    : MachO(D, Triple, Args), CudaInstallation(D, Triple, Args),958      RocmInstallation(D, Triple, Args), SYCLInstallation(D, Triple, Args) {}959 960/// Darwin - Darwin tool chain for i386 and x86_64.961Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)962    : AppleMachO(D, Triple, Args), TargetInitialized(false) {}963 964types::ID MachO::LookupTypeForExtension(StringRef Ext) const {965  types::ID Ty = ToolChain::LookupTypeForExtension(Ext);966 967  // Darwin always preprocesses assembly files (unless -x is used explicitly).968  if (Ty == types::TY_PP_Asm)969    return types::TY_Asm;970 971  return Ty;972}973 974bool MachO::HasNativeLLVMSupport() const { return true; }975 976ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {977  // Always use libc++ by default978  return ToolChain::CST_Libcxx;979}980 981/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.982ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {983  if (isTargetWatchOSBased())984    return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);985  if (isTargetIOSBased())986    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);987  if (isTargetXROS()) {988    // XROS uses the iOS runtime.989    auto T = llvm::Triple(Twine("arm64-apple-") +990                          llvm::Triple::getOSTypeName(llvm::Triple::XROS) +991                          TargetVersion.getAsString());992    return ObjCRuntime(ObjCRuntime::iOS, T.getiOSVersion());993  }994  if (isNonFragile)995    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);996  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);997}998 999/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.1000bool Darwin::hasBlocksRuntime() const {1001  if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS())1002    return true;1003  else if (isTargetIOSBased())1004    return !isIPhoneOSVersionLT(3, 2);1005  else {1006    assert(isTargetMacOSBased() && "unexpected darwin target");1007    return !isMacosxVersionLT(10, 6);1008  }1009}1010 1011void AppleMachO::AddCudaIncludeArgs(const ArgList &DriverArgs,1012                                    ArgStringList &CC1Args) const {1013  CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);1014}1015 1016void AppleMachO::AddHIPIncludeArgs(const ArgList &DriverArgs,1017                                   ArgStringList &CC1Args) const {1018  RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);1019}1020 1021void AppleMachO::addSYCLIncludeArgs(const ArgList &DriverArgs,1022                                    ArgStringList &CC1Args) const {1023  SYCLInstallation->addSYCLIncludeArgs(DriverArgs, CC1Args);1024}1025 1026// This is just a MachO name translation routine and there's no1027// way to join this into ARMTargetParser without breaking all1028// other assumptions. Maybe MachO should consider standardising1029// their nomenclature.1030static const char *ArmMachOArchName(StringRef Arch) {1031  return llvm::StringSwitch<const char *>(Arch)1032      .Case("armv6k", "armv6")1033      .Case("armv6m", "armv6m")1034      .Case("armv5tej", "armv5")1035      .Case("xscale", "xscale")1036      .Case("armv4t", "armv4t")1037      .Case("armv7", "armv7")1038      .Cases({"armv7a", "armv7-a"}, "armv7")1039      .Cases({"armv7r", "armv7-r"}, "armv7")1040      .Cases({"armv7em", "armv7e-m"}, "armv7em")1041      .Cases({"armv7k", "armv7-k"}, "armv7k")1042      .Cases({"armv7m", "armv7-m"}, "armv7m")1043      .Cases({"armv7s", "armv7-s"}, "armv7s")1044      .Default(nullptr);1045}1046 1047static const char *ArmMachOArchNameCPU(StringRef CPU) {1048  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);1049  if (ArchKind == llvm::ARM::ArchKind::INVALID)1050    return nullptr;1051  StringRef Arch = llvm::ARM::getArchName(ArchKind);1052 1053  // FIXME: Make sure this MachO triple mangling is really necessary.1054  // ARMv5* normalises to ARMv5.1055  if (Arch.starts_with("armv5"))1056    Arch = Arch.substr(0, 5);1057  // ARMv6*, except ARMv6M, normalises to ARMv6.1058  else if (Arch.starts_with("armv6") && !Arch.ends_with("6m"))1059    Arch = Arch.substr(0, 5);1060  // ARMv7A normalises to ARMv7.1061  else if (Arch.ends_with("v7a"))1062    Arch = Arch.substr(0, 5);1063  return Arch.data();1064}1065 1066StringRef MachO::getMachOArchName(const ArgList &Args) const {1067  switch (getTriple().getArch()) {1068  default:1069    return getDefaultUniversalArchName();1070 1071  case llvm::Triple::aarch64_32:1072    return "arm64_32";1073 1074  case llvm::Triple::aarch64: {1075    if (getTriple().isArm64e())1076      return "arm64e";1077    return "arm64";1078  }1079 1080  case llvm::Triple::thumb:1081  case llvm::Triple::arm:1082    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))1083      if (const char *Arch = ArmMachOArchName(A->getValue()))1084        return Arch;1085 1086    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))1087      if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))1088        return Arch;1089 1090    return "arm";1091  }1092}1093 1094VersionTuple MachO::getLinkerVersion(const llvm::opt::ArgList &Args) const {1095  if (LinkerVersion) {1096#ifndef NDEBUG1097    VersionTuple NewLinkerVersion;1098    if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ))1099      (void)NewLinkerVersion.tryParse(A->getValue());1100    assert(NewLinkerVersion == LinkerVersion);1101#endif1102    return *LinkerVersion;1103  }1104 1105  VersionTuple NewLinkerVersion;1106  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ))1107    if (NewLinkerVersion.tryParse(A->getValue()))1108      getDriver().Diag(diag::err_drv_invalid_version_number)1109        << A->getAsString(Args);1110 1111  LinkerVersion = NewLinkerVersion;1112  return *LinkerVersion;1113}1114 1115Darwin::~Darwin() {}1116 1117AppleMachO::~AppleMachO() {}1118 1119MachO::~MachO() {}1120 1121std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,1122                                                types::ID InputType) const {1123  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));1124 1125  // If the target isn't initialized (e.g., an unknown Darwin platform, return1126  // the default triple).1127  if (!isTargetInitialized())1128    return Triple.getTriple();1129 1130  SmallString<16> Str;1131  if (isTargetWatchOSBased())1132    Str += "watchos";1133  else if (isTargetTvOSBased())1134    Str += "tvos";1135  else if (isTargetDriverKit())1136    Str += "driverkit";1137  else if (isTargetIOSBased() || isTargetMacCatalyst())1138    Str += "ios";1139  else if (isTargetXROS())1140    Str += llvm::Triple::getOSTypeName(llvm::Triple::XROS);1141  else1142    Str += "macosx";1143  Str += getTripleTargetVersion().getAsString();1144  Triple.setOSName(Str);1145 1146  return Triple.getTriple();1147}1148 1149Tool *MachO::getTool(Action::ActionClass AC) const {1150  switch (AC) {1151  case Action::LipoJobClass:1152    if (!Lipo)1153      Lipo.reset(new tools::darwin::Lipo(*this));1154    return Lipo.get();1155  case Action::DsymutilJobClass:1156    if (!Dsymutil)1157      Dsymutil.reset(new tools::darwin::Dsymutil(*this));1158    return Dsymutil.get();1159  case Action::VerifyDebugInfoJobClass:1160    if (!VerifyDebug)1161      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));1162    return VerifyDebug.get();1163  default:1164    return ToolChain::getTool(AC);1165  }1166}1167 1168Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }1169 1170Tool *MachO::buildStaticLibTool() const {1171  return new tools::darwin::StaticLibTool(*this);1172}1173 1174Tool *MachO::buildAssembler() const {1175  return new tools::darwin::Assembler(*this);1176}1177 1178DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,1179                         const ArgList &Args)1180    : Darwin(D, Triple, Args) {}1181 1182void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {1183  // Always error about undefined 'TARGET_OS_*' macros.1184  CC1Args.push_back("-Wundef-prefix=TARGET_OS_");1185  CC1Args.push_back("-Werror=undef-prefix");1186 1187  // For modern targets, promote certain warnings to errors.1188  if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {1189    // Always enable -Wdeprecated-objc-isa-usage and promote it1190    // to an error.1191    CC1Args.push_back("-Wdeprecated-objc-isa-usage");1192    CC1Args.push_back("-Werror=deprecated-objc-isa-usage");1193 1194    // For iOS and watchOS, also error about implicit function declarations,1195    // as that can impact calling conventions.1196    if (!isTargetMacOS())1197      CC1Args.push_back("-Werror=implicit-function-declaration");1198  }1199}1200 1201void DarwinClang::addClangTargetOptions(1202    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,1203    Action::OffloadKind DeviceOffloadKind) const {1204 1205  Darwin::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);1206}1207 1208/// Take a path that speculatively points into Xcode and return the1209/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path1210/// otherwise.1211static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) {1212  static constexpr llvm::StringLiteral XcodeAppSuffix(1213      ".app/Contents/Developer");1214  size_t Index = PathIntoXcode.find(XcodeAppSuffix);1215  if (Index == StringRef::npos)1216    return "";1217  return PathIntoXcode.take_front(Index + XcodeAppSuffix.size());1218}1219 1220void DarwinClang::AddLinkARCArgs(const ArgList &Args,1221                                 ArgStringList &CmdArgs) const {1222  // Avoid linking compatibility stubs on i386 mac.1223  if (isTargetMacOSBased() && getArch() == llvm::Triple::x86)1224    return;1225  if (isTargetAppleSiliconMac())1226    return;1227  // ARC runtime is supported everywhere on arm64e.1228  if (getTriple().isArm64e())1229    return;1230  if (isTargetXROS())1231    return;1232 1233  ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);1234 1235  if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&1236      runtime.hasSubscripting())1237    return;1238 1239  SmallString<128> P(getDriver().ClangExecutable);1240  llvm::sys::path::remove_filename(P); // 'clang'1241  llvm::sys::path::remove_filename(P); // 'bin'1242  llvm::sys::path::append(P, "lib", "arc");1243 1244  // 'libarclite' usually lives in the same toolchain as 'clang'. However, the1245  // Swift open source toolchains for macOS distribute Clang without libarclite.1246  // In that case, to allow the linker to find 'libarclite', we point to the1247  // 'libarclite' in the XcodeDefault toolchain instead.1248  if (!getVFS().exists(P)) {1249    auto updatePath = [&](const Arg *A) {1250      // Try to infer the path to 'libarclite' in the toolchain from the1251      // specified SDK path.1252      StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue());1253      if (XcodePathForSDK.empty())1254        return false;1255 1256      P = XcodePathForSDK;1257      llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr",1258                              "lib", "arc");1259      return getVFS().exists(P);1260    };1261 1262    bool updated = false;1263    if (const Arg *A = Args.getLastArg(options::OPT_isysroot))1264      updated = updatePath(A);1265 1266    if (!updated) {1267      if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))1268        updatePath(A);1269    }1270  }1271 1272  CmdArgs.push_back("-force_load");1273  llvm::sys::path::append(P, "libarclite_");1274  // Mash in the platform.1275  if (isTargetWatchOSSimulator())1276    P += "watchsimulator";1277  else if (isTargetWatchOS())1278    P += "watchos";1279  else if (isTargetTvOSSimulator())1280    P += "appletvsimulator";1281  else if (isTargetTvOS())1282    P += "appletvos";1283  else if (isTargetIOSSimulator())1284    P += "iphonesimulator";1285  else if (isTargetIPhoneOS())1286    P += "iphoneos";1287  else1288    P += "macosx";1289  P += ".a";1290 1291  if (!getVFS().exists(P))1292    getDriver().Diag(clang::diag::err_drv_darwin_sdk_missing_arclite) << P;1293 1294  CmdArgs.push_back(Args.MakeArgString(P));1295}1296 1297unsigned DarwinClang::GetDefaultDwarfVersion() const {1298  // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.1299  if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) ||1300      (isTargetIOSBased() && isIPhoneOSVersionLT(9)))1301    return 2;1302  // Default to use DWARF 4 on OS X 10.11 - macOS 14 / iOS 9 - iOS 17.1303  if ((isTargetMacOSBased() && isMacosxVersionLT(15)) ||1304      (isTargetIOSBased() && isIPhoneOSVersionLT(18)) ||1305      (isTargetWatchOSBased() && TargetVersion < llvm::VersionTuple(11)) ||1306      (isTargetXROS() && TargetVersion < llvm::VersionTuple(2)) ||1307      (isTargetDriverKit() && TargetVersion < llvm::VersionTuple(24)) ||1308      (isTargetMacOSBased() &&1309       TargetVersion.empty())) // apple-darwin, no version.1310    return 4;1311  return 5;1312}1313 1314void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,1315                              StringRef Component, RuntimeLinkOptions Opts,1316                              bool IsShared) const {1317  std::string P = getCompilerRT(1318      Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static);1319 1320  // For now, allow missing resource libraries to support developers who may1321  // not have compiler-rt checked out or integrated into their build (unless1322  // we explicitly force linking with this library).1323  if ((Opts & RLO_AlwaysLink) || getVFS().exists(P)) {1324    const char *LibArg = Args.MakeArgString(P);1325    CmdArgs.push_back(LibArg);1326  }1327 1328  // Adding the rpaths might negatively interact when other rpaths are involved,1329  // so we should make sure we add the rpaths last, after all user-specified1330  // rpaths. This is currently true from this place, but we need to be1331  // careful if this function is ever called before user's rpaths are emitted.1332  if (Opts & RLO_AddRPath) {1333    assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library");1334 1335    // Add @executable_path to rpath to support having the dylib copied with1336    // the executable.1337    CmdArgs.push_back("-rpath");1338    CmdArgs.push_back("@executable_path");1339 1340    // Add the compiler-rt library's directory to rpath to support using the1341    // dylib from the default location without copying.1342    CmdArgs.push_back("-rpath");1343    CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P)));1344  }1345}1346 1347std::string MachO::getCompilerRT(const ArgList &, StringRef Component,1348                                 FileType Type, bool IsFortran) const {1349  assert(Type != ToolChain::FT_Object &&1350         "it doesn't make sense to ask for the compiler-rt library name as an "1351         "object file");1352  SmallString<64> MachOLibName = StringRef("libclang_rt");1353  // On MachO, the builtins component is not in the library name1354  if (Component != "builtins") {1355    MachOLibName += '.';1356    MachOLibName += Component;1357  }1358  MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";1359 1360  SmallString<128> FullPath(getDriver().ResourceDir);1361  llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded",1362                          MachOLibName);1363  return std::string(FullPath);1364}1365 1366std::string Darwin::getCompilerRT(const ArgList &, StringRef Component,1367                                  FileType Type, bool IsFortran) const {1368  assert(Type != ToolChain::FT_Object &&1369         "it doesn't make sense to ask for the compiler-rt library name as an "1370         "object file");1371  SmallString<64> DarwinLibName = StringRef("libclang_rt.");1372  // On Darwin, the builtins component is not in the library name1373  if (Component != "builtins") {1374    DarwinLibName += Component;1375    DarwinLibName += '_';1376  }1377  DarwinLibName += getOSLibraryNameSuffix();1378  DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";1379 1380  SmallString<128> FullPath(getDriver().ResourceDir);1381  llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName);1382  return std::string(FullPath);1383}1384 1385StringRef Darwin::getPlatformFamily() const {1386  switch (TargetPlatform) {1387    case DarwinPlatformKind::MacOS:1388      return "MacOSX";1389    case DarwinPlatformKind::IPhoneOS:1390      if (TargetEnvironment == MacCatalyst)1391        return "MacOSX";1392      return "iPhone";1393    case DarwinPlatformKind::TvOS:1394      return "AppleTV";1395    case DarwinPlatformKind::WatchOS:1396      return "Watch";1397    case DarwinPlatformKind::DriverKit:1398      return "DriverKit";1399    case DarwinPlatformKind::XROS:1400      return "XR";1401  }1402  llvm_unreachable("Unsupported platform");1403}1404 1405StringRef Darwin::getSDKName(StringRef isysroot) {1406  // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk1407  auto BeginSDK = llvm::sys::path::rbegin(isysroot);1408  auto EndSDK = llvm::sys::path::rend(isysroot);1409  for (auto IT = BeginSDK; IT != EndSDK; ++IT) {1410    StringRef SDK = *IT;1411    if (SDK.consume_back(".sdk"))1412      return SDK;1413  }1414  return "";1415}1416 1417StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {1418  switch (TargetPlatform) {1419  case DarwinPlatformKind::MacOS:1420    return "osx";1421  case DarwinPlatformKind::IPhoneOS:1422    if (TargetEnvironment == MacCatalyst)1423      return "osx";1424    return TargetEnvironment == NativeEnvironment || IgnoreSim ? "ios"1425                                                               : "iossim";1426  case DarwinPlatformKind::TvOS:1427    return TargetEnvironment == NativeEnvironment || IgnoreSim ? "tvos"1428                                                               : "tvossim";1429  case DarwinPlatformKind::WatchOS:1430    return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos"1431                                                               : "watchossim";1432  case DarwinPlatformKind::XROS:1433    return TargetEnvironment == NativeEnvironment || IgnoreSim ? "xros"1434                                                               : "xrossim";1435  case DarwinPlatformKind::DriverKit:1436    return "driverkit";1437  }1438  llvm_unreachable("Unsupported platform");1439}1440 1441/// Check if the link command contains a symbol export directive.1442static bool hasExportSymbolDirective(const ArgList &Args) {1443  for (Arg *A : Args) {1444    if (A->getOption().matches(options::OPT_exported__symbols__list))1445      return true;1446    if (!A->getOption().matches(options::OPT_Wl_COMMA) &&1447        !A->getOption().matches(options::OPT_Xlinker))1448      continue;1449    if (A->containsValue("-exported_symbols_list") ||1450        A->containsValue("-exported_symbol"))1451      return true;1452  }1453  return false;1454}1455 1456/// Add an export directive for \p Symbol to the link command.1457static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) {1458  CmdArgs.push_back("-exported_symbol");1459  CmdArgs.push_back(Symbol);1460}1461 1462/// Add a sectalign directive for \p Segment and \p Section to the maximum1463/// expected page size for Darwin.1464///1465/// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K.1466/// Use a common alignment constant (16K) for now, and reduce the alignment on1467/// macOS if it proves important.1468static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs,1469                               StringRef Segment, StringRef Section) {1470  for (const char *A : {"-sectalign", Args.MakeArgString(Segment),1471                        Args.MakeArgString(Section), "0x4000"})1472    CmdArgs.push_back(A);1473}1474 1475void Darwin::addProfileRTLibs(const ArgList &Args,1476                              ArgStringList &CmdArgs) const {1477  if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args))1478    return;1479 1480  AddLinkRuntimeLib(Args, CmdArgs, "profile",1481                    RuntimeLinkOptions(RLO_AlwaysLink));1482 1483  bool ForGCOV = needsGCovInstrumentation(Args);1484 1485  // If we have a symbol export directive and we're linking in the profile1486  // runtime, automatically export symbols necessary to implement some of the1487  // runtime's functionality.1488  if (hasExportSymbolDirective(Args) && ForGCOV) {1489    addExportedSymbol(CmdArgs, "___gcov_dump");1490    addExportedSymbol(CmdArgs, "___gcov_reset");1491    addExportedSymbol(CmdArgs, "_writeout_fn_list");1492    addExportedSymbol(CmdArgs, "_reset_fn_list");1493  }1494 1495  // Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page1496  // alignment. This allows profile counters to be mmap()'d to disk. Note that1497  // it's not enough to just page-align __llvm_prf_cnts: the following section1498  // must also be page-aligned so that its data is not clobbered by mmap().1499  //1500  // The section alignment is only needed when continuous profile sync is1501  // enabled, but this is expected to be the default in Xcode. Specifying the1502  // extra alignment also allows the same binary to be used with/without sync1503  // enabled.1504  if (!ForGCOV) {1505    for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_bitmap, llvm::IPSK_data}) {1506      addSectalignToPage(1507          Args, CmdArgs, "__DATA",1508          llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO,1509                                        /*AddSegmentInfo=*/false));1510    }1511  }1512}1513 1514void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,1515                                          ArgStringList &CmdArgs,1516                                          StringRef Sanitizer,1517                                          bool Shared) const {1518  auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U));1519  AddLinkRuntimeLib(Args, CmdArgs, Sanitizer, RLO, Shared);1520}1521 1522ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(1523    const ArgList &Args) const {1524  if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {1525    StringRef Value = A->getValue();1526    if (Value != "compiler-rt" && Value != "platform")1527      getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform)1528          << Value << "darwin";1529  }1530 1531  return ToolChain::RLT_CompilerRT;1532}1533 1534void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,1535                                        ArgStringList &CmdArgs,1536                                        bool ForceLinkBuiltinRT) const {1537  // Call once to ensure diagnostic is printed if wrong value was specified1538  GetRuntimeLibType(Args);1539 1540  // Darwin doesn't support real static executables, don't link any runtime1541  // libraries with -static.1542  if (Args.hasArg(options::OPT_static) ||1543      Args.hasArg(options::OPT_fapple_kext) ||1544      Args.hasArg(options::OPT_mkernel)) {1545    if (ForceLinkBuiltinRT)1546      AddLinkRuntimeLib(Args, CmdArgs, "builtins");1547    return;1548  }1549 1550  // Reject -static-libgcc for now, we can deal with this when and if someone1551  // cares. This is useful in situations where someone wants to statically link1552  // something like libstdc++, and needs its runtime support routines.1553  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {1554    getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);1555    return;1556  }1557 1558  const SanitizerArgs &Sanitize = getSanitizerArgs(Args);1559 1560  if (!Sanitize.needsSharedRt()) {1561    const char *sanitizer = nullptr;1562    if (Sanitize.needsUbsanRt()) {1563      sanitizer = "UndefinedBehaviorSanitizer";1564    } else if (Sanitize.needsRtsanRt()) {1565      sanitizer = "RealtimeSanitizer";1566    } else if (Sanitize.needsAsanRt()) {1567      sanitizer = "AddressSanitizer";1568    } else if (Sanitize.needsTsanRt()) {1569      sanitizer = "ThreadSanitizer";1570    }1571    if (sanitizer) {1572      getDriver().Diag(diag::err_drv_unsupported_static_sanitizer_darwin)1573          << sanitizer;1574      return;1575    }1576  }1577 1578  if (Sanitize.linkRuntimes()) {1579    if (Sanitize.needsAsanRt()) {1580      if (Sanitize.needsStableAbi()) {1581        AddLinkSanitizerLibArgs(Args, CmdArgs, "asan_abi", /*shared=*/false);1582      } else {1583        assert(Sanitize.needsSharedRt() &&1584               "Static sanitizer runtimes not supported");1585        AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");1586      }1587    }1588    if (Sanitize.needsRtsanRt()) {1589      assert(Sanitize.needsSharedRt() &&1590             "Static sanitizer runtimes not supported");1591      AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan");1592    }1593    if (Sanitize.needsLsanRt())1594      AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");1595    if (Sanitize.needsUbsanRt()) {1596      assert(Sanitize.needsSharedRt() &&1597             "Static sanitizer runtimes not supported");1598      AddLinkSanitizerLibArgs(1599          Args, CmdArgs,1600          Sanitize.requiresMinimalRuntime() ? "ubsan_minimal" : "ubsan");1601    }1602    if (Sanitize.needsTsanRt()) {1603      assert(Sanitize.needsSharedRt() &&1604             "Static sanitizer runtimes not supported");1605      AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");1606    }1607    if (Sanitize.needsTysanRt())1608      AddLinkSanitizerLibArgs(Args, CmdArgs, "tysan");1609    if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) {1610      AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false);1611 1612      // Libfuzzer is written in C++ and requires libcxx.1613      // Since darwin::Linker::ConstructJob already adds -lc++ for clang++1614      // by default if ShouldLinkCXXStdlib(Args), we only add the option if1615      // !ShouldLinkCXXStdlib(Args). This avoids duplicate library errors1616      // on Darwin.1617      if (!ShouldLinkCXXStdlib(Args))1618        AddCXXStdlibLibArgs(Args, CmdArgs);1619    }1620    if (Sanitize.needsStatsRt()) {1621      AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);1622      AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");1623    }1624  }1625 1626  if (Sanitize.needsMemProfRt())1627    if (hasExportSymbolDirective(Args))1628      addExportedSymbol(1629          CmdArgs,1630          llvm::memprof::getMemprofOptionsSymbolDarwinLinkageName().data());1631 1632  const XRayArgs &XRay = getXRayArgs(Args);1633  if (XRay.needsXRayRt()) {1634    AddLinkRuntimeLib(Args, CmdArgs, "xray");1635    AddLinkRuntimeLib(Args, CmdArgs, "xray-basic");1636    AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr");1637  }1638 1639  if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) {1640    CmdArgs.push_back("-framework");1641    CmdArgs.push_back("DriverKit");1642  }1643 1644  // Otherwise link libSystem, then the dynamic runtime library, and finally any1645  // target specific static runtime library.1646  if (!isTargetDriverKit())1647    CmdArgs.push_back("-lSystem");1648 1649  // Select the dynamic runtime library and the target specific static library.1650  // Some old Darwin versions put builtins, libunwind, and some other stuff in1651  // libgcc_s.1.dylib. MacOS X 10.6 and iOS 5 moved those functions to1652  // libSystem, and made libgcc_s.1.dylib a stub. We never link libgcc_s when1653  // building for aarch64 or iOS simulator, since libgcc_s was made obsolete1654  // before either existed.1655  if (getTriple().getArch() != llvm::Triple::aarch64 &&1656      ((isTargetIOSBased() && isIPhoneOSVersionLT(5, 0) &&1657        !isTargetIOSSimulator()) ||1658       (isTargetMacOSBased() && isMacosxVersionLT(10, 6))))1659    CmdArgs.push_back("-lgcc_s.1");1660  AddLinkRuntimeLib(Args, CmdArgs, "builtins");1661}1662 1663/// Returns the most appropriate macOS target version for the current process.1664///1665/// If the macOS SDK version is the same or earlier than the system version,1666/// then the SDK version is returned. Otherwise the system version is returned.1667static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {1668  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());1669  if (!SystemTriple.isMacOSX())1670    return std::string(MacOSSDKVersion);1671  VersionTuple SystemVersion;1672  SystemTriple.getMacOSXVersion(SystemVersion);1673 1674  unsigned Major, Minor, Micro;1675  bool HadExtra;1676  if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,1677                                 HadExtra))1678    return std::string(MacOSSDKVersion);1679  VersionTuple SDKVersion(Major, Minor, Micro);1680 1681  if (SDKVersion > SystemVersion)1682    return SystemVersion.getAsString();1683  return std::string(MacOSSDKVersion);1684}1685 1686namespace {1687 1688/// The Darwin OS and version that was selected or inferred from arguments or1689/// environment.1690struct DarwinPlatform {1691  enum SourceKind {1692    /// The OS was specified using the -target argument.1693    TargetArg,1694    /// The OS was specified using the -mtargetos= argument.1695    MTargetOSArg,1696    /// The OS was specified using the -m<os>-version-min argument.1697    OSVersionArg,1698    /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.1699    DeploymentTargetEnv,1700    /// The OS was inferred from the SDK.1701    InferredFromSDK,1702    /// The OS was inferred from the -arch.1703    InferredFromArch1704  };1705 1706  using DarwinPlatformKind = Darwin::DarwinPlatformKind;1707  using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind;1708 1709  DarwinPlatformKind getPlatform() const { return Platform; }1710 1711  DarwinEnvironmentKind getEnvironment() const { return Environment; }1712 1713  void setEnvironment(DarwinEnvironmentKind Kind) {1714    Environment = Kind;1715    InferSimulatorFromArch = false;1716  }1717 1718  const VersionTuple getOSVersion() const {1719    return UnderlyingOSVersion.value_or(VersionTuple());1720  }1721 1722  VersionTuple takeOSVersion() {1723    assert(UnderlyingOSVersion.has_value() &&1724           "attempting to get an unset OS version");1725    VersionTuple Result = *UnderlyingOSVersion;1726    UnderlyingOSVersion.reset();1727    return Result;1728  }1729  bool isValidOSVersion() const {1730    return llvm::Triple::isValidVersionForOS(getOSFromPlatform(Platform),1731                                             getOSVersion());1732  }1733 1734  VersionTuple getCanonicalOSVersion() const {1735    return llvm::Triple::getCanonicalVersionForOS(1736        getOSFromPlatform(Platform), getOSVersion(), /*IsInValidRange=*/true);1737  }1738 1739  void setOSVersion(const VersionTuple &Version) {1740    UnderlyingOSVersion = Version;1741  }1742 1743  bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); }1744 1745  VersionTuple getZipperedOSVersion() const {1746    assert(Environment == DarwinEnvironmentKind::MacCatalyst &&1747           "zippered target version is specified only for Mac Catalyst");1748    return ZipperedOSVersion;1749  }1750 1751  /// Returns true if the target OS was explicitly specified.1752  bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }1753 1754  /// Returns true if the simulator environment can be inferred from the arch.1755  bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }1756 1757  const std::optional<llvm::Triple> &getTargetVariantTriple() const {1758    return TargetVariantTriple;1759  }1760 1761  /// Adds the -m<os>-version-min argument to the compiler invocation.1762  void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {1763    auto &[Arg, OSVersionStr] = Arguments;1764    if (Arg)1765      return;1766    assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&1767           "Invalid kind");1768    options::ID Opt;1769    switch (Platform) {1770    case DarwinPlatformKind::MacOS:1771      Opt = options::OPT_mmacos_version_min_EQ;1772      break;1773    case DarwinPlatformKind::IPhoneOS:1774      Opt = options::OPT_mios_version_min_EQ;1775      break;1776    case DarwinPlatformKind::TvOS:1777      Opt = options::OPT_mtvos_version_min_EQ;1778      break;1779    case DarwinPlatformKind::WatchOS:1780      Opt = options::OPT_mwatchos_version_min_EQ;1781      break;1782    case DarwinPlatformKind::XROS:1783      // xrOS always explicitly provides a version in the triple.1784      return;1785    case DarwinPlatformKind::DriverKit:1786      // DriverKit always explicitly provides a version in the triple.1787      return;1788    }1789    Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);1790    Args.append(Arg);1791  }1792 1793  /// Returns the OS version with the argument / environment variable that1794  /// specified it.1795  std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {1796    auto &[Arg, OSVersionStr] = Arguments;1797    switch (Kind) {1798    case TargetArg:1799    case MTargetOSArg:1800    case OSVersionArg:1801      assert(Arg && "OS version argument not yet inferred");1802      return Arg->getAsString(Args);1803    case DeploymentTargetEnv:1804      return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();1805    case InferredFromSDK:1806    case InferredFromArch:1807      llvm_unreachable("Cannot print arguments for inferred OS version");1808    }1809    llvm_unreachable("Unsupported Darwin Source Kind");1810  }1811 1812  // Returns the inferred source of how the OS version was resolved.1813  std::string getInferredSource() {1814    assert(!isExplicitlySpecified() && "OS version was not inferred");1815    return InferredSource.str();1816  }1817 1818  void setEnvironment(llvm::Triple::EnvironmentType EnvType,1819                      const VersionTuple &OSVersion,1820                      const std::optional<DarwinSDKInfo> &SDKInfo) {1821    switch (EnvType) {1822    case llvm::Triple::Simulator:1823      Environment = DarwinEnvironmentKind::Simulator;1824      break;1825    case llvm::Triple::MacABI: {1826      Environment = DarwinEnvironmentKind::MacCatalyst;1827      // The minimum native macOS target for MacCatalyst is macOS 10.15.1828      ZipperedOSVersion = VersionTuple(10, 15);1829      if (hasOSVersion() && SDKInfo) {1830        if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(1831                DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {1832          if (auto MacOSVersion = MacCatalystToMacOSMapping->map(1833                  OSVersion, ZipperedOSVersion, std::nullopt)) {1834            ZipperedOSVersion = *MacOSVersion;1835          }1836        }1837      }1838      // In a zippered build, we could be building for a macOS target that's1839      // lower than the version that's implied by the OS version. In that case1840      // we need to use the minimum version as the native target version.1841      if (TargetVariantTriple) {1842        auto TargetVariantVersion = TargetVariantTriple->getOSVersion();1843        if (TargetVariantVersion.getMajor()) {1844          if (TargetVariantVersion < ZipperedOSVersion)1845            ZipperedOSVersion = TargetVariantVersion;1846        }1847      }1848      break;1849    }1850    default:1851      break;1852    }1853  }1854 1855  static DarwinPlatform1856  createFromTarget(const llvm::Triple &TT, Arg *A,1857                   std::optional<llvm::Triple> TargetVariantTriple,1858                   const std::optional<DarwinSDKInfo> &SDKInfo) {1859    DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()),1860                          TT.getOSVersion(), A);1861    VersionTuple OsVersion = TT.getOSVersion();1862    Result.TargetVariantTriple = TargetVariantTriple;1863    Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);1864    return Result;1865  }1866  static DarwinPlatform1867  createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,1868                      llvm::Triple::EnvironmentType Environment, Arg *A,1869                      const std::optional<DarwinSDKInfo> &SDKInfo) {1870    DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), OSVersion, A);1871    Result.InferSimulatorFromArch = false;1872    Result.setEnvironment(Environment, OSVersion, SDKInfo);1873    return Result;1874  }1875  static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A,1876                                           bool IsSimulator) {1877    DarwinPlatform Result{OSVersionArg, Platform,1878                          getVersionFromString(A->getValue()), A};1879    if (IsSimulator)1880      Result.Environment = DarwinEnvironmentKind::Simulator;1881    return Result;1882  }1883  static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,1884                                                  StringRef EnvVarName,1885                                                  StringRef OSVersion) {1886    DarwinPlatform Result(DeploymentTargetEnv, Platform,1887                          getVersionFromString(OSVersion));1888    Result.EnvVarName = EnvVarName;1889    return Result;1890  }1891  static DarwinPlatform createFromSDK(StringRef SDKRoot,1892                                      DarwinPlatformKind Platform,1893                                      StringRef Value,1894                                      bool IsSimulator = false) {1895    DarwinPlatform Result(InferredFromSDK, Platform,1896                          getVersionFromString(Value));1897    if (IsSimulator)1898      Result.Environment = DarwinEnvironmentKind::Simulator;1899    Result.InferSimulatorFromArch = false;1900    Result.InferredSource = SDKRoot;1901    return Result;1902  }1903  static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,1904                                       VersionTuple Version) {1905    auto Result =1906        DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);1907    Result.InferredSource = Arch;1908    return Result;1909  }1910 1911  /// Constructs an inferred SDKInfo value based on the version inferred from1912  /// the SDK path itself. Only works for values that were created by inferring1913  /// the platform from the SDKPath.1914  DarwinSDKInfo inferSDKInfo() {1915    assert(Kind == InferredFromSDK && "can infer SDK info only");1916    return DarwinSDKInfo(getOSVersion(),1917                         /*MaximumDeploymentTarget=*/1918                         VersionTuple(getOSVersion().getMajor(), 0, 99),1919                         getOSFromPlatform(Platform));1920  }1921 1922private:1923  DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)1924      : Kind(Kind), Platform(Platform),1925        Arguments({Argument, VersionTuple().getAsString()}) {}1926  DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,1927                 VersionTuple Value, Arg *Argument = nullptr)1928      : Kind(Kind), Platform(Platform),1929        Arguments({Argument, Value.getAsString()}) {1930    if (!Value.empty())1931      UnderlyingOSVersion = Value;1932  }1933 1934  static VersionTuple getVersionFromString(const StringRef Input) {1935    llvm::VersionTuple Version;1936    bool IsValid = !Version.tryParse(Input);1937    assert(IsValid && "unable to convert input version to version tuple");1938    (void)IsValid;1939    return Version;1940  }1941 1942  static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {1943    switch (OS) {1944    case llvm::Triple::Darwin:1945    case llvm::Triple::MacOSX:1946      return DarwinPlatformKind::MacOS;1947    case llvm::Triple::IOS:1948      return DarwinPlatformKind::IPhoneOS;1949    case llvm::Triple::TvOS:1950      return DarwinPlatformKind::TvOS;1951    case llvm::Triple::WatchOS:1952      return DarwinPlatformKind::WatchOS;1953    case llvm::Triple::XROS:1954      return DarwinPlatformKind::XROS;1955    case llvm::Triple::DriverKit:1956      return DarwinPlatformKind::DriverKit;1957    default:1958      llvm_unreachable("Unable to infer Darwin variant");1959    }1960  }1961 1962  static llvm::Triple::OSType getOSFromPlatform(DarwinPlatformKind Platform) {1963    switch (Platform) {1964    case DarwinPlatformKind::MacOS:1965      return llvm::Triple::MacOSX;1966    case DarwinPlatformKind::IPhoneOS:1967      return llvm::Triple::IOS;1968    case DarwinPlatformKind::TvOS:1969      return llvm::Triple::TvOS;1970    case DarwinPlatformKind::WatchOS:1971      return llvm::Triple::WatchOS;1972    case DarwinPlatformKind::DriverKit:1973      return llvm::Triple::DriverKit;1974    case DarwinPlatformKind::XROS:1975      return llvm::Triple::XROS;1976    }1977    llvm_unreachable("Unknown DarwinPlatformKind enum");1978  }1979 1980  SourceKind Kind;1981  DarwinPlatformKind Platform;1982  DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;1983  // When compiling for a zippered target, this means both target &1984  // target variant is set on the command line, ZipperedOSVersion holds the1985  // OSVersion tied to the main target value.1986  VersionTuple ZipperedOSVersion;1987  // We allow multiple ways to set or default the OS1988  // version used for compilation. When set, UnderlyingOSVersion represents1989  // the intended version to match the platform information computed from1990  // arguments.1991  std::optional<VersionTuple> UnderlyingOSVersion;1992  bool InferSimulatorFromArch = true;1993  std::pair<Arg *, std::string> Arguments;1994  StringRef EnvVarName;1995  // If the DarwinPlatform information is derived from an inferred source, this1996  // captures what that source input was for error reporting.1997  StringRef InferredSource;1998  // When compiling for a zippered target, this value represents the target1999  // triple encoded in the target variant.2000  std::optional<llvm::Triple> TargetVariantTriple;2001};2002 2003/// Returns the deployment target that's specified using the -m<os>-version-min2004/// argument.2005std::optional<DarwinPlatform>2006getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,2007                                    const Driver &TheDriver) {2008  Arg *macOSVersion = Args.getLastArg(options::OPT_mmacos_version_min_EQ);2009  Arg *iOSVersion = Args.getLastArg(options::OPT_mios_version_min_EQ,2010                                    options::OPT_mios_simulator_version_min_EQ);2011  Arg *TvOSVersion =2012      Args.getLastArg(options::OPT_mtvos_version_min_EQ,2013                      options::OPT_mtvos_simulator_version_min_EQ);2014  Arg *WatchOSVersion =2015      Args.getLastArg(options::OPT_mwatchos_version_min_EQ,2016                      options::OPT_mwatchos_simulator_version_min_EQ);2017 2018  auto GetDarwinPlatform =2019      [&](DarwinPlatform::DarwinPlatformKind Platform, Arg *VersionArg,2020          bool IsSimulator) -> std::optional<DarwinPlatform> {2021    if (StringRef(VersionArg->getValue()).empty()) {2022      TheDriver.Diag(diag::err_drv_missing_version_number)2023          << VersionArg->getAsString(Args);2024      return std::nullopt;2025    }2026    return DarwinPlatform::createOSVersionArg(Platform, VersionArg,2027                                              /*IsSimulator=*/IsSimulator);2028  };2029 2030  if (macOSVersion) {2031    if (iOSVersion || TvOSVersion || WatchOSVersion) {2032      TheDriver.Diag(diag::err_drv_argument_not_allowed_with)2033          << macOSVersion->getAsString(Args)2034          << (iOSVersion ? iOSVersion2035                         : TvOSVersion ? TvOSVersion : WatchOSVersion)2036                 ->getAsString(Args);2037    }2038    return GetDarwinPlatform(Darwin::MacOS, macOSVersion,2039                             /*IsSimulator=*/false);2040 2041  } else if (iOSVersion) {2042    if (TvOSVersion || WatchOSVersion) {2043      TheDriver.Diag(diag::err_drv_argument_not_allowed_with)2044          << iOSVersion->getAsString(Args)2045          << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);2046    }2047    return GetDarwinPlatform(Darwin::IPhoneOS, iOSVersion,2048                             iOSVersion->getOption().getID() ==2049                                 options::OPT_mios_simulator_version_min_EQ);2050  } else if (TvOSVersion) {2051    if (WatchOSVersion) {2052      TheDriver.Diag(diag::err_drv_argument_not_allowed_with)2053          << TvOSVersion->getAsString(Args)2054          << WatchOSVersion->getAsString(Args);2055    }2056    return GetDarwinPlatform(Darwin::TvOS, TvOSVersion,2057                             TvOSVersion->getOption().getID() ==2058                                 options::OPT_mtvos_simulator_version_min_EQ);2059  } else if (WatchOSVersion)2060    return GetDarwinPlatform(2061        Darwin::WatchOS, WatchOSVersion,2062        WatchOSVersion->getOption().getID() ==2063            options::OPT_mwatchos_simulator_version_min_EQ);2064  return std::nullopt;2065}2066 2067/// Returns the deployment target that's specified using the2068/// OS_DEPLOYMENT_TARGET environment variable.2069std::optional<DarwinPlatform>2070getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,2071                                            const llvm::Triple &Triple) {2072  std::string Targets[Darwin::LastDarwinPlatform + 1];2073  const char *EnvVars[] = {2074      "MACOSX_DEPLOYMENT_TARGET",2075      "IPHONEOS_DEPLOYMENT_TARGET",2076      "TVOS_DEPLOYMENT_TARGET",2077      "WATCHOS_DEPLOYMENT_TARGET",2078      "DRIVERKIT_DEPLOYMENT_TARGET",2079      "XROS_DEPLOYMENT_TARGET"2080  };2081  static_assert(std::size(EnvVars) == Darwin::LastDarwinPlatform + 1,2082                "Missing platform");2083  for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) {2084    if (char *Env = ::getenv(I.value()))2085      Targets[I.index()] = Env;2086  }2087 2088  // Allow conflicts among OSX and iOS for historical reasons, but choose the2089  // default platform.2090  if (!Targets[Darwin::MacOS].empty() &&2091      (!Targets[Darwin::IPhoneOS].empty() ||2092       !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty() ||2093       !Targets[Darwin::XROS].empty())) {2094    if (Triple.getArch() == llvm::Triple::arm ||2095        Triple.getArch() == llvm::Triple::aarch64 ||2096        Triple.getArch() == llvm::Triple::thumb)2097      Targets[Darwin::MacOS] = "";2098    else2099      Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] =2100          Targets[Darwin::TvOS] = Targets[Darwin::XROS] = "";2101  } else {2102    // Don't allow conflicts in any other platform.2103    unsigned FirstTarget = std::size(Targets);2104    for (unsigned I = 0; I != std::size(Targets); ++I) {2105      if (Targets[I].empty())2106        continue;2107      if (FirstTarget == std::size(Targets))2108        FirstTarget = I;2109      else2110        TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)2111            << Targets[FirstTarget] << Targets[I];2112    }2113  }2114 2115  for (const auto &Target : llvm::enumerate(llvm::ArrayRef(Targets))) {2116    if (!Target.value().empty())2117      return DarwinPlatform::createDeploymentTargetEnv(2118          (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],2119          Target.value());2120  }2121  return std::nullopt;2122}2123 2124/// Returns the SDK name without the optional prefix that ends with a '.' or an2125/// empty string otherwise.2126static StringRef dropSDKNamePrefix(StringRef SDKName) {2127  size_t PrefixPos = SDKName.find('.');2128  if (PrefixPos == StringRef::npos)2129    return "";2130  return SDKName.substr(PrefixPos + 1);2131}2132 2133/// Tries to infer the deployment target from the SDK specified by -isysroot2134/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if2135/// it's available.2136std::optional<DarwinPlatform>2137inferDeploymentTargetFromSDK(DerivedArgList &Args,2138                             const std::optional<DarwinSDKInfo> &SDKInfo) {2139  const Arg *A = Args.getLastArg(options::OPT_isysroot);2140  if (!A)2141    return std::nullopt;2142  StringRef isysroot = A->getValue();2143  StringRef SDK = Darwin::getSDKName(isysroot);2144  if (!SDK.size())2145    return std::nullopt;2146 2147  std::string Version;2148  if (SDKInfo) {2149    // Get the version from the SDKSettings.json if it's available.2150    Version = SDKInfo->getVersion().getAsString();2151  } else {2152    // Slice the version number out.2153    // Version number is between the first and the last number.2154    size_t StartVer = SDK.find_first_of("0123456789");2155    size_t EndVer = SDK.find_last_of("0123456789");2156    if (StartVer != StringRef::npos && EndVer > StartVer)2157      Version = std::string(SDK.slice(StartVer, EndVer + 1));2158  }2159  if (Version.empty())2160    return std::nullopt;2161 2162  auto CreatePlatformFromSDKName =2163      [&](StringRef SDK) -> std::optional<DarwinPlatform> {2164    if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))2165      return DarwinPlatform::createFromSDK(2166          isysroot, Darwin::IPhoneOS, Version,2167          /*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));2168    else if (SDK.starts_with("MacOSX"))2169      return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,2170                                           getSystemOrSDKMacOSVersion(Version));2171    else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))2172      return DarwinPlatform::createFromSDK(2173          isysroot, Darwin::WatchOS, Version,2174          /*IsSimulator=*/SDK.starts_with("WatchSimulator"));2175    else if (SDK.starts_with("AppleTVOS") ||2176             SDK.starts_with("AppleTVSimulator"))2177      return DarwinPlatform::createFromSDK(2178          isysroot, Darwin::TvOS, Version,2179          /*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));2180    else if (SDK.starts_with("XR"))2181      return DarwinPlatform::createFromSDK(2182          isysroot, Darwin::XROS, Version,2183          /*IsSimulator=*/SDK.contains("Simulator"));2184    else if (SDK.starts_with("DriverKit"))2185      return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit,2186                                           Version);2187    return std::nullopt;2188  };2189  if (auto Result = CreatePlatformFromSDKName(SDK))2190    return Result;2191  // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.2192  return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK));2193}2194// Compute & get the OS Version when the target triple omitted one.2195VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,2196                                  const llvm::Triple &Triple,2197                                  const Driver &TheDriver) {2198  VersionTuple OsVersion;2199  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());2200  switch (OS) {2201  case llvm::Triple::Darwin:2202  case llvm::Triple::MacOSX:2203    // If there is no version specified on triple, and both host and target are2204    // macos, use the host triple to infer OS version.2205    if (Triple.isMacOSX() && SystemTriple.isMacOSX() &&2206        !Triple.getOSMajorVersion())2207      SystemTriple.getMacOSXVersion(OsVersion);2208    else if (!Triple.getMacOSXVersion(OsVersion))2209      TheDriver.Diag(diag::err_drv_invalid_darwin_version)2210          << Triple.getOSName();2211    break;2212  case llvm::Triple::IOS:2213    if (Triple.isMacCatalystEnvironment() && !Triple.getOSMajorVersion()) {2214      OsVersion = VersionTuple(13, 1);2215    } else2216      OsVersion = Triple.getiOSVersion();2217    break;2218  case llvm::Triple::TvOS:2219    OsVersion = Triple.getOSVersion();2220    break;2221  case llvm::Triple::WatchOS:2222    OsVersion = Triple.getWatchOSVersion();2223    break;2224  case llvm::Triple::XROS:2225    OsVersion = Triple.getOSVersion();2226    if (!OsVersion.getMajor())2227      OsVersion = OsVersion.withMajorReplaced(1);2228    break;2229  case llvm::Triple::DriverKit:2230    OsVersion = Triple.getDriverKitVersion();2231    break;2232  default:2233    llvm_unreachable("Unexpected OS type");2234    break;2235  }2236  return OsVersion;2237}2238 2239/// Tries to infer the target OS from the -arch.2240std::optional<DarwinPlatform>2241inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,2242                              const llvm::Triple &Triple,2243                              const Driver &TheDriver) {2244  llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;2245 2246  StringRef MachOArchName = Toolchain.getMachOArchName(Args);2247  if (MachOArchName == "arm64" || MachOArchName == "arm64e")2248    OSTy = llvm::Triple::MacOSX;2249  else if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||2250           MachOArchName == "armv6")2251    OSTy = llvm::Triple::IOS;2252  else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32")2253    OSTy = llvm::Triple::WatchOS;2254  else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&2255           MachOArchName != "armv7em")2256    OSTy = llvm::Triple::MacOSX;2257  if (OSTy == llvm::Triple::UnknownOS)2258    return std::nullopt;2259  return DarwinPlatform::createFromArch(2260      MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));2261}2262 2263/// Returns the deployment target that's specified using the -target option.2264std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(2265    DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver,2266    const std::optional<DarwinSDKInfo> &SDKInfo) {2267  if (!Args.hasArg(options::OPT_target))2268    return std::nullopt;2269  if (Triple.getOS() == llvm::Triple::Darwin ||2270      Triple.getOS() == llvm::Triple::UnknownOS)2271    return std::nullopt;2272  std::optional<llvm::Triple> TargetVariantTriple;2273  for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {2274    llvm::Triple TVT(A->getValue());2275    // Find a matching <arch>-<vendor> target variant triple that can be used.2276    if ((Triple.getArch() == llvm::Triple::aarch64 ||2277         TVT.getArchName() == Triple.getArchName()) &&2278        TVT.getArch() == Triple.getArch() &&2279        TVT.getSubArch() == Triple.getSubArch() &&2280        TVT.getVendor() == Triple.getVendor()) {2281      if (TargetVariantTriple)2282        continue;2283      A->claim();2284      // Accept a -target-variant triple when compiling code that may run on2285      // macOS or Mac Catalyst.2286      if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS &&2287           TVT.isMacCatalystEnvironment()) ||2288          (TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS &&2289           Triple.isMacCatalystEnvironment())) {2290        TargetVariantTriple = TVT;2291        continue;2292      }2293      TheDriver.Diag(diag::err_drv_target_variant_invalid)2294          << A->getSpelling() << A->getValue();2295    }2296  }2297  DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget(2298      Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,2299      SDKInfo);2300 2301  return PlatformAndVersion;2302}2303 2304/// Returns the deployment target that's specified using the -mtargetos option.2305std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg(2306    DerivedArgList &Args, const Driver &TheDriver,2307    const std::optional<DarwinSDKInfo> &SDKInfo) {2308  auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);2309  if (!A)2310    return std::nullopt;2311  llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());2312  switch (TT.getOS()) {2313  case llvm::Triple::MacOSX:2314  case llvm::Triple::IOS:2315  case llvm::Triple::TvOS:2316  case llvm::Triple::WatchOS:2317  case llvm::Triple::XROS:2318    break;2319  default:2320    TheDriver.Diag(diag::err_drv_invalid_os_in_arg)2321        << TT.getOSName() << A->getAsString(Args);2322    return std::nullopt;2323  }2324 2325  VersionTuple Version = TT.getOSVersion();2326  if (!Version.getMajor()) {2327    TheDriver.Diag(diag::err_drv_invalid_version_number)2328        << A->getAsString(Args);2329    return std::nullopt;2330  }2331  return DarwinPlatform::createFromMTargetOS(TT.getOS(), Version,2332                                             TT.getEnvironment(), A, SDKInfo);2333}2334 2335std::optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,2336                                              const ArgList &Args,2337                                              const Driver &TheDriver) {2338  const Arg *A = Args.getLastArg(options::OPT_isysroot);2339  if (!A)2340    return std::nullopt;2341  StringRef isysroot = A->getValue();2342  auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot);2343  if (!SDKInfoOrErr) {2344    llvm::consumeError(SDKInfoOrErr.takeError());2345    TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);2346    return std::nullopt;2347  }2348  return *SDKInfoOrErr;2349}2350 2351} // namespace2352 2353void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {2354  const OptTable &Opts = getDriver().getOpts();2355 2356  // Support allowing the SDKROOT environment variable used by xcrun and other2357  // Xcode tools to define the default sysroot, by making it the default for2358  // isysroot.2359  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {2360    // Warn if the path does not exist.2361    if (!getVFS().exists(A->getValue()))2362      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();2363  } else {2364    if (char *env = ::getenv("SDKROOT")) {2365      // We only use this value as the default if it is an absolute path,2366      // exists, and it is not the root path.2367      if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&2368          StringRef(env) != "/") {2369        Args.append(Args.MakeSeparateArg(2370            nullptr, Opts.getOption(options::OPT_isysroot), env));2371      }2372    }2373  }2374 2375  // Read the SDKSettings.json file for more information, like the SDK version2376  // that we can pass down to the compiler.2377  SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());2378 2379  // The OS and the version can be specified using the -target argument.2380  std::optional<DarwinPlatform> PlatformAndVersion =2381      getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);2382  if (PlatformAndVersion) {2383    // Disallow mixing -target and -mtargetos=.2384    if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {2385      std::string TargetArgStr = PlatformAndVersion->getAsString(Args, Opts);2386      std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);2387      getDriver().Diag(diag::err_drv_cannot_mix_options)2388          << TargetArgStr << MTargetOSArgStr;2389    }2390    // Implicitly allow resolving the OS version when it wasn't explicitly set.2391    bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion();2392    if (!TripleProvidedOSVersion)2393      PlatformAndVersion->setOSVersion(2394          getInferredOSVersion(getTriple().getOS(), getTriple(), getDriver()));2395 2396    std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =2397        getDeploymentTargetFromOSVersionArg(Args, getDriver());2398    if (PlatformAndVersionFromOSVersionArg) {2399      unsigned TargetMajor, TargetMinor, TargetMicro;2400      bool TargetExtra;2401      unsigned ArgMajor, ArgMinor, ArgMicro;2402      bool ArgExtra;2403      if (PlatformAndVersion->getPlatform() !=2404              PlatformAndVersionFromOSVersionArg->getPlatform() ||2405          (Driver::GetReleaseVersion(2406               PlatformAndVersion->getOSVersion().getAsString(), TargetMajor,2407               TargetMinor, TargetMicro, TargetExtra) &&2408           Driver::GetReleaseVersion(2409               PlatformAndVersionFromOSVersionArg->getOSVersion().getAsString(),2410               ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&2411           (VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=2412                VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||2413            TargetExtra != ArgExtra))) {2414        // Select the OS version from the -m<os>-version-min argument when2415        // the -target does not include an OS version.2416        if (PlatformAndVersion->getPlatform() ==2417                PlatformAndVersionFromOSVersionArg->getPlatform() &&2418            !TripleProvidedOSVersion) {2419          PlatformAndVersion->setOSVersion(2420              PlatformAndVersionFromOSVersionArg->getOSVersion());2421        } else {2422          // Warn about -m<os>-version-min that doesn't match the OS version2423          // that's specified in the target.2424          std::string OSVersionArg =2425              PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);2426          std::string TargetArg = PlatformAndVersion->getAsString(Args, Opts);2427          getDriver().Diag(clang::diag::warn_drv_overriding_option)2428              << OSVersionArg << TargetArg;2429        }2430      }2431    }2432  } else if ((PlatformAndVersion = getDeploymentTargetFromMTargetOSArg(2433                  Args, getDriver(), SDKInfo))) {2434    // The OS target can be specified using the -mtargetos= argument.2435    // Disallow mixing -mtargetos= and -m<os>version-min=.2436    std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =2437        getDeploymentTargetFromOSVersionArg(Args, getDriver());2438    if (PlatformAndVersionFromOSVersionArg) {2439      std::string MTargetOSArgStr = PlatformAndVersion->getAsString(Args, Opts);2440      std::string OSVersionArgStr =2441          PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);2442      getDriver().Diag(diag::err_drv_cannot_mix_options)2443          << MTargetOSArgStr << OSVersionArgStr;2444    }2445  } else {2446    // The OS target can be specified using the -m<os>version-min argument.2447    PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver());2448    // If no deployment target was specified on the command line, check for2449    // environment defines.2450    if (!PlatformAndVersion) {2451      PlatformAndVersion =2452          getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());2453      if (PlatformAndVersion) {2454        // Don't infer simulator from the arch when the SDK is also specified.2455        std::optional<DarwinPlatform> SDKTarget =2456            inferDeploymentTargetFromSDK(Args, SDKInfo);2457        if (SDKTarget)2458          PlatformAndVersion->setEnvironment(SDKTarget->getEnvironment());2459      }2460    }2461    // If there is no command-line argument to specify the Target version and2462    // no environment variable defined, see if we can set the default based2463    // on -isysroot using SDKSettings.json if it exists.2464    if (!PlatformAndVersion) {2465      PlatformAndVersion = inferDeploymentTargetFromSDK(Args, SDKInfo);2466      /// If the target was successfully constructed from the SDK path, try to2467      /// infer the SDK info if the SDK doesn't have it.2468      if (PlatformAndVersion && !SDKInfo)2469        SDKInfo = PlatformAndVersion->inferSDKInfo();2470    }2471    // If no OS targets have been specified, try to guess platform from -target2472    // or arch name and compute the version from the triple.2473    if (!PlatformAndVersion)2474      PlatformAndVersion =2475          inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());2476  }2477 2478  assert(PlatformAndVersion && "Unable to infer Darwin variant");2479  if (!PlatformAndVersion->isValidOSVersion()) {2480    if (PlatformAndVersion->isExplicitlySpecified())2481      getDriver().Diag(diag::err_drv_invalid_version_number)2482          << PlatformAndVersion->getAsString(Args, Opts);2483    else2484      getDriver().Diag(diag::err_drv_invalid_version_number_inferred)2485          << PlatformAndVersion->getOSVersion().getAsString()2486          << PlatformAndVersion->getInferredSource();2487  }2488  // After the deployment OS version has been resolved, set it to the canonical2489  // version before further error detection and converting to a proper target2490  // triple.2491  VersionTuple CanonicalVersion = PlatformAndVersion->getCanonicalOSVersion();2492  if (CanonicalVersion != PlatformAndVersion->getOSVersion()) {2493    getDriver().Diag(diag::warn_drv_overriding_deployment_version)2494        << PlatformAndVersion->getOSVersion().getAsString()2495        << CanonicalVersion.getAsString();2496    PlatformAndVersion->setOSVersion(CanonicalVersion);2497  }2498 2499  PlatformAndVersion->addOSVersionMinArgument(Args, Opts);2500  DarwinPlatformKind Platform = PlatformAndVersion->getPlatform();2501 2502  unsigned Major, Minor, Micro;2503  bool HadExtra;2504  // The major version should not be over this number.2505  const unsigned MajorVersionLimit = 1000;2506  const VersionTuple OSVersion = PlatformAndVersion->takeOSVersion();2507  const std::string OSVersionStr = OSVersion.getAsString();2508  // Set the tool chain target information.2509  if (Platform == MacOS) {2510    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2511                                   HadExtra) ||2512        HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||2513        Micro >= 100)2514      getDriver().Diag(diag::err_drv_invalid_version_number)2515          << PlatformAndVersion->getAsString(Args, Opts);2516  } else if (Platform == IPhoneOS) {2517    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2518                                   HadExtra) ||2519        HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)2520      getDriver().Diag(diag::err_drv_invalid_version_number)2521          << PlatformAndVersion->getAsString(Args, Opts);2522    ;2523    if (PlatformAndVersion->getEnvironment() == MacCatalyst &&2524        (Major < 13 || (Major == 13 && Minor < 1))) {2525      getDriver().Diag(diag::err_drv_invalid_version_number)2526          << PlatformAndVersion->getAsString(Args, Opts);2527      Major = 13;2528      Minor = 1;2529      Micro = 0;2530    }2531    // For 32-bit targets, the deployment target for iOS has to be earlier than2532    // iOS 11.2533    if (getTriple().isArch32Bit() && Major >= 11) {2534      // If the deployment target is explicitly specified, print a diagnostic.2535      if (PlatformAndVersion->isExplicitlySpecified()) {2536        if (PlatformAndVersion->getEnvironment() == MacCatalyst)2537          getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);2538        else2539          getDriver().Diag(diag::warn_invalid_ios_deployment_target)2540              << PlatformAndVersion->getAsString(Args, Opts);2541        // Otherwise, set it to 10.99.99.2542      } else {2543        Major = 10;2544        Minor = 99;2545        Micro = 99;2546      }2547    }2548  } else if (Platform == TvOS) {2549    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2550                                   HadExtra) ||2551        HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)2552      getDriver().Diag(diag::err_drv_invalid_version_number)2553          << PlatformAndVersion->getAsString(Args, Opts);2554  } else if (Platform == WatchOS) {2555    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2556                                   HadExtra) ||2557        HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)2558      getDriver().Diag(diag::err_drv_invalid_version_number)2559          << PlatformAndVersion->getAsString(Args, Opts);2560  } else if (Platform == DriverKit) {2561    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2562                                   HadExtra) ||2563        HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||2564        Micro >= 100)2565      getDriver().Diag(diag::err_drv_invalid_version_number)2566          << PlatformAndVersion->getAsString(Args, Opts);2567  } else if (Platform == XROS) {2568    if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,2569                                   HadExtra) ||2570        HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||2571        Micro >= 100)2572      getDriver().Diag(diag::err_drv_invalid_version_number)2573          << PlatformAndVersion->getAsString(Args, Opts);2574  } else2575    llvm_unreachable("unknown kind of Darwin platform");2576 2577  DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();2578  // Recognize iOS targets with an x86 architecture as the iOS simulator.2579  if (Environment == NativeEnvironment && Platform != MacOS &&2580      Platform != DriverKit &&2581      PlatformAndVersion->canInferSimulatorFromArch() && getTriple().isX86())2582    Environment = Simulator;2583 2584  VersionTuple ZipperedOSVersion;2585  if (Environment == MacCatalyst)2586    ZipperedOSVersion = PlatformAndVersion->getZipperedOSVersion();2587  setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);2588  TargetVariantTriple = PlatformAndVersion->getTargetVariantTriple();2589  if (TargetVariantTriple &&2590      !llvm::Triple::isValidVersionForOS(TargetVariantTriple->getOS(),2591                                         TargetVariantTriple->getOSVersion())) {2592    getDriver().Diag(diag::err_drv_invalid_version_number)2593        << TargetVariantTriple->str();2594  }2595 2596  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {2597    StringRef SDK = getSDKName(A->getValue());2598    if (SDK.size() > 0) {2599      size_t StartVer = SDK.find_first_of("0123456789");2600      StringRef SDKName = SDK.slice(0, StartVer);2601      if (!SDKName.starts_with(getPlatformFamily()) &&2602          !dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily()))2603        getDriver().Diag(diag::warn_incompatible_sysroot)2604            << SDKName << getPlatformFamily();2605    }2606  }2607}2608 2609// For certain platforms/environments almost all resources (e.g., headers) are2610// located in sub-directories, e.g., for DriverKit they live in2611// <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).2612static void AppendPlatformPrefix(SmallString<128> &Path,2613                                 const llvm::Triple &T) {2614  if (T.isDriverKit()) {2615    llvm::sys::path::append(Path, "System", "DriverKit");2616  }2617}2618 2619// Returns the effective sysroot from either -isysroot or --sysroot, plus the2620// platform prefix (if any).2621llvm::SmallString<128>2622AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {2623  llvm::SmallString<128> Path("/");2624  if (DriverArgs.hasArg(options::OPT_isysroot))2625    Path = DriverArgs.getLastArgValue(options::OPT_isysroot);2626  else if (!getDriver().SysRoot.empty())2627    Path = getDriver().SysRoot;2628 2629  if (hasEffectiveTriple()) {2630    AppendPlatformPrefix(Path, getEffectiveTriple());2631  }2632  return Path;2633}2634 2635void AppleMachO::AddClangSystemIncludeArgs(2636    const llvm::opt::ArgList &DriverArgs,2637    llvm::opt::ArgStringList &CC1Args) const {2638  const Driver &D = getDriver();2639 2640  llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);2641 2642  bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);2643  bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);2644  bool NoBuiltinInc = DriverArgs.hasFlag(2645      options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false);2646  bool ForceBuiltinInc = DriverArgs.hasFlag(2647      options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false);2648 2649  // Add <sysroot>/usr/local/include2650  if (!NoStdInc && !NoStdlibInc) {2651      SmallString<128> P(Sysroot);2652      llvm::sys::path::append(P, "usr", "local", "include");2653      addSystemInclude(DriverArgs, CC1Args, P);2654  }2655 2656  // Add the Clang builtin headers (<resource>/include)2657  if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) {2658    SmallString<128> P(D.ResourceDir);2659    llvm::sys::path::append(P, "include");2660    addSystemInclude(DriverArgs, CC1Args, P);2661  }2662 2663  if (NoStdInc || NoStdlibInc)2664    return;2665 2666  // Check for configure-time C include directories.2667  llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);2668  if (!CIncludeDirs.empty()) {2669    llvm::SmallVector<llvm::StringRef, 5> dirs;2670    CIncludeDirs.split(dirs, ":");2671    for (llvm::StringRef dir : dirs) {2672      llvm::StringRef Prefix =2673          llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot);2674      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);2675    }2676  } else {2677    // Otherwise, add <sysroot>/usr/include.2678    SmallString<128> P(Sysroot);2679    llvm::sys::path::append(P, "usr", "include");2680    addExternCSystemInclude(DriverArgs, CC1Args, P.str());2681  }2682}2683 2684void DarwinClang::AddClangSystemIncludeArgs(2685    const llvm::opt::ArgList &DriverArgs,2686    llvm::opt::ArgStringList &CC1Args) const {2687  AppleMachO::AddClangSystemIncludeArgs(DriverArgs, CC1Args);2688 2689  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc))2690    return;2691 2692  llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);2693 2694  // Add <sysroot>/System/Library/Frameworks2695  // Add <sysroot>/System/Library/SubFrameworks2696  // Add <sysroot>/Library/Frameworks2697  SmallString<128> P1(Sysroot), P2(Sysroot), P3(Sysroot);2698  llvm::sys::path::append(P1, "System", "Library", "Frameworks");2699  llvm::sys::path::append(P2, "System", "Library", "SubFrameworks");2700  llvm::sys::path::append(P3, "Library", "Frameworks");2701  addSystemFrameworkIncludes(DriverArgs, CC1Args, {P1, P2, P3});2702}2703 2704bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,2705                                              llvm::opt::ArgStringList &CC1Args,2706                                              llvm::SmallString<128> Base,2707                                              llvm::StringRef Version,2708                                              llvm::StringRef ArchDir,2709                                              llvm::StringRef BitDir) const {2710  llvm::sys::path::append(Base, Version);2711 2712  // Add the base dir2713  addSystemInclude(DriverArgs, CC1Args, Base);2714 2715  // Add the multilib dirs2716  {2717    llvm::SmallString<128> P = Base;2718    if (!ArchDir.empty())2719      llvm::sys::path::append(P, ArchDir);2720    if (!BitDir.empty())2721      llvm::sys::path::append(P, BitDir);2722    addSystemInclude(DriverArgs, CC1Args, P);2723  }2724 2725  // Add the backward dir2726  {2727    llvm::SmallString<128> P = Base;2728    llvm::sys::path::append(P, "backward");2729    addSystemInclude(DriverArgs, CC1Args, P);2730  }2731 2732  return getVFS().exists(Base);2733}2734 2735void AppleMachO::AddClangCXXStdlibIncludeArgs(2736    const llvm::opt::ArgList &DriverArgs,2737    llvm::opt::ArgStringList &CC1Args) const {2738  // The implementation from a base class will pass through the -stdlib to2739  // CC1Args.2740  // FIXME: this should not be necessary, remove usages in the frontend2741  //        (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.2742  //        Also check whether this is used for setting library search paths.2743  ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);2744 2745  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,2746                        options::OPT_nostdincxx))2747    return;2748 2749  llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);2750 2751  switch (GetCXXStdlibType(DriverArgs)) {2752  case ToolChain::CST_Libcxx: {2753    // On Darwin, libc++ can be installed in one of the following places:2754    // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v12755    // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v12756    //2757    // The precedence of paths is as listed above, i.e. we take the first path2758    // that exists. Note that we never include libc++ twice -- we take the first2759    // path that exists and don't send the other paths to CC1 (otherwise2760    // include_next could break).2761 2762    // Check for (1)2763    // Get from '<install>/bin' to '<install>/include/c++/v1'.2764    // Note that InstallBin can be relative, so we use '..' instead of2765    // parent_path.2766    llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin2767    llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");2768    if (getVFS().exists(InstallBin)) {2769      addSystemInclude(DriverArgs, CC1Args, InstallBin);2770      return;2771    } else if (DriverArgs.hasArg(options::OPT_v)) {2772      llvm::errs() << "ignoring nonexistent directory \"" << InstallBin2773                   << "\"\n";2774    }2775 2776    // Otherwise, check for (2)2777    llvm::SmallString<128> SysrootUsr = Sysroot;2778    llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");2779    if (getVFS().exists(SysrootUsr)) {2780      addSystemInclude(DriverArgs, CC1Args, SysrootUsr);2781      return;2782    } else if (DriverArgs.hasArg(options::OPT_v)) {2783      llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr2784                   << "\"\n";2785    }2786 2787    // Otherwise, don't add any path.2788    break;2789  }2790 2791  case ToolChain::CST_Libstdcxx:2792    AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);2793    break;2794  }2795}2796 2797void AppleMachO::AddGnuCPlusPlusIncludePaths(2798    const llvm::opt::ArgList &DriverArgs,2799    llvm::opt::ArgStringList &CC1Args) const {}2800 2801void DarwinClang::AddGnuCPlusPlusIncludePaths(2802    const llvm::opt::ArgList &DriverArgs,2803    llvm::opt::ArgStringList &CC1Args) const {2804  llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);2805  llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");2806 2807  llvm::Triple::ArchType arch = getTriple().getArch();2808  bool IsBaseFound = true;2809  switch (arch) {2810  default:2811    break;2812 2813  case llvm::Triple::x86:2814  case llvm::Triple::x86_64:2815    IsBaseFound = AddGnuCPlusPlusIncludePaths(2816        DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",2817        arch == llvm::Triple::x86_64 ? "x86_64" : "");2818    IsBaseFound |= AddGnuCPlusPlusIncludePaths(2819        DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");2820    break;2821 2822  case llvm::Triple::arm:2823  case llvm::Triple::thumb:2824    IsBaseFound =2825        AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",2826                                    "arm-apple-darwin10", "v7");2827    IsBaseFound |=2828        AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",2829                                    "arm-apple-darwin10", "v6");2830    break;2831 2832  case llvm::Triple::aarch64:2833    IsBaseFound =2834        AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",2835                                    "arm64-apple-darwin10", "");2836    break;2837  }2838 2839  if (!IsBaseFound) {2840    getDriver().Diag(diag::warn_drv_libstdcxx_not_found);2841  }2842}2843 2844void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,2845                                     ArgStringList &CmdArgs) const {2846  CXXStdlibType Type = GetCXXStdlibType(Args);2847 2848  switch (Type) {2849  case ToolChain::CST_Libcxx:2850    CmdArgs.push_back("-lc++");2851    if (Args.hasArg(options::OPT_fexperimental_library))2852      CmdArgs.push_back("-lc++experimental");2853    break;2854 2855  case ToolChain::CST_Libstdcxx:2856    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;2857    // it was previously found in the gcc lib dir. However, for all the Darwin2858    // platforms we care about it was -lstdc++.6, so we search for that2859    // explicitly if we can't see an obvious -lstdc++ candidate.2860 2861    // Check in the sysroot first.2862    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {2863      SmallString<128> P(A->getValue());2864      llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");2865 2866      if (!getVFS().exists(P)) {2867        llvm::sys::path::remove_filename(P);2868        llvm::sys::path::append(P, "libstdc++.6.dylib");2869        if (getVFS().exists(P)) {2870          CmdArgs.push_back(Args.MakeArgString(P));2871          return;2872        }2873      }2874    }2875 2876    // Otherwise, look in the root.2877    // FIXME: This should be removed someday when we don't have to care about2878    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.2879    if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&2880        getVFS().exists("/usr/lib/libstdc++.6.dylib")) {2881      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");2882      return;2883    }2884 2885    // Otherwise, let the linker search.2886    CmdArgs.push_back("-lstdc++");2887    break;2888  }2889}2890 2891void DarwinClang::AddCCKextLibArgs(const ArgList &Args,2892                                   ArgStringList &CmdArgs) const {2893  // For Darwin platforms, use the compiler-rt-based support library2894  // instead of the gcc-provided one (which is also incidentally2895  // only present in the gcc lib dir, which makes it hard to find).2896 2897  SmallString<128> P(getDriver().ResourceDir);2898  llvm::sys::path::append(P, "lib", "darwin");2899 2900  // Use the newer cc_kext for iOS ARM after 6.0.2901  if (isTargetWatchOS()) {2902    llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");2903  } else if (isTargetTvOS()) {2904    llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");2905  } else if (isTargetIPhoneOS()) {2906    llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");2907  } else if (isTargetDriverKit()) {2908    // DriverKit doesn't want extra runtime support.2909  } else if (isTargetXROSDevice()) {2910    llvm::sys::path::append(2911        P, llvm::Twine("libclang_rt.cc_kext_") +2912               llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a");2913  } else {2914    llvm::sys::path::append(P, "libclang_rt.cc_kext.a");2915  }2916 2917  // For now, allow missing resource libraries to support developers who may2918  // not have compiler-rt checked out or integrated into their build.2919  if (getVFS().exists(P))2920    CmdArgs.push_back(Args.MakeArgString(P));2921}2922 2923DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,2924                                     StringRef BoundArch,2925                                     Action::OffloadKind) const {2926  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());2927  const OptTable &Opts = getDriver().getOpts();2928 2929  // FIXME: We really want to get out of the tool chain level argument2930  // translation business, as it makes the driver functionality much2931  // more opaque. For now, we follow gcc closely solely for the2932  // purpose of easily achieving feature parity & testability. Once we2933  // have something that works, we should reevaluate each translation2934  // and try to push it down into tool specific logic.2935 2936  for (Arg *A : Args) {2937    // Sob. These is strictly gcc compatible for the time being. Apple2938    // gcc translates options twice, which means that self-expanding2939    // options add duplicates.2940    switch ((options::ID)A->getOption().getID()) {2941    default:2942      DAL->append(A);2943      break;2944 2945    case options::OPT_mkernel:2946    case options::OPT_fapple_kext:2947      DAL->append(A);2948      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));2949      break;2950 2951    case options::OPT_dependency_file:2952      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());2953      break;2954 2955    case options::OPT_gfull:2956      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));2957      DAL->AddFlagArg(2958          A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));2959      break;2960 2961    case options::OPT_gused:2962      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));2963      DAL->AddFlagArg(2964          A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));2965      break;2966 2967    case options::OPT_shared:2968      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));2969      break;2970 2971    case options::OPT_fconstant_cfstrings:2972      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));2973      break;2974 2975    case options::OPT_fno_constant_cfstrings:2976      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));2977      break;2978 2979    case options::OPT_Wnonportable_cfstrings:2980      DAL->AddFlagArg(A,2981                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));2982      break;2983 2984    case options::OPT_Wno_nonportable_cfstrings:2985      DAL->AddFlagArg(2986          A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));2987      break;2988    }2989  }2990 2991  // Add the arch options based on the particular spelling of -arch, to match2992  // how the driver works.2993  if (!BoundArch.empty()) {2994    StringRef Name = BoundArch;2995    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);2996    const Option MArch = Opts.getOption(options::OPT_march_EQ);2997 2998    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,2999    // which defines the list of which architectures we accept.3000    if (Name == "ppc")3001      ;3002    else if (Name == "ppc601")3003      DAL->AddJoinedArg(nullptr, MCpu, "601");3004    else if (Name == "ppc603")3005      DAL->AddJoinedArg(nullptr, MCpu, "603");3006    else if (Name == "ppc604")3007      DAL->AddJoinedArg(nullptr, MCpu, "604");3008    else if (Name == "ppc604e")3009      DAL->AddJoinedArg(nullptr, MCpu, "604e");3010    else if (Name == "ppc750")3011      DAL->AddJoinedArg(nullptr, MCpu, "750");3012    else if (Name == "ppc7400")3013      DAL->AddJoinedArg(nullptr, MCpu, "7400");3014    else if (Name == "ppc7450")3015      DAL->AddJoinedArg(nullptr, MCpu, "7450");3016    else if (Name == "ppc970")3017      DAL->AddJoinedArg(nullptr, MCpu, "970");3018 3019    else if (Name == "ppc64" || Name == "ppc64le")3020      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));3021 3022    else if (Name == "i386")3023      ;3024    else if (Name == "i486")3025      DAL->AddJoinedArg(nullptr, MArch, "i486");3026    else if (Name == "i586")3027      DAL->AddJoinedArg(nullptr, MArch, "i586");3028    else if (Name == "i686")3029      DAL->AddJoinedArg(nullptr, MArch, "i686");3030    else if (Name == "pentium")3031      DAL->AddJoinedArg(nullptr, MArch, "pentium");3032    else if (Name == "pentium2")3033      DAL->AddJoinedArg(nullptr, MArch, "pentium2");3034    else if (Name == "pentpro")3035      DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");3036    else if (Name == "pentIIm3")3037      DAL->AddJoinedArg(nullptr, MArch, "pentium2");3038 3039    else if (Name == "x86_64" || Name == "x86_64h")3040      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));3041 3042    else if (Name == "arm")3043      DAL->AddJoinedArg(nullptr, MArch, "armv4t");3044    else if (Name == "armv4t")3045      DAL->AddJoinedArg(nullptr, MArch, "armv4t");3046    else if (Name == "armv5")3047      DAL->AddJoinedArg(nullptr, MArch, "armv5tej");3048    else if (Name == "xscale")3049      DAL->AddJoinedArg(nullptr, MArch, "xscale");3050    else if (Name == "armv6")3051      DAL->AddJoinedArg(nullptr, MArch, "armv6k");3052    else if (Name == "armv6m")3053      DAL->AddJoinedArg(nullptr, MArch, "armv6m");3054    else if (Name == "armv7")3055      DAL->AddJoinedArg(nullptr, MArch, "armv7a");3056    else if (Name == "armv7em")3057      DAL->AddJoinedArg(nullptr, MArch, "armv7em");3058    else if (Name == "armv7k")3059      DAL->AddJoinedArg(nullptr, MArch, "armv7k");3060    else if (Name == "armv7m")3061      DAL->AddJoinedArg(nullptr, MArch, "armv7m");3062    else if (Name == "armv7s")3063      DAL->AddJoinedArg(nullptr, MArch, "armv7s");3064  }3065 3066  return DAL;3067}3068 3069void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,3070                                  ArgStringList &CmdArgs,3071                                  bool ForceLinkBuiltinRT) const {3072  // Embedded targets are simple at the moment, not supporting sanitizers and3073  // with different libraries for each member of the product { static, PIC } x3074  // { hard-float, soft-float }3075  llvm::SmallString<32> CompilerRT = StringRef("");3076  CompilerRT +=3077      (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)3078          ? "hard"3079          : "soft";3080  CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static";3081 3082  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);3083}3084 3085bool Darwin::isAlignedAllocationUnavailable() const {3086  llvm::Triple::OSType OS;3087 3088  if (isTargetMacCatalyst())3089    return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX);3090  switch (TargetPlatform) {3091  case MacOS: // Earlier than 10.13.3092    OS = llvm::Triple::MacOSX;3093    break;3094  case IPhoneOS:3095    OS = llvm::Triple::IOS;3096    break;3097  case TvOS: // Earlier than 11.0.3098    OS = llvm::Triple::TvOS;3099    break;3100  case WatchOS: // Earlier than 4.0.3101    OS = llvm::Triple::WatchOS;3102    break;3103  case XROS: // Always available.3104    return false;3105  case DriverKit: // Always available.3106    return false;3107  }3108 3109  return TargetVersion < alignedAllocMinVersion(OS);3110}3111 3112static bool3113sdkSupportsBuiltinModules(const std::optional<DarwinSDKInfo> &SDKInfo) {3114  if (!SDKInfo)3115    // If there is no SDK info, assume this is building against a3116    // pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those3117    // don't support modules anyway, but the headers definitely3118    // don't support builtin modules either. It might also be some3119    // kind of degenerate build environment, err on the side of3120    // the old behavior which is to not use builtin modules.3121    return false;3122 3123  VersionTuple SDKVersion = SDKInfo->getVersion();3124  switch (SDKInfo->getOS()) {3125  // Existing SDKs added support for builtin modules in the fall3126  // 2024 major releases.3127  case llvm::Triple::MacOSX:3128    return SDKVersion >= VersionTuple(15U);3129  case llvm::Triple::IOS:3130    return SDKVersion >= VersionTuple(18U);3131  case llvm::Triple::TvOS:3132    return SDKVersion >= VersionTuple(18U);3133  case llvm::Triple::WatchOS:3134    return SDKVersion >= VersionTuple(11U);3135  case llvm::Triple::XROS:3136    return SDKVersion >= VersionTuple(2U);3137 3138  // New SDKs support builtin modules from the start.3139  default:3140    return true;3141  }3142}3143 3144static inline llvm::VersionTuple3145sizedDeallocMinVersion(llvm::Triple::OSType OS) {3146  switch (OS) {3147  default:3148    break;3149  case llvm::Triple::Darwin:3150  case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.3151    return llvm::VersionTuple(10U, 12U);3152  case llvm::Triple::IOS:3153  case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0.3154    return llvm::VersionTuple(10U);3155  case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0.3156    return llvm::VersionTuple(3U);3157  }3158 3159  llvm_unreachable("Unexpected OS");3160}3161 3162bool Darwin::isSizedDeallocationUnavailable() const {3163  llvm::Triple::OSType OS;3164 3165  if (isTargetMacCatalyst())3166    return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX);3167  switch (TargetPlatform) {3168  case MacOS: // Earlier than 10.12.3169    OS = llvm::Triple::MacOSX;3170    break;3171  case IPhoneOS:3172    OS = llvm::Triple::IOS;3173    break;3174  case TvOS: // Earlier than 10.0.3175    OS = llvm::Triple::TvOS;3176    break;3177  case WatchOS: // Earlier than 3.0.3178    OS = llvm::Triple::WatchOS;3179    break;3180  case DriverKit:3181  case XROS:3182    // Always available.3183    return false;3184  }3185 3186  return TargetVersion < sizedDeallocMinVersion(OS);3187}3188 3189void MachO::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,3190                                  llvm::opt::ArgStringList &CC1Args,3191                                  Action::OffloadKind DeviceOffloadKind) const {3192 3193  ToolChain::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);3194 3195  // On arm64e, we enable all the features required for the Darwin userspace3196  // ABI3197  if (getTriple().isArm64e()) {3198    // Core platform ABI3199    if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,3200                           options::OPT_fno_ptrauth_calls))3201      CC1Args.push_back("-fptrauth-calls");3202    if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,3203                           options::OPT_fno_ptrauth_returns))3204      CC1Args.push_back("-fptrauth-returns");3205    if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,3206                           options::OPT_fno_ptrauth_intrinsics))3207      CC1Args.push_back("-fptrauth-intrinsics");3208    if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos,3209                           options::OPT_fno_ptrauth_indirect_gotos))3210      CC1Args.push_back("-fptrauth-indirect-gotos");3211    if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,3212                           options::OPT_fno_ptrauth_auth_traps))3213      CC1Args.push_back("-fptrauth-auth-traps");3214 3215    // C++ v-table ABI3216    if (!DriverArgs.hasArg(3217            options::OPT_fptrauth_vtable_pointer_address_discrimination,3218            options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))3219      CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");3220    if (!DriverArgs.hasArg(3221            options::OPT_fptrauth_vtable_pointer_type_discrimination,3222            options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))3223      CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");3224 3225    // Objective-C ABI3226    if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_isa,3227                           options::OPT_fno_ptrauth_objc_isa))3228      CC1Args.push_back("-fptrauth-objc-isa");3229    if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_class_ro,3230                           options::OPT_fno_ptrauth_objc_class_ro))3231      CC1Args.push_back("-fptrauth-objc-class-ro");3232    if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_interface_sel,3233                           options::OPT_fno_ptrauth_objc_interface_sel))3234      CC1Args.push_back("-fptrauth-objc-interface-sel");3235  }3236}3237 3238void Darwin::addClangTargetOptions(3239    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,3240    Action::OffloadKind DeviceOffloadKind) const {3241 3242  MachO::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);3243 3244  // Pass "-faligned-alloc-unavailable" only when the user hasn't manually3245  // enabled or disabled aligned allocations.3246  if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,3247                                options::OPT_fno_aligned_allocation) &&3248      isAlignedAllocationUnavailable())3249    CC1Args.push_back("-faligned-alloc-unavailable");3250 3251  // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled3252  // or disabled sized deallocations.3253  if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,3254                                options::OPT_fno_sized_deallocation) &&3255      isSizedDeallocationUnavailable())3256    CC1Args.push_back("-fno-sized-deallocation");3257 3258  addClangCC1ASTargetOptions(DriverArgs, CC1Args);3259 3260  // Enable compatibility mode for NSItemProviderCompletionHandler in3261  // Foundation/NSItemProvider.h.3262  CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking");3263 3264  // Give static local variables in inline functions hidden visibility when3265  // -fvisibility-inlines-hidden is enabled.3266  if (!DriverArgs.getLastArgNoClaim(3267          options::OPT_fvisibility_inlines_hidden_static_local_var,3268          options::OPT_fno_visibility_inlines_hidden_static_local_var))3269    CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");3270 3271  // Earlier versions of the darwin SDK have the C standard library headers3272  // all together in the Darwin module. That leads to module cycles with3273  // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.3274  // The builtin <stdint.h> include-nexts <stdint.h>. When both of those3275  // darwin headers are in the Darwin module, there's a module cycle Darwin ->3276  // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->3277  // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,3278  // but until then, the builtin headers need to join the system modules.3279  // i.e. when the builtin stdint.h is in the Darwin module too, the cycle3280  // goes away. Note that -fbuiltin-headers-in-system-modules does nothing3281  // to fix the same problem with C++ headers, and is generally fragile.3282  if (!sdkSupportsBuiltinModules(SDKInfo))3283    CC1Args.push_back("-fbuiltin-headers-in-system-modules");3284 3285  if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros,3286                                options::OPT_fno_define_target_os_macros))3287    CC1Args.push_back("-fdefine-target-os-macros");3288 3289  // Disable subdirectory modulemap search on sufficiently recent SDKs.3290  if (SDKInfo &&3291      !DriverArgs.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search,3292                          options::OPT_fno_modulemap_allow_subdirectory_search,3293                          false)) {3294    bool RequiresSubdirectorySearch;3295    VersionTuple SDKVersion = SDKInfo->getVersion();3296    switch (TargetPlatform) {3297    default:3298      RequiresSubdirectorySearch = true;3299      break;3300    case MacOS:3301      RequiresSubdirectorySearch = SDKVersion < VersionTuple(15, 0);3302      break;3303    case IPhoneOS:3304    case TvOS:3305      RequiresSubdirectorySearch = SDKVersion < VersionTuple(18, 0);3306      break;3307    case WatchOS:3308      RequiresSubdirectorySearch = SDKVersion < VersionTuple(11, 0);3309      break;3310    case XROS:3311      RequiresSubdirectorySearch = SDKVersion < VersionTuple(2, 0);3312      break;3313    }3314    if (!RequiresSubdirectorySearch)3315      CC1Args.push_back("-fno-modulemap-allow-subdirectory-search");3316  }3317}3318 3319void Darwin::addClangCC1ASTargetOptions(3320    const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const {3321  if (TargetVariantTriple) {3322    CC1ASArgs.push_back("-darwin-target-variant-triple");3323    CC1ASArgs.push_back(Args.MakeArgString(TargetVariantTriple->getTriple()));3324  }3325 3326  if (SDKInfo) {3327    /// Pass the SDK version to the compiler when the SDK information is3328    /// available.3329    auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) {3330      std::string Arg;3331      llvm::raw_string_ostream OS(Arg);3332      OS << "-target-sdk-version=" << V;3333      CC1ASArgs.push_back(Args.MakeArgString(Arg));3334    };3335 3336    if (isTargetMacCatalyst()) {3337      if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(3338              DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {3339        std::optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(3340            SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(),3341            std::nullopt);3342        EmitTargetSDKVersionArg(3343            SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget());3344      }3345    } else {3346      EmitTargetSDKVersionArg(SDKInfo->getVersion());3347    }3348 3349    /// Pass the target variant SDK version to the compiler when the SDK3350    /// information is available and is required for target variant.3351    if (TargetVariantTriple) {3352      if (isTargetMacCatalyst()) {3353        std::string Arg;3354        llvm::raw_string_ostream OS(Arg);3355        OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();3356        CC1ASArgs.push_back(Args.MakeArgString(Arg));3357      } else if (const auto *MacOStoMacCatalystMapping =3358                     SDKInfo->getVersionMapping(3359                         DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {3360        if (std::optional<VersionTuple> SDKVersion =3361                MacOStoMacCatalystMapping->map(3362                    SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(),3363                    std::nullopt)) {3364          std::string Arg;3365          llvm::raw_string_ostream OS(Arg);3366          OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;3367          CC1ASArgs.push_back(Args.MakeArgString(Arg));3368        }3369      }3370    }3371  }3372}3373 3374DerivedArgList *3375Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,3376                      Action::OffloadKind DeviceOffloadKind) const {3377  // First get the generic Apple args, before moving onto Darwin-specific ones.3378  DerivedArgList *DAL =3379      MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);3380 3381  // If no architecture is bound, none of the translations here are relevant.3382  if (BoundArch.empty())3383    return DAL;3384 3385  // Add an explicit version min argument for the deployment target. We do this3386  // after argument translation because -Xarch_ arguments may add a version min3387  // argument.3388  AddDeploymentTarget(*DAL);3389 3390  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.3391  // FIXME: It would be far better to avoid inserting those -static arguments,3392  // but we can't check the deployment target in the translation code until3393  // it is set here.3394  if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS() ||3395      (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {3396    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {3397      Arg *A = *it;3398      ++it;3399      if (A->getOption().getID() != options::OPT_mkernel &&3400          A->getOption().getID() != options::OPT_fapple_kext)3401        continue;3402      assert(it != ie && "unexpected argument translation");3403      A = *it;3404      assert(A->getOption().getID() == options::OPT_static &&3405             "missing expected -static argument");3406      *it = nullptr;3407      ++it;3408    }3409  }3410 3411  auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch);3412  if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {3413    if (Args.hasFlag(options::OPT_fomit_frame_pointer,3414                     options::OPT_fno_omit_frame_pointer, false))3415      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)3416          << "-fomit-frame-pointer" << BoundArch;3417  }3418 3419  return DAL;3420}3421 3422ToolChain::UnwindTableLevel MachO::getDefaultUnwindTableLevel(const ArgList &Args) const {3423  // Unwind tables are not emitted if -fno-exceptions is supplied (except when3424  // targeting x86_64).3425  if (getArch() == llvm::Triple::x86_64 ||3426      (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&3427       Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,3428                    true)))3429    return (getArch() == llvm::Triple::aarch64 ||3430            getArch() == llvm::Triple::aarch64_32)3431               ? UnwindTableLevel::Synchronous3432               : UnwindTableLevel::Asynchronous;3433 3434  return UnwindTableLevel::None;3435}3436 3437bool MachO::UseDwarfDebugFlags() const {3438  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))3439    return S[0] != '\0';3440  return false;3441}3442 3443std::string MachO::GetGlobalDebugPathRemapping() const {3444  if (const char *S = ::getenv("RC_DEBUG_PREFIX_MAP"))3445    return S;3446  return {};3447}3448 3449llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {3450  // Darwin uses SjLj exceptions on ARM.3451  if (getTriple().getArch() != llvm::Triple::arm &&3452      getTriple().getArch() != llvm::Triple::thumb)3453    return llvm::ExceptionHandling::None;3454 3455  // Only watchOS uses the new DWARF/Compact unwinding method.3456  llvm::Triple Triple(ComputeLLVMTriple(Args));3457  if (Triple.isWatchABI())3458    return llvm::ExceptionHandling::DwarfCFI;3459 3460  return llvm::ExceptionHandling::SjLj;3461}3462 3463bool Darwin::SupportsEmbeddedBitcode() const {3464  assert(TargetInitialized && "Target not initialized!");3465  if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))3466    return false;3467  return true;3468}3469 3470bool MachO::isPICDefault() const { return true; }3471 3472bool MachO::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; }3473 3474bool MachO::isPICDefaultForced() const {3475  return (getArch() == llvm::Triple::x86_64 ||3476          getArch() == llvm::Triple::aarch64);3477}3478 3479bool MachO::SupportsProfiling() const {3480  // Profiling instrumentation is only supported on x86.3481  return getTriple().isX86();3482}3483 3484void Darwin::addMinVersionArgs(const ArgList &Args,3485                               ArgStringList &CmdArgs) const {3486  VersionTuple TargetVersion = getTripleTargetVersion();3487 3488  assert(!isTargetXROS() && "xrOS always uses -platform-version");3489 3490  if (isTargetWatchOS())3491    CmdArgs.push_back("-watchos_version_min");3492  else if (isTargetWatchOSSimulator())3493    CmdArgs.push_back("-watchos_simulator_version_min");3494  else if (isTargetTvOS())3495    CmdArgs.push_back("-tvos_version_min");3496  else if (isTargetTvOSSimulator())3497    CmdArgs.push_back("-tvos_simulator_version_min");3498  else if (isTargetDriverKit())3499    CmdArgs.push_back("-driverkit_version_min");3500  else if (isTargetIOSSimulator())3501    CmdArgs.push_back("-ios_simulator_version_min");3502  else if (isTargetIOSBased())3503    CmdArgs.push_back("-iphoneos_version_min");3504  else if (isTargetMacCatalyst())3505    CmdArgs.push_back("-maccatalyst_version_min");3506  else {3507    assert(isTargetMacOS() && "unexpected target");3508    CmdArgs.push_back("-macosx_version_min");3509  }3510 3511  VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();3512  if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)3513    TargetVersion = MinTgtVers;3514  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));3515  if (TargetVariantTriple) {3516    assert(isTargetMacOSBased() && "unexpected target");3517    VersionTuple VariantTargetVersion;3518    if (TargetVariantTriple->isMacOSX()) {3519      CmdArgs.push_back("-macosx_version_min");3520      TargetVariantTriple->getMacOSXVersion(VariantTargetVersion);3521    } else {3522      assert(TargetVariantTriple->isiOS() &&3523             TargetVariantTriple->isMacCatalystEnvironment() &&3524             "unexpected target variant triple");3525      CmdArgs.push_back("-maccatalyst_version_min");3526      VariantTargetVersion = TargetVariantTriple->getiOSVersion();3527    }3528    VersionTuple MinTgtVers =3529        TargetVariantTriple->getMinimumSupportedOSVersion();3530    if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion)3531      VariantTargetVersion = MinTgtVers;3532    CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString()));3533  }3534}3535 3536static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,3537                                   Darwin::DarwinEnvironmentKind Environment) {3538  switch (Platform) {3539  case Darwin::MacOS:3540    return "macos";3541  case Darwin::IPhoneOS:3542    if (Environment == Darwin::MacCatalyst)3543      return "mac catalyst";3544    return "ios";3545  case Darwin::TvOS:3546    return "tvos";3547  case Darwin::WatchOS:3548    return "watchos";3549  case Darwin::XROS:3550    return "xros";3551  case Darwin::DriverKit:3552    return "driverkit";3553  }3554  llvm_unreachable("invalid platform");3555}3556 3557void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,3558                                    llvm::opt::ArgStringList &CmdArgs) const {3559  auto EmitPlatformVersionArg =3560      [&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,3561          Darwin::DarwinEnvironmentKind TargetEnvironment,3562          const llvm::Triple &TT) {3563        // -platform_version <platform> <target_version> <sdk_version>3564        // Both the target and SDK version support only up to 3 components.3565        CmdArgs.push_back("-platform_version");3566        std::string PlatformName =3567            getPlatformName(TargetPlatform, TargetEnvironment);3568        if (TargetEnvironment == Darwin::Simulator)3569          PlatformName += "-simulator";3570        CmdArgs.push_back(Args.MakeArgString(PlatformName));3571        VersionTuple TargetVersion = TV.withoutBuild();3572        if ((TargetPlatform == Darwin::IPhoneOS ||3573             TargetPlatform == Darwin::TvOS) &&3574            getTriple().getArchName() == "arm64e" &&3575            TargetVersion.getMajor() < 14) {3576          // arm64e slice is supported on iOS/tvOS 14+ only.3577          TargetVersion = VersionTuple(14, 0);3578        }3579        VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion();3580        if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)3581          TargetVersion = MinTgtVers;3582        CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));3583 3584        if (TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst) {3585          // Mac Catalyst programs must use the appropriate iOS SDK version3586          // that corresponds to the macOS SDK version used for the compilation.3587          std::optional<VersionTuple> iOSSDKVersion;3588          if (SDKInfo) {3589            if (const auto *MacOStoMacCatalystMapping =3590                    SDKInfo->getVersionMapping(3591                        DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {3592              iOSSDKVersion = MacOStoMacCatalystMapping->map(3593                  SDKInfo->getVersion().withoutBuild(),3594                  minimumMacCatalystDeploymentTarget(), std::nullopt);3595            }3596          }3597          CmdArgs.push_back(Args.MakeArgString(3598              (iOSSDKVersion ? *iOSSDKVersion3599                             : minimumMacCatalystDeploymentTarget())3600                  .getAsString()));3601          return;3602        }3603 3604        if (SDKInfo) {3605          VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();3606          if (!SDKVersion.getMinor())3607            SDKVersion = VersionTuple(SDKVersion.getMajor(), 0);3608          CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));3609        } else {3610          // Use an SDK version that's matching the deployment target if the SDK3611          // version is missing. This is preferred over an empty SDK version3612          // (0.0.0) as the system's runtime might expect the linked binary to3613          // contain a valid SDK version in order for the binary to work3614          // correctly. It's reasonable to use the deployment target version as3615          // a proxy for the SDK version because older SDKs don't guarantee3616          // support for deployment targets newer than the SDK versions, so that3617          // rules out using some predetermined older SDK version, which leaves3618          // the deployment target version as the only reasonable choice.3619          CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));3620        }3621      };3622  EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform,3623                         TargetEnvironment, getEffectiveTriple());3624  if (!TargetVariantTriple)3625    return;3626  Darwin::DarwinPlatformKind Platform;3627  Darwin::DarwinEnvironmentKind Environment;3628  VersionTuple TargetVariantVersion;3629  if (TargetVariantTriple->isMacOSX()) {3630    TargetVariantTriple->getMacOSXVersion(TargetVariantVersion);3631    Platform = Darwin::MacOS;3632    Environment = Darwin::NativeEnvironment;3633  } else {3634    assert(TargetVariantTriple->isiOS() &&3635           TargetVariantTriple->isMacCatalystEnvironment() &&3636           "unexpected target variant triple");3637    TargetVariantVersion = TargetVariantTriple->getiOSVersion();3638    Platform = Darwin::IPhoneOS;3639    Environment = Darwin::MacCatalyst;3640  }3641  EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment,3642                         *TargetVariantTriple);3643}3644 3645// Add additional link args for the -dynamiclib option.3646static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args,3647                                  ArgStringList &CmdArgs) {3648  // Derived from darwin_dylib1 spec.3649  if (D.isTargetIPhoneOS()) {3650    if (D.isIPhoneOSVersionLT(3, 1))3651      CmdArgs.push_back("-ldylib1.o");3652    return;3653  }3654 3655  if (!D.isTargetMacOS())3656    return;3657  if (D.isMacosxVersionLT(10, 5))3658    CmdArgs.push_back("-ldylib1.o");3659  else if (D.isMacosxVersionLT(10, 6))3660    CmdArgs.push_back("-ldylib1.10.5.o");3661}3662 3663// Add additional link args for the -bundle option.3664static void addBundleLinkArgs(const Darwin &D, const ArgList &Args,3665                              ArgStringList &CmdArgs) {3666  if (Args.hasArg(options::OPT_static))3667    return;3668  // Derived from darwin_bundle1 spec.3669  if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) ||3670      (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6)))3671    CmdArgs.push_back("-lbundle1.o");3672}3673 3674// Add additional link args for the -pg option.3675static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,3676                                   ArgStringList &CmdArgs) {3677  if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) {3678    if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) ||3679        Args.hasArg(options::OPT_preload)) {3680      CmdArgs.push_back("-lgcrt0.o");3681    } else {3682      CmdArgs.push_back("-lgcrt1.o");3683 3684      // darwin_crt2 spec is empty.3685    }3686    // By default on OS X 10.8 and later, we don't link with a crt1.o3687    // file and the linker knows to use _main as the entry point.  But,3688    // when compiling with -pg, we need to link with the gcrt1.o file,3689    // so pass the -no_new_main option to tell the linker to use the3690    // "start" symbol as the entry point.3691    if (!D.isMacosxVersionLT(10, 8))3692      CmdArgs.push_back("-no_new_main");3693  } else {3694    D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)3695        << D.isTargetMacOSBased();3696  }3697}3698 3699static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args,3700                                  ArgStringList &CmdArgs) {3701  // Derived from darwin_crt1 spec.3702  if (D.isTargetIPhoneOS()) {3703    if (D.getArch() == llvm::Triple::aarch64)3704      ; // iOS does not need any crt1 files for arm643705    else if (D.isIPhoneOSVersionLT(3, 1))3706      CmdArgs.push_back("-lcrt1.o");3707    else if (D.isIPhoneOSVersionLT(6, 0))3708      CmdArgs.push_back("-lcrt1.3.1.o");3709    return;3710  }3711 3712  if (!D.isTargetMacOS())3713    return;3714  if (D.isMacosxVersionLT(10, 5))3715    CmdArgs.push_back("-lcrt1.o");3716  else if (D.isMacosxVersionLT(10, 6))3717    CmdArgs.push_back("-lcrt1.10.5.o");3718  else if (D.isMacosxVersionLT(10, 8))3719    CmdArgs.push_back("-lcrt1.10.6.o");3720  // darwin_crt2 spec is empty.3721}3722 3723void Darwin::addStartObjectFileArgs(const ArgList &Args,3724                                    ArgStringList &CmdArgs) const {3725  // Derived from startfile spec.3726  if (Args.hasArg(options::OPT_dynamiclib))3727    addDynamicLibLinkArgs(*this, Args, CmdArgs);3728  else if (Args.hasArg(options::OPT_bundle))3729    addBundleLinkArgs(*this, Args, CmdArgs);3730  else if (Args.hasArg(options::OPT_pg) && SupportsProfiling())3731    addPgProfilingLinkArgs(*this, Args, CmdArgs);3732  else if (Args.hasArg(options::OPT_static) ||3733           Args.hasArg(options::OPT_object) ||3734           Args.hasArg(options::OPT_preload))3735    CmdArgs.push_back("-lcrt0.o");3736  else3737    addDefaultCRTLinkArgs(*this, Args, CmdArgs);3738 3739  if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) &&3740      isMacosxVersionLT(10, 5)) {3741    const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));3742    CmdArgs.push_back(Str);3743  }3744}3745 3746void Darwin::CheckObjCARC() const {3747  if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() ||3748      (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)))3749    return;3750  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);3751}3752 3753SanitizerMask Darwin::getSupportedSanitizers() const {3754  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;3755  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;3756  SanitizerMask Res = ToolChain::getSupportedSanitizers();3757  Res |= SanitizerKind::Address;3758  Res |= SanitizerKind::PointerCompare;3759  Res |= SanitizerKind::PointerSubtract;3760  Res |= SanitizerKind::Realtime;3761  Res |= SanitizerKind::Leak;3762  Res |= SanitizerKind::Fuzzer;3763  Res |= SanitizerKind::FuzzerNoLink;3764  Res |= SanitizerKind::ObjCCast;3765 3766  // Prior to 10.9, macOS shipped a version of the C++ standard library without3767  // C++11 support. The same is true of iOS prior to version 5. These OS'es are3768  // incompatible with -fsanitize=vptr.3769  if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&3770      !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))3771    Res |= SanitizerKind::Vptr;3772 3773  if ((IsX86_64 || IsAArch64) &&3774      (isTargetMacOSBased() || isTargetIOSSimulator() ||3775       isTargetTvOSSimulator() || isTargetWatchOSSimulator())) {3776    Res |= SanitizerKind::Thread;3777  }3778 3779  if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {3780    Res |= SanitizerKind::Type;3781  }3782 3783  if (IsX86_64)3784    Res |= SanitizerKind::NumericalStability;3785 3786  return Res;3787}3788 3789void AppleMachO::printVerboseInfo(raw_ostream &OS) const {3790  CudaInstallation->print(OS);3791  RocmInstallation->print(OS);3792}3793