Coverage Report

Created: 2023-09-21 18:56

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