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