Coverage Report

Created: 2024-01-17 10:31

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