Coverage Report

Created: 2020-11-24 06:42

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