Coverage Report

Created: 2020-09-15 12:33

/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
58.7k
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
58.7k
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
58.7k
46
  // This code must be kept in sync with Clang's Darwin specific argument
47
  // translation.
48
58.7k
49
58.7k
  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
50
58.7k
      .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
51
58.7k
      .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
52
58.7k
      .Case("ppc64", llvm::Triple::ppc64)
53
58.7k
      .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
54
58.7k
      .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
55
58.7k
             llvm::Triple::x86)
56
58.7k
      .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
57
      // This is derived from the driver driver.
58
58.7k
      .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
59
58.7k
      .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
60
58.7k
      .Cases("armv7s", "xscale", llvm::Triple::arm)
61
58.7k
      .Case("arm64", llvm::Triple::aarch64)
62
58.7k
      .Case("arm64_32", llvm::Triple::aarch64_32)
63
58.7k
      .Case("r600", llvm::Triple::r600)
64
58.7k
      .Case("amdgcn", llvm::Triple::amdgcn)
65
58.7k
      .Case("nvptx", llvm::Triple::nvptx)
66
58.7k
      .Case("nvptx64", llvm::Triple::nvptx64)
67
58.7k
      .Case("amdil", llvm::Triple::amdil)
68
58.7k
      .Case("spir", llvm::Triple::spir)
69
58.7k
      .Default(llvm::Triple::UnknownArch);
70
58.7k
}
71
72
29.3k
void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
73
29.3k
  const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
74
29.3k
  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str);
75
29.3k
  T.setArch(Arch);
76
29.3k
77
29.3k
  if (Str == "x86_64h")
78
16
    T.setArchName(Str);
79
29.3k
  else if (ArchKind == llvm::ARM::ArchKind::ARMV6M ||
80
29.3k
           ArchKind == llvm::ARM::ArchKind::ARMV7M ||
81
29.3k
           ArchKind == llvm::ARM::ArchKind::ARMV7EM) {
82
47
    T.setOS(llvm::Triple::UnknownOS);
83
47
    T.setObjectFormat(llvm::Triple::MachO);
84
47
  }
85
29.3k
}
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
10
94
10
  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
95
10
  const InputInfo &Input = Inputs[0];
96
10
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
10
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
10
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
10
124
  // Derived from asm spec.
125
10
  AddMachOArch(Args, CmdArgs);
126
10
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
10
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
10
139
10
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
140
10
141
10
  assert(Output.isFilename() && "Unexpected lipo output.");
142
10
  CmdArgs.push_back("-o");
143
10
  CmdArgs.push_back(Output.getFilename());
144
10
145
10
  assert(Input.isFilename() && "Invalid input.");
146
10
  CmdArgs.push_back(Input.getFilename());
147
10
148
  // asm_final spec is empty.
149
10
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));
153
10
}
154
155
0
void darwin::MachOTool::anchor() {}
156
157
void darwin::MachOTool::AddMachOArch(const ArgList &Args,
158
3.44k
                                     ArgStringList &CmdArgs) const {
159
3.44k
  StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
160
3.44k
161
  // Derived from darwin_arch spec.
162
3.44k
  CmdArgs.push_back("-arch");
163
3.44k
  CmdArgs.push_back(Args.MakeArgString(ArchName));
164
3.44k
165
  // FIXME: Is this needed anymore?
166
3.44k
  if (ArchName == "arm")
167
0
    CmdArgs.push_back("-force_cpusubtype_ALL");
168
3.44k
}
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
15
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.41k
static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
189
3.41k
  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
190
2.69k
    if (A->getOption().matches(options::OPT_O0))
191
2.58k
      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
722
199
722
  if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.
200
583
    return true;
201
139
  return false;
202
139
}
203
204
void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
205
                                 ArgStringList &CmdArgs,
206
                                 const InputInfoList &Inputs,
207
3.43k
                                 unsigned Version[5]) const {
208
3.43k
  const Driver &D = getToolChain().getDriver();
209
3.43k
  const toolchains::MachO &MachOTC = getMachOToolChain();
210
3.43k
211
  // Newer linkers support -demangle. Pass it if supported and not disabled by
212
  // the user.
213
3.43k
  if (Version[0] >= 100 && 
!Args.hasArg(options::OPT_Z_Xlinker__no_demangle)3.42k
)
214
3.42k
    CmdArgs.push_back("-demangle");
215
3.43k
216
3.43k
  if (Args.hasArg(options::OPT_rdynamic) && 
Version[0] >= 1372
)
217
1
    CmdArgs.push_back("-export_dynamic");
218
3.43k
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.43k
  if (Args.hasFlag(options::OPT_fapplication_extension,
222
3.43k
                   options::OPT_fno_application_extension, false))
223
0
    CmdArgs.push_back("-application_extension");
224
3.43k
225
3.43k
  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
15
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
3.43k
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.43k
  if (Version[0] >= 133) {
253
    // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
254
3.42k
    StringRef P = llvm::sys::path::parent_path(D.Dir);
255
3.42k
    SmallString<128> LibLTOPath(P);
256
3.42k
    llvm::sys::path::append(LibLTOPath, "lib");
257
3.42k
    llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
258
3.42k
    CmdArgs.push_back("-lto_library");
259
3.42k
    CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
260
3.42k
  }
261
3.43k
262
  // ld64 version 262 and above run the deduplicate pass by default.
263
3.43k
  if (Version[0] >= 262 && 
shouldLinkerNotDedup(C.getJobs().empty(), Args)3.41k
)
264
3.18k
    CmdArgs.push_back("-no_deduplicate");
265
3.43k
266
  // Derived from the "link" spec.
267
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_static);
268
3.43k
  if (!Args.hasArg(options::OPT_static))
269
3.42k
    CmdArgs.push_back("-dynamic");
270
3.43k
  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
3.43k
275
3.43k
  if (!Args.hasArg(options::OPT_dynamiclib)) {
276
3.24k
    AddMachOArch(Args, CmdArgs);
277
    // FIXME: Why do this only on this path?
278
3.24k
    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
279
3.24k
280
3.24k
    Args.AddLastArg(CmdArgs, options::OPT_bundle);
281
3.24k
    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
282
3.24k
    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
283
3.24k
284
3.24k
    Arg *A;
285
3.24k
    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
286
3.24k
        (A = Args.getLastArg(options::OPT_current__version)) ||
287
3.24k
        (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
3.24k
291
3.24k
    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
292
3.24k
    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
293
3.24k
    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
294
190
  } else {
295
190
    CmdArgs.push_back("-dylib");
296
190
297
190
    Arg *A;
298
190
    if ((A = Args.getLastArg(options::OPT_bundle)) ||
299
190
        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
300
190
        (A = Args.getLastArg(options::OPT_client__name)) ||
301
190
        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
302
190
        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
303
190
        (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
190
307
190
    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
308
190
                              "-dylib_compatibility_version");
309
190
    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
310
190
                              "-dylib_current_version");
311
190
312
190
    AddMachOArch(Args, CmdArgs);
313
190
314
190
    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
315
190
                              "-dylib_install_name");
316
190
  }
317
3.43k
318
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_all__load);
319
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
320
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
321
3.43k
  if (MachOTC.isTargetIOSBased())
322
0
    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
323
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
324
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
325
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
326
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
327
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
328
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
329
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_force__load);
330
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
331
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
332
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_init);
333
3.43k
334
  // Add the deployment target.
335
3.43k
  if (Version[0] >= 520)
336
3.34k
    MachOTC.addPlatformVersionArgs(Args, CmdArgs);
337
85
  else
338
85
    MachOTC.addMinVersionArgs(Args, CmdArgs);
339
3.43k
340
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
341
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
342
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_single__module);
343
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
344
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
345
3.43k
346
3.43k
  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
3.43k
356
  // for embed-bitcode, use -bitcode_bundle in linker command
357
3.43k
  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
3.43k
369
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_prebind);
370
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
371
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
372
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
373
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
374
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
375
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
376
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
377
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
378
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
379
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
380
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
381
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
382
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
383
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
384
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
385
3.43k
386
  // Give --sysroot= preference, over the Apple specific behavior to also use
387
  // --isysroot as the syslibroot.
388
3.43k
  StringRef sysroot = C.getSysRoot();
389
3.43k
  if (sysroot != "") {
390
8
    CmdArgs.push_back("-syslibroot");
391
8
    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
392
3.42k
  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
393
2.77k
    CmdArgs.push_back("-syslibroot");
394
2.77k
    CmdArgs.push_back(A->getValue());
395
2.77k
  }
396
3.43k
397
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
398
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
399
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
400
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
401
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
402
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
403
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
404
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_y);
405
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_w);
406
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
407
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
408
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
409
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
410
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
411
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
412
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
413
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_whyload);
414
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
415
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
416
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
417
3.43k
  Args.AddLastArg(CmdArgs, options::OPT_Mach);
418
3.43k
}
419
420
/// Determine whether we are linking the ObjC runtime.
421
3.43k
static bool isObjCRuntimeLinked(const ArgList &Args) {
422
3.43k
  if (isObjCAutoRefCount(Args)) {
423
1
    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
424
1
    return true;
425
1
  }
426
3.43k
  return Args.hasArg(options::OPT_fobjc_link_runtime);
427
3.43k
}
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
14
453
14
  CmdArgs.push_back("-mllvm");
454
14
  CmdArgs.push_back("-lto-pass-remarks-output");
455
14
  CmdArgs.push_back("-mllvm");
456
14
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
13
467
13
    CmdArgs.push_back(Args.MakeArgString(F));
468
13
  }
469
14
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
14
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
14
484
14
  if (getLastProfileUseArg(Args)) {
485
2
    CmdArgs.push_back("-mllvm");
486
2
    CmdArgs.push_back("-lto-pass-remarks-with-hotness");
487
2
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.43k
                                  const char *LinkingOutput) const {
503
3.43k
  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
504
3.43k
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.43k
  llvm::opt::ArgStringList InputFileList;
510
3.43k
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.43k
  ArgStringList CmdArgs;
515
3.43k
516
  /// Hack(tm) to ignore linking errors when we are doing ARC migration.
517
3.43k
  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));
526
2
    return;
527
2
  }
528
3.43k
529
3.43k
  unsigned Version[5] = {0, 0, 0, 0, 0};
530
3.43k
  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
531
3.43k
    if (!Driver::GetReleaseVersion(A->getValue(), Version))
532
3
      getToolChain().getDriver().Diag(diag::err_drv_invalid_version_number)
533
3
          << A->getAsString(Args);
534
3.43k
  }
535
3.43k
536
  // I'm not sure why this particular decomposition exists in gcc, but
537
  // we follow suite for ease of comparison.
538
3.43k
  AddLinkArgs(C, Args, CmdArgs, Inputs, Version);
539
3.43k
540
3.43k
  if (willEmitRemarks(Args) &&
541
16
      checkRemarksOptions(getToolChain().getDriver(), Args,
542
16
                          getToolChain().getTriple()))
543
14
    renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA);
544
3.43k
545
  // Propagate the -moutline flag to the linker in LTO.
546
3.43k
  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
1
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
3.43k
566
  // Setup statistics file output.
567
3.43k
  SmallString<128> StatsFile =
568
3.43k
      getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());
569
3.43k
  if (!StatsFile.empty()) {
570
2
    CmdArgs.push_back("-mllvm");
571
2
    CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str()));
572
2
  }
573
3.43k
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.43k
  Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
577
3.43k
                            options::OPT_Z_Flag, options::OPT_u_Group,
578
3.43k
                            options::OPT_e, options::OPT_r});
579
3.43k
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.43k
  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
584
0
    CmdArgs.push_back("-ObjC");
585
3.43k
586
3.43k
  CmdArgs.push_back("-o");
587
3.43k
  CmdArgs.push_back(Output.getFilename());
588
3.43k
589
3.43k
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
590
3.42k
    getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
591
3.43k
592
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_L);
593
3.43k
594
3.43k
  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.40k
  for (const auto &II : Inputs) {
598
4.40k
    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
552
      if (InputFileList.size() > 0)
604
523
        break;
605
29
606
29
      continue;
607
29
    }
608
3.85k
609
3.85k
    InputFileList.push_back(II.getFilename());
610
3.85k
  }
611
3.43k
612
3.43k
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
613
3.42k
    addOpenMPRuntime(CmdArgs, getToolChain(), Args);
614
3.43k
615
3.43k
  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
6
620
6
    CmdArgs.push_back("-framework");
621
6
    CmdArgs.push_back("Foundation");
622
    // Link libobj.
623
6
    CmdArgs.push_back("-lobjc");
624
6
  }
625
3.43k
626
3.43k
  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
3.43k
632
3.43k
  if (Args.hasArg(options::OPT_fnested_functions))
633
0
    CmdArgs.push_back("-allow_stack_execute");
634
3.43k
635
3.43k
  getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
636
3.43k
637
3.43k
  StringRef Parallelism = getLTOParallelism(Args, getToolChain().getDriver());
638
3.43k
  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
3.43k
645
3.43k
  if (getToolChain().ShouldLinkCXXStdlib(Args))
646
2.68k
    getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
647
3.43k
648
3.43k
  bool NoStdOrDefaultLibs =
649
3.43k
      Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
650
3.43k
  bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib);
651
3.43k
  if (!NoStdOrDefaultLibs || 
ForceLinkBuiltins11
) {
652
    // link_ssp spec is empty.
653
3.42k
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.42k
    if (NoStdOrDefaultLibs && 
ForceLinkBuiltins1
) {
657
1
      getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins");
658
3.42k
    } else {
659
      // Let the tool chain choose which runtime library to link.
660
3.42k
      getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs,
661
3.42k
                                                ForceLinkBuiltins);
662
3.42k
663
      // No need to do anything for pthreads. Claim argument to avoid warning.
664
3.42k
      Args.ClaimAllArgs(options::OPT_pthread);
665
3.42k
      Args.ClaimAllArgs(options::OPT_pthreads);
666
3.42k
    }
667
3.42k
  }
668
3.43k
669
3.43k
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
670
    // endfile_spec is empty.
671
3.42k
  }
672
3.43k
673
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
674
3.43k
  Args.AddAllArgs(CmdArgs, options::OPT_F);
675
3.43k
676
  // -iframework should be forwarded as -F.
677
3.43k
  for (const Arg *A : Args.filtered(options::OPT_iframework))
678
1
    CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
679
3.43k
680
3.43k
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
681
3.42k
    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.42k
  }
688
3.43k
689
3.43k
  ResponseFileSupport ResponseSupport = ResponseFileSupport::AtFileUTF8();
690
3.43k
  if (Version[0] < 607) {
691
    // For older versions of the linker, use the legacy filelist method instead.
692
3.43k
    ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8,
693
3.43k
                       "-filelist"};
694
3.43k
  }
695
3.43k
696
3.43k
  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
697
3.43k
  std::unique_ptr<Command> Cmd = std::make_unique<Command>(
698
3.43k
      JA, *this, ResponseSupport, Exec, CmdArgs, Inputs);
699
3.43k
  Cmd->setInputFileList(std::move(InputFileList));
700
3.43k
  C.addCommand(std::move(Cmd));
701
3.43k
}
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
10
710
10
  CmdArgs.push_back("-create");
711
10
  assert(Output.isFilename() && "Unexpected lipo output.");
712
10
713
10
  CmdArgs.push_back("-output");
714
10
  CmdArgs.push_back(Output.getFilename());
715
10
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
10
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));
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
79
                                    const char *LinkingOutput) const {
731
79
  ArgStringList CmdArgs;
732
79
733
79
  CmdArgs.push_back("-o");
734
79
  CmdArgs.push_back(Output.getFilename());
735
79
736
79
  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
737
79
  const InputInfo &Input = Inputs[0];
738
79
  assert(Input.isFilename() && "Unexpected dsymutil input.");
739
79
  CmdArgs.push_back(Input.getFilename());
740
79
741
79
  const char *Exec =
742
79
      Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
743
79
  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
744
79
                                         Exec, CmdArgs, Inputs));
745
79
}
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
0
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
0
762
  // Grabbing the output of the earlier dsymutil run.
763
0
  CmdArgs.push_back(Input.getFilename());
764
0
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));
769
0
}
770
771
MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
772
21.9k
    : ToolChain(D, Triple, Args) {
773
  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
774
21.9k
  getProgramPaths().push_back(getDriver().getInstalledDir());
775
21.9k
  if (getDriver().getInstalledDir() != getDriver().Dir)
776
31
    getProgramPaths().push_back(getDriver().Dir);
777
21.9k
}
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
21.9k
      CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {}
783
784
19.1k
types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
785
19.1k
  types::ID Ty = ToolChain::LookupTypeForExtension(Ext);
786
19.1k
787
  // Darwin always preprocesses assembly files (unless -x is used explicitly).
788
19.1k
  if (Ty == types::TY_PP_Asm)
789
27
    return types::TY_Asm;
790
19.0k
791
19.0k
  return Ty;
792
19.0k
}
793
794
4.93k
bool MachO::HasNativeLLVMSupport() const { return true; }
795
796
20.3k
ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
797
  // Default to use libc++ on OS X 10.9+ and iOS 7+.
798
20.3k
  if ((isTargetMacOS() && 
!isMacosxVersionLT(10, 9)19.9k
) ||
799
961
       (isTargetIOSBased() && 
!isIPhoneOSVersionLT(7, 0)337
) ||
800
822
       isTargetWatchOSBased())
801
19.5k
    return ToolChain::CST_Libcxx;
802
767
803
767
  return ToolChain::CST_Libstdcxx;
804
767
}
805
806
/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
807
18.0k
ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
808
18.0k
  if (isTargetWatchOSBased())
809
42
    return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
810
17.9k
  if (isTargetIOSBased())
811
190
    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
812
17.7k
  if (isNonFragile)
813
17.6k
    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
814
92
  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
815
92
}
816
817
/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
818
18.0k
bool Darwin::hasBlocksRuntime() const {
819
18.0k
  if (isTargetWatchOSBased())
820
42
    return true;
821
17.9k
  else if (isTargetIOSBased())
822
191
    return !isIPhoneOSVersionLT(3, 2);
823
17.8k
  else {
824
17.8k
    assert(isTargetMacOS() && "unexpected darwin target");
825
17.8k
    return !isMacosxVersionLT(10, 6);
826
17.8k
  }
827
18.0k
}
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
6
                               ArgStringList &CC1Args) const {
836
6
  RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
837
6
}
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
0
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.0k
StringRef MachO::getMachOArchName(const ArgList &Args) const {
880
12.0k
  switch (getTriple().getArch()) {
881
11.8k
  default:
882
11.8k
    return getDefaultUniversalArchName();
883
0
884
5
  case llvm::Triple::aarch64_32:
885
5
    return "arm64_32";
886
0
887
62
  case llvm::Triple::aarch64:
888
62
    return "arm64";
889
0
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
0
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
0
900
0
    return "arm";
901
12.0k
  }
902
12.0k
}
903
904
21.9k
Darwin::~Darwin() {}
905
906
21.9k
MachO::~MachO() {}
907
908
std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
909
21.7k
                                                types::ID InputType) const {
910
21.7k
  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
911
21.7k
912
  // If the target isn't initialized (e.g., an unknown Darwin platform, return
913
  // the default triple).
914
21.7k
  if (!isTargetInitialized())
915
2
    return Triple.getTriple();
916
21.7k
917
21.7k
  SmallString<16> Str;
918
21.7k
  if (isTargetWatchOSBased())
919
63
    Str += "watchos";
920
21.6k
  else if (isTargetTvOSBased())
921
55
    Str += "tvos";
922
21.6k
  else if (isTargetIOSBased())
923
257
    Str += "ios";
924
21.3k
  else
925
21.3k
    Str += "macosx";
926
21.7k
  Str += getTargetVersion().getAsString();
927
21.7k
  Triple.setOSName(Str);
928
21.7k
929
21.7k
  return Triple.getTriple();
930
21.7k
}
931
932
3.66k
Tool *MachO::getTool(Action::ActionClass AC) const {
933
3.66k
  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
85
  case Action::DsymutilJobClass:
939
85
    if (!Dsymutil)
940
85
      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
941
85
    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.56k
  default:
947
3.56k
    return ToolChain::getTool(AC);
948
3.66k
  }
949
3.66k
}
950
951
3.44k
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
21.9k
    : Darwin(D, Triple, Args) {}
960
961
18.1k
void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
962
  // Always error about undefined 'TARGET_OS_*' macros.
963
18.1k
  CC1Args.push_back("-Wundef-prefix=TARGET_OS_");
964
18.1k
  CC1Args.push_back("-Werror=undef-prefix");
965
18.1k
966
  // For modern targets, promote certain warnings to errors.
967
18.1k
  if (isTargetWatchOSBased() || 
getTriple().isArch64Bit()18.1k
) {
968
    // Always enable -Wdeprecated-objc-isa-usage and promote it
969
    // to an error.
970
17.9k
    CC1Args.push_back("-Wdeprecated-objc-isa-usage");
971
17.9k
    CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
972
17.9k
973
    // For iOS and watchOS, also error about implicit function declarations,
974
    // as that can impact calling conventions.
975
17.9k
    if (!isTargetMacOS())
976
151
      CC1Args.push_back("-Werror=implicit-function-declaration");
977
17.9k
  }
978
18.1k
}
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
4
1000
4
  ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
1001
4
1002
4
  if ((runtime.hasNativeARC() || 
!isObjCAutoRefCount(Args)0
) &&
1003
4
      runtime.hasSubscripting())
1004
1
    return;
1005
3
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
3
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
3
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
3
1045
3
  CmdArgs.push_back(Args.MakeArgString(P));
1046
3
}
1047
1048
6.24k
unsigned DarwinClang::GetDefaultDwarfVersion() const {
1049
  // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
1050
6.24k
  if ((isTargetMacOS() && 
isMacosxVersionLT(10, 11)6.22k
) ||
1051
6.22k
      (isTargetIOSBased() && 
isIPhoneOSVersionLT(9)14
))
1052
19
    return 2;
1053
6.22k
  return 4;
1054
6.22k
}
1055
1056
void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
1057
                              StringRef Component, RuntimeLinkOptions Opts,
1058
3.54k
                              bool IsShared) const {
1059
3.54k
  SmallString<64> DarwinLibName = StringRef("libclang_rt.");
1060
  // an Darwin the builtins compomnent is not in the library name
1061
3.54k
  if (Component != "builtins") {
1062
134
    DarwinLibName += Component;
1063
134
    if (!(Opts & RLO_IsEmbedded))
1064
124
      DarwinLibName += "_";
1065
134
  }
1066
3.54k
1067
3.54k
  DarwinLibName += getOSLibraryNameSuffix();
1068
3.45k
  DarwinLibName += IsShared ? 
"_dynamic.dylib"93
: ".a";
1069
3.54k
  SmallString<128> Dir(getDriver().ResourceDir);
1070
3.54k
  llvm::sys::path::append(
1071
3.53k
      Dir, "lib", (Opts & RLO_IsEmbedded) ? 
"macho_embedded"10
: "darwin");
1072
3.54k
1073
3.54k
  SmallString<128> P(Dir);
1074
3.54k
  llvm::sys::path::append(P, DarwinLibName);
1075
3.54k
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.54k
  if ((Opts & RLO_AlwaysLink) || 
getVFS().exists(P)3.42k
) {
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
3.54k
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.54k
  if (Opts & RLO_AddRPath) {
1092
93
    assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
1093
93
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
93
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.54k
}
1105
1106
11.7k
StringRef Darwin::getPlatformFamily() const {
1107
11.7k
  switch (TargetPlatform) {
1108
11.6k
    case DarwinPlatformKind::MacOS:
1109
11.6k
      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.2k
StringRef Darwin::getSDKName(StringRef isysroot) {
1121
  // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
1122
22.2k
  auto BeginSDK = llvm::sys::path::rbegin(isysroot);
1123
22.2k
  auto EndSDK = llvm::sys::path::rend(isysroot);
1124
23.6k
  for (auto IT = BeginSDK; IT != EndSDK; 
++IT1.48k
) {
1125
23.5k
    StringRef SDK = *IT;
1126
23.5k
    if (SDK.endswith(".sdk"))
1127
22.0k
      return SDK.slice(0, SDK.size() - 4);
1128
23.5k
  }
1129
122
  return "";
1130
22.2k
}
1131
1132
3.53k
StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
1133
3.53k
  switch (TargetPlatform) {
1134
3.38k
  case DarwinPlatformKind::MacOS:
1135
3.38k
    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.42k
                              ArgStringList &CmdArgs) const {
1185
3.42k
  if (!needsProfileRT(Args) && 
!needsGCovInstrumentation(Args)3.40k
)
1186
3.39k
    return;
1187
26
1188
26
  AddLinkRuntimeLib(Args, CmdArgs, "profile",
1189
26
                    RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink));
1190
26
1191
26
  bool ForGCOV = needsGCovInstrumentation(Args);
1192
26
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
26
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.41k
    const ArgList &Args) const {
1238
3.41k
  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
3.41k
1245
3.41k
  return ToolChain::RLT_CompilerRT;
1246
3.41k
}
1247
1248
void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
1249
                                        ArgStringList &CmdArgs,
1250
3.41k
                                        bool ForceLinkBuiltinRT) const {
1251
  // Call once to ensure diagnostic is printed if wrong value was specified
1252
3.41k
  GetRuntimeLibType(Args);
1253
3.41k
1254
  // Darwin doesn't support real static executables, don't link any runtime
1255
  // libraries with -static.
1256
3.41k
  if (Args.hasArg(options::OPT_static) ||
1257
3.40k
      Args.hasArg(options::OPT_fapple_kext) ||
1258
3.40k
      Args.hasArg(options::OPT_mkernel)) {
1259
5
    if (ForceLinkBuiltinRT)
1260
1
      AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1261
5
    return;
1262
5
  }
1263
3.40k
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.40k
  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
3.40k
1272
3.40k
  const SanitizerArgs &Sanitize = getSanitizerArgs();
1273
3.40k
  if (Sanitize.needsAsanRt())
1274
21
    AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
1275
3.40k
  if (Sanitize.needsLsanRt())
1276
8
    AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
1277
3.40k
  if (Sanitize.needsUbsanRt())
1278
39
    AddLinkSanitizerLibArgs(Args, CmdArgs,
1279
2
                            Sanitize.requiresMinimalRuntime() ? "ubsan_minimal"
1280
37
                                                              : "ubsan",
1281
39
                            Sanitize.needsSharedRt());
1282
3.40k
  if (Sanitize.needsTsanRt())
1283
25
    AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
1284
3.40k
  if (Sanitize.needsFuzzer() && 
!Args.hasArg(options::OPT_dynamiclib)4
) {
1285
3
    AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false);
1286
3
1287
    // Libfuzzer is written in C++ and requires libcxx.
1288
3
    AddCXXStdlibLibArgs(Args, CmdArgs);
1289
3
  }
1290
3.40k
  if (Sanitize.needsStatsRt()) {
1291
1
    AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
1292
1
    AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
1293
1
  }
1294
3.40k
1295
3.40k
  const XRayArgs &XRay = getXRayArgs();
1296
3.40k
  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
3.40k
1302
  // Otherwise link libSystem, then the dynamic runtime library, and finally any
1303
  // target specific static runtime library.
1304
3.40k
  CmdArgs.push_back("-lSystem");
1305
3.40k
1306
  // Select the dynamic runtime library and the target specific static library.
1307
3.40k
  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.40k
  AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1316
3.40k
}
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.3k
static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
1323
10.3k
  unsigned Major, Minor, Micro;
1324
10.3k
  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
1325
10.3k
  if (!SystemTriple.isMacOSX())
1326
0
    return std::string(MacOSSDKVersion);
1327
10.3k
  SystemTriple.getMacOSXVersion(Major, Minor, Micro);
1328
10.3k
  VersionTuple SystemVersion(Major, Minor, Micro);
1329
10.3k
  bool HadExtra;
1330
10.3k
  if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
1331
10.3k
                                 HadExtra))
1332
0
    return std::string(MacOSSDKVersion);
1333
10.3k
  VersionTuple SDKVersion(Major, Minor, Micro);
1334
10.3k
  if (SDKVersion > SystemVersion)
1335
10.3k
    return SystemVersion.getAsString();
1336
7
  return std::string(MacOSSDKVersion);
1337
7
}
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
25.7k
  DarwinPlatformKind getPlatform() const { return Platform; }
1360
1361
20.6k
  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.2k
  StringRef getOSVersion() const {
1369
23.2k
    if (Kind == OSVersionArg)
1370
1.43k
      return Argument->getValue();
1371
21.7k
    return OSVersion;
1372
21.7k
  }
1373
1374
47
  void setOSVersion(StringRef S) {
1375
47
    assert(Kind == TargetArg && "Unexpected kind!");
1376
47
    OSVersion = std::string(S);
1377
47
  }
1378
1379
1.24k
  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
269
  bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }
1386
1387
  /// Adds the -m<os>-version-min argument to the compiler invocation.
1388
20.6k
  void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
1389
20.6k
    if (Argument)
1390
1.65k
      return;
1391
19.0k
    assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind");
1392
19.0k
    options::ID Opt;
1393
19.0k
    switch (Platform) {
1394
18.9k
    case DarwinPlatformKind::MacOS:
1395
18.9k
      Opt = options::OPT_mmacosx_version_min_EQ;
1396
18.9k
      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.0k
    }
1407
19.0k
    Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion);
1408
19.0k
    Args.append(Argument);
1409
19.0k
  }
1410
1411
  /// Returns the OS version with the argument / environment variable that
1412
  /// specified it.
1413
2.41k
  std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
1414
2.41k
    switch (Kind) {
1415
2.41k
    case TargetArg:
1416
2.41k
    case OSVersionArg:
1417
2.41k
    case InferredFromSDK:
1418
2.41k
    case InferredFromArch:
1419
2.41k
      assert(Argument && "OS version argument not yet inferred");
1420
2.41k
      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.53k
                                         StringRef OSVersion, Arg *A) {
1429
1.53k
    DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
1430
1.53k
                          A);
1431
1.53k
    switch (TT.getEnvironment()) {
1432
5
    case llvm::Triple::Simulator:
1433
5
      Result.Environment = DarwinEnvironmentKind::Simulator;
1434
5
      break;
1435
1.52k
    default:
1436
1.52k
      break;
1437
1.53k
    }
1438
1.53k
    unsigned Major, Minor, Micro;
1439
1.53k
    TT.getOSVersion(Major, Minor, Micro);
1440
1.53k
    if (Major == 0)
1441
117
      Result.HasOSVersion = false;
1442
1.53k
    return Result;
1443
1.53k
  }
1444
  static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
1445
1.39k
                                           Arg *A) {
1446
1.39k
    return DarwinPlatform(OSVersionArg, Platform, A);
1447
1.39k
  }
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.3k
                                      bool IsSimulator = false) {
1458
10.3k
    DarwinPlatform Result(InferredFromSDK, Platform, Value);
1459
10.3k
    if (IsSimulator)
1460
16
      Result.Environment = DarwinEnvironmentKind::Simulator;
1461
10.3k
    Result.InferSimulatorFromArch = false;
1462
10.3k
    return Result;
1463
10.3k
  }
1464
  static DarwinPlatform createFromArch(llvm::Triple::OSType OS,
1465
8.60k
                                       StringRef Value) {
1466
8.60k
    return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value);
1467
8.60k
  }
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.39k
      : Kind(Kind), Platform(Platform), Argument(Argument) {}
1484
  DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value,
1485
                 Arg *Argument = nullptr)
1486
20.5k
      : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {}
1487
1488
10.1k
  static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {
1489
10.1k
    switch (OS) {
1490
9.96k
    case llvm::Triple::Darwin:
1491
9.96k
    case llvm::Triple::MacOSX:
1492
9.96k
      return DarwinPlatformKind::MacOS;
1493
120
    case llvm::Triple::IOS:
1494
120
      return DarwinPlatformKind::IPhoneOS;
1495
21
    case llvm::Triple::TvOS:
1496
21
      return DarwinPlatformKind::TvOS;
1497
26
    case llvm::Triple::WatchOS:
1498
26
      return DarwinPlatformKind::WatchOS;
1499
0
    default:
1500
0
      llvm_unreachable("Unable to infer Darwin variant");
1501
10.1k
    }
1502
10.1k
  }
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
20.6k
                                    const Driver &TheDriver) {
1518
20.6k
  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
1519
20.6k
  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ,
1520
20.6k
                                    options::OPT_mios_simulator_version_min_EQ);
1521
20.6k
  Arg *TvOSVersion =
1522
20.6k
      Args.getLastArg(options::OPT_mtvos_version_min_EQ,
1523
20.6k
                      options::OPT_mtvos_simulator_version_min_EQ);
1524
20.6k
  Arg *WatchOSVersion =
1525
20.6k
      Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
1526
20.6k
                      options::OPT_mwatchos_simulator_version_min_EQ);
1527
20.6k
  if (OSXVersion) {
1528
1.28k
    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.28k
    return DarwinPlatform::createOSVersionArg(Darwin::MacOS, OSXVersion);
1536
19.3k
  } 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.3k
  } 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.2k
  } else if (WatchOSVersion)
1551
22
    return DarwinPlatform::createOSVersionArg(Darwin::WatchOS, WatchOSVersion);
1552
19.2k
  return None;
1553
19.2k
}
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
18.9k
                                            const llvm::Triple &Triple) {
1560
18.9k
  std::string Targets[Darwin::LastDarwinPlatform + 1];
1561
18.9k
  const char *EnvVars[] = {
1562
18.9k
      "MACOSX_DEPLOYMENT_TARGET",
1563
18.9k
      "IPHONEOS_DEPLOYMENT_TARGET",
1564
18.9k
      "TVOS_DEPLOYMENT_TARGET",
1565
18.9k
      "WATCHOS_DEPLOYMENT_TARGET",
1566
18.9k
  };
1567
18.9k
  static_assert(llvm::array_lengthof(EnvVars) == Darwin::LastDarwinPlatform + 1,
1568
18.9k
                "Missing platform");
1569
75.9k
  for (const auto &I : llvm::enumerate(llvm::makeArrayRef(EnvVars))) {
1570
75.9k
    if (char *Env = ::getenv(I.value()))
1571
28
      Targets[I.index()] = Env;
1572
75.9k
  }
1573
18.9k
1574
  // Allow conflicts among OSX and iOS for historical reasons, but choose the
1575
  // default platform.
1576
18.9k
  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
18.9k
  } else {
1587
    // Don't allow conflicts in any other platform.
1588
18.9k
    unsigned FirstTarget = llvm::array_lengthof(Targets);
1589
94.9k
    for (unsigned I = 0; I != llvm::array_lengthof(Targets); 
++I75.9k
) {
1590
75.9k
      if (Targets[I].empty())
1591
75.9k
        continue;
1592
21
      if (FirstTarget == llvm::array_lengthof(Targets))
1593
20
        FirstTarget = I;
1594
1
      else
1595
1
        TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
1596
1
            << Targets[FirstTarget] << Targets[I];
1597
21
    }
1598
18.9k
  }
1599
18.9k
1600
75.9k
  for (const auto &Target : llvm::enumerate(llvm::makeArrayRef(Targets))) {
1601
75.9k
    if (!Target.value().empty())
1602
24
      return DarwinPlatform::createDeploymentTargetEnv(
1603
24
          (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],
1604
24
          Target.value());
1605
75.9k
  }
1606
18.9k
  return None;
1607
18.9k
}
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
18.9k
                             const Optional<DarwinSDKInfo> &SDKInfo) {
1615
18.9k
  const Arg *A = Args.getLastArg(options::OPT_isysroot);
1616
18.9k
  if (!A)
1617
8.56k
    return None;
1618
10.4k
  StringRef isysroot = A->getValue();
1619
10.4k
  StringRef SDK = Darwin::getSDKName(isysroot);
1620
10.4k
  if (!SDK.size())
1621
60
    return None;
1622
10.3k
1623
10.3k
  std::string Version;
1624
10.3k
  if (SDKInfo) {
1625
    // Get the version from the SDKSettings.json if it's available.
1626
10.3k
    Version = SDKInfo->getVersion().getAsString();
1627
14
  } else {
1628
    // Slice the version number out.
1629
    // Version number is between the first and the last number.
1630
14
    size_t StartVer = SDK.find_first_of("0123456789");
1631
14
    size_t EndVer = SDK.find_last_of("0123456789");
1632
19
    if (
StartVer != StringRef::npos14
&& EndVer > StartVer)
1633
19
      Version = std::string(SDK.slice(StartVer, EndVer + 1));
1634
14
  }
1635
10.3k
  if (Version.empty())
1636
0
    return None;
1637
10.3k
1638
10.3k
  if (SDK.startswith("iPhoneOS") || 
SDK.startswith("iPhoneSimulator")10.3k
)
1639
11
    return DarwinPlatform::createFromSDK(
1640
11
        Darwin::IPhoneOS, Version,
1641
11
        /*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
1642
10.3k
  else if (SDK.startswith("MacOSX"))
1643
10.3k
    return DarwinPlatform::createFromSDK(Darwin::MacOS,
1644
10.3k
                                         getSystemOrSDKMacOSVersion(Version));
1645
13
  else if (SDK.startswith("WatchOS") || 
SDK.startswith("WatchSimulator")11
)
1646
7
    return DarwinPlatform::createFromSDK(
1647
7
        Darwin::WatchOS, Version,
1648
7
        /*IsSimulator=*/SDK.startswith("WatchSimulator"));
1649
6
  else if (SDK.startswith("AppleTVOS") || 
SDK.startswith("AppleTVSimulator")5
)
1650
6
    return DarwinPlatform::createFromSDK(
1651
6
        Darwin::TvOS, Version,
1652
6
        /*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
1653
0
  return None;
1654
0
}
1655
1656
std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
1657
10.1k
                         const Driver &TheDriver) {
1658
10.1k
  unsigned Major, Minor, Micro;
1659
10.1k
  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
1660
10.1k
  switch (OS) {
1661
9.97k
  case llvm::Triple::Darwin:
1662
9.97k
  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
9.97k
    if (Triple.isMacOSX() && SystemTriple.isMacOSX() &&
1666
9.97k
        !Triple.getOSMajorVersion())
1667
207
      SystemTriple.getMacOSXVersion(Major, Minor, Micro);
1668
9.76k
    else if (!Triple.getMacOSXVersion(Major, Minor, Micro))
1669
0
      TheDriver.Diag(diag::err_drv_invalid_darwin_version)
1670
0
          << Triple.getOSName();
1671
9.97k
    break;
1672
120
  case llvm::Triple::IOS:
1673
120
    Triple.getiOSVersion(Major, Minor, Micro);
1674
120
    break;
1675
21
  case llvm::Triple::TvOS:
1676
21
    Triple.getOSVersion(Major, Minor, Micro);
1677
21
    break;
1678
26
  case llvm::Triple::WatchOS:
1679
26
    Triple.getWatchOSVersion(Major, Minor, Micro);
1680
26
    break;
1681
0
  default:
1682
0
    llvm_unreachable("Unexpected OS type");
1683
0
    break;
1684
10.1k
  }
1685
10.1k
1686
10.1k
  std::string OSVersion;
1687
10.1k
  llvm::raw_string_ostream(OSVersion) << Major << '.' << Minor << '.' << Micro;
1688
10.1k
  return OSVersion;
1689
10.1k
}
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.60k
                              const Driver &TheDriver) {
1696
8.60k
  llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
1697
8.60k
1698
8.60k
  StringRef MachOArchName = Toolchain.getMachOArchName(Args);
1699
8.60k
  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.59k
  } else if (MachOArchName == "armv7" || 
MachOArchName == "armv7s"8.57k
)
1709
20
    OSTy = llvm::Triple::IOS;
1710
8.57k
  else if (MachOArchName == "armv7k" || 
MachOArchName == "arm64_32"8.57k
)
1711
2
    OSTy = llvm::Triple::WatchOS;
1712
8.57k
  else if (MachOArchName != "armv6m" && 
MachOArchName != "armv7m"8.57k
&&
1713
8.57k
           MachOArchName != "armv7em")
1714
8.57k
    OSTy = llvm::Triple::MacOSX;
1715
8.60k
1716
8.60k
  if (OSTy == llvm::Triple::UnknownOS)
1717
0
    return None;
1718
8.60k
  return DarwinPlatform::createFromArch(OSTy,
1719
8.60k
                                        getOSVersion(OSTy, Triple, TheDriver));
1720
8.60k
}
1721
1722
/// Returns the deployment target that's specified using the -target option.
1723
Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
1724
20.6k
    DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver) {
1725
20.6k
  if (!Args.hasArg(options::OPT_target))
1726
18.4k
    return None;
1727
2.17k
  if (Triple.getOS() == llvm::Triple::Darwin ||
1728
1.53k
      Triple.getOS() == llvm::Triple::UnknownOS)
1729
636
    return None;
1730
1.53k
  std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
1731
1.53k
  return DarwinPlatform::createFromTarget(Triple, OSVersion,
1732
1.53k
                                          Args.getLastArg(options::OPT_target));
1733
1.53k
}
1734
1735
Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
1736
                                         const ArgList &Args,
1737
20.6k
                                         const Driver &TheDriver) {
1738
20.6k
  const Arg *A = Args.getLastArg(options::OPT_isysroot);
1739
20.6k
  if (!A)
1740
8.89k
    return None;
1741
11.7k
  StringRef isysroot = A->getValue();
1742
11.7k
  auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot);
1743
11.7k
  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.7k
  return *SDKInfoOrErr;
1749
11.7k
}
1750
1751
} // namespace
1752
1753
20.6k
void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
1754
20.6k
  const OptTable &Opts = getDriver().getOpts();
1755
20.6k
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
20.6k
  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
1760
    // Warn if the path does not exist.
1761
9.91k
    if (!getVFS().exists(A->getValue()))
1762
21
      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
1763
10.7k
  } else {
1764
10.7k
    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.86k
      if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
1768
1.86k
          StringRef(env) != "/") {
1769
1.85k
        Args.append(Args.MakeSeparateArg(
1770
1.85k
            nullptr, Opts.getOption(options::OPT_isysroot), env));
1771
1.85k
      }
1772
1.86k
    }
1773
10.7k
  }
1774
20.6k
1775
  // Read the SDKSettings.json file for more information, like the SDK version
1776
  // that we can pass down to the compiler.
1777
20.6k
  SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
1778
20.6k
1779
  // The OS and the version can be specified using the -target argument.
1780
20.6k
  Optional<DarwinPlatform> OSTarget =
1781
20.6k
      getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver());
1782
20.6k
  if (OSTarget) {
1783
1.53k
    Optional<DarwinPlatform> OSVersionArgTarget =
1784
1.53k
        getDeploymentTargetFromOSVersionArg(Args, getDriver());
1785
1.53k
    if (OSVersionArgTarget) {
1786
1.26k
      unsigned TargetMajor, TargetMinor, TargetMicro;
1787
1.26k
      bool TargetExtra;
1788
1.26k
      unsigned ArgMajor, ArgMinor, ArgMicro;
1789
1.26k
      bool ArgExtra;
1790
1.26k
      if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() ||
1791
1.26k
          (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor,
1792
1.26k
                                     TargetMinor, TargetMicro, TargetExtra) &&
1793
1.26k
           Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(),
1794
1.26k
                                     ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
1795
1.26k
           (VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
1796
1.26k
                VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
1797
1.25k
            
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.25k
        if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() &&
1801
1.24k
            !OSTarget->hasOSVersion()) {
1802
47
          OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion());
1803
1.20k
        } else {
1804
          // Warn about -m<os>-version-min that doesn't match the OS version
1805
          // that's specified in the target.
1806
1.20k
          std::string OSVersionArg =
1807
1.20k
              OSVersionArgTarget->getAsString(Args, Opts);
1808
1.20k
          std::string TargetArg = OSTarget->getAsString(Args, Opts);
1809
1.20k
          getDriver().Diag(clang::diag::warn_drv_overriding_flag_option)
1810
1.20k
              << OSVersionArg << TargetArg;
1811
1.20k
        }
1812
1.25k
      }
1813
1.26k
    }
1814
19.1k
  } else {
1815
    // The OS target can be specified using the -m<os>version-min argument.
1816
19.1k
    OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver());
1817
    // If no deployment target was specified on the command line, check for
1818
    // environment defines.
1819
19.1k
    if (!OSTarget) {
1820
18.9k
      OSTarget =
1821
18.9k
          getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
1822
18.9k
      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
18.9k
    }
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.1k
    if (!OSTarget) {
1834
18.9k
      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
18.9k
      if (OSTarget && 
!SDKInfo10.3k
)
1838
16
        SDKInfo = OSTarget->inferSDKInfo();
1839
18.9k
    }
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.1k
    if (!OSTarget)
1843
8.60k
      OSTarget =
1844
8.60k
          inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
1845
19.1k
  }
1846
20.6k
1847
20.6k
  assert(OSTarget && "Unable to infer Darwin variant");
1848
20.6k
  OSTarget->addOSVersionMinArgument(Args, Opts);
1849
20.6k
  DarwinPlatformKind Platform = OSTarget->getPlatform();
1850
20.6k
1851
20.6k
  unsigned Major, Minor, Micro;
1852
20.6k
  bool HadExtra;
1853
  // Set the tool chain target information.
1854
20.6k
  if (Platform == MacOS) {
1855
20.3k
    if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
1856
20.3k
                                   Micro, HadExtra) ||
1857
20.3k
        
HadExtra20.3k
||
Major < 1020.3k
|| Major >= 100 ||
Minor >= 10020.3k
||
Micro >= 10020.3k
)
1858
3
      getDriver().Diag(diag::err_drv_invalid_version_number)
1859
3
          << OSTarget->getAsString(Args, Opts);
1860
288
  } else if (Platform == IPhoneOS) {
1861
193
    if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
1862
193
                                   Micro, HadExtra) ||
1863
193
        HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
1864
0
      getDriver().Diag(diag::err_drv_invalid_version_number)
1865
0
          << OSTarget->getAsString(Args, Opts);
1866
193
    ;
1867
    // For 32-bit targets, the deployment target for iOS has to be earlier than
1868
    // iOS 11.
1869
193
    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
95
  } else if (Platform == TvOS) {
1882
45
    if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
1883
45
                                   Micro, HadExtra) ||
1884
45
        HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
1885
0
      getDriver().Diag(diag::err_drv_invalid_version_number)
1886
0
          << OSTarget->getAsString(Args, Opts);
1887
52
  } else 
if (50
Platform == WatchOS50
) {
1888
52
    if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
1889
52
                                   Micro, HadExtra) ||
1890
52
        HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100)
1891
0
      getDriver().Diag(diag::err_drv_invalid_version_number)
1892
0
          << OSTarget->getAsString(Args, Opts);
1893
52
  } else
1894
18.4E
    llvm_unreachable("unknown kind of Darwin platform");
1895
20.6k
1896
20.6k
  DarwinEnvironmentKind Environment = OSTarget->getEnvironment();
1897
  // Recognize iOS targets with an x86 architecture as the iOS simulator.
1898
20.6k
  if (Environment == NativeEnvironment && 
Platform != MacOS20.6k
&&
1899
269
      OSTarget->canInferSimulatorFromArch() && 
getTriple().isX86()260
)
1900
66
    Environment = Simulator;
1901
20.6k
1902
20.6k
  setTarget(Platform, Environment, Major, Minor, Micro);
1903
20.6k
1904
20.6k
  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
1905
11.7k
    StringRef SDK = getSDKName(A->getValue());
1906
11.7k
    if (SDK.size() > 0) {
1907
11.7k
      size_t StartVer = SDK.find_first_of("0123456789");
1908
11.7k
      StringRef SDKName = SDK.slice(0, StartVer);
1909
11.7k
      if (!SDKName.startswith(getPlatformFamily()))
1910
23
        getDriver().Diag(diag::warn_incompatible_sysroot)
1911
23
            << SDKName << getPlatformFamily();
1912
11.7k
    }
1913
11.7k
  }
1914
20.6k
}
1915
1916
// Returns the effective header sysroot path to use. This comes either from
1917
// -isysroot or --sysroot.
1918
30.7k
llvm::StringRef DarwinClang::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const {
1919
30.7k
  if(DriverArgs.hasArg(options::OPT_isysroot))
1920
14.7k
    return DriverArgs.getLastArgValue(options::OPT_isysroot);
1921
16.0k
  if (!getDriver().SysRoot.empty())
1922
30
    return getDriver().SysRoot;
1923
15.9k
  return "/";
1924
15.9k
}
1925
1926
void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
1927
18.1k
                                            llvm::opt::ArgStringList &CC1Args) const {
1928
18.1k
  const Driver &D = getDriver();
1929
18.1k
1930
18.1k
  llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
1931
18.1k
1932
18.1k
  bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);
1933
18.1k
  bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);
1934
18.1k
  bool NoBuiltinInc = DriverArgs.hasFlag(
1935
18.1k
      options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false);
1936
18.1k
  bool ForceBuiltinInc = DriverArgs.hasFlag(
1937
18.1k
      options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false);
1938
18.1k
1939
  // Add <sysroot>/usr/local/include
1940
18.1k
  if (!NoStdInc && 
!NoStdlibInc18.0k
) {
1941
18.0k
      SmallString<128> P(Sysroot);
1942
18.0k
      llvm::sys::path::append(P, "usr", "local", "include");
1943
18.0k
      addSystemInclude(DriverArgs, CC1Args, P);
1944
18.0k
  }
1945
18.1k
1946
  // Add the Clang builtin headers (<resource>/include)
1947
18.1k
  if (!(NoStdInc && 
!ForceBuiltinInc42
) &&
!NoBuiltinInc18.0k
) {
1948
18.0k
    SmallString<128> P(D.ResourceDir);
1949
18.0k
    llvm::sys::path::append(P, "include");
1950
18.0k
    addSystemInclude(DriverArgs, CC1Args, P);
1951
18.0k
  }
1952
18.1k
1953
18.1k
  if (NoStdInc || 
NoStdlibInc18.0k
)
1954
46
    return;
1955
18.0k
1956
  // Check for configure-time C include directories.
1957
18.0k
  llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
1958
18.0k
  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.0k
  } else {
1967
    // Otherwise, add <sysroot>/usr/include.
1968
18.0k
    SmallString<128> P(Sysroot);
1969
18.0k
    llvm::sys::path::append(P, "usr", "include");
1970
18.0k
    addExternCSystemInclude(DriverArgs, CC1Args, P.str());
1971
18.0k
  }
1972
18.0k
}
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
61
1982
  // Add the base dir
1983
61
  addSystemInclude(DriverArgs, CC1Args, Base);
1984
61
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
61
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
61
2002
61
  return getVFS().exists(Base);
2003
61
}
2004
2005
void DarwinClang::AddClangCXXStdlibIncludeArgs(
2006
    const llvm::opt::ArgList &DriverArgs,
2007
12.6k
    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.6k
  ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
2014
12.6k
2015
12.6k
  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2016
12.6k
      DriverArgs.hasArg(options::OPT_nostdincxx))
2017
22
    return;
2018
12.6k
2019
12.6k
  llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
2020
12.6k
2021
12.6k
  switch (GetCXXStdlibType(DriverArgs)) {
2022
12.5k
  case ToolChain::CST_Libcxx: {
2023
    // On Darwin, libc++ is installed alongside the compiler in
2024
    // include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'.
2025
12.5k
    {
2026
12.5k
      llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir());
2027
      // Note that P can be relative, so we have to '..' and not parent_path.
2028
12.5k
      llvm::sys::path::append(P, "..", "include", "c++", "v1");
2029
12.5k
      addSystemInclude(DriverArgs, CC1Args, P);
2030
12.5k
    }
2031
    // Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used,
2032
    // to match the legacy behavior in CC1.
2033
12.5k
    if (!DriverArgs.hasArg(options::OPT_nostdinc)) {
2034
12.5k
      llvm::SmallString<128> P = Sysroot;
2035
12.5k
      llvm::sys::path::append(P, "usr", "include", "c++", "v1");
2036
12.5k
      addSystemInclude(DriverArgs, CC1Args, P);
2037
12.5k
    }
2038
12.5k
    break;
2039
0
  }
2040
0
2041
32
  case ToolChain::CST_Libstdcxx:
2042
32
    llvm::SmallString<128> UsrIncludeCxx = Sysroot;
2043
32
    llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
2044
32
2045
32
    llvm::Triple::ArchType arch = getTriple().getArch();
2046
32
    bool IsBaseFound = true;
2047
32
    switch (arch) {
2048
0
    default: break;
2049
0
2050
0
    case llvm::Triple::ppc:
2051
0
    case llvm::Triple::ppc64:
2052
0
      IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2053
0
                                                "4.2.1",
2054
0
                                                "powerpc-apple-darwin10",
2055
0
                                                arch == llvm::Triple::ppc64 ? "ppc64" : "");
2056
0
      IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2057
0
                                                "4.0.0", "powerpc-apple-darwin10",
2058
0
                                                 arch == llvm::Triple::ppc64 ? "ppc64" : "");
2059
0
      break;
2060
0
2061
26
    case llvm::Triple::x86:
2062
26
    case llvm::Triple::x86_64:
2063
26
      IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2064
26
                                                "4.2.1",
2065
26
                                                "i686-apple-darwin10",
2066
21
                                                arch == llvm::Triple::x86_64 ? "x86_64" : 
""5
);
2067
26
      IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2068
26
                                                "4.0.0", "i686-apple-darwin8",
2069
26
                                                 "");
2070
26
      break;
2071
26
2072
3
    case llvm::Triple::arm:
2073
3
    case llvm::Triple::thumb:
2074
3
      IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2075
3
                                                "4.2.1",
2076
3
                                                "arm-apple-darwin10",
2077
3
                                                "v7");
2078
3
      IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2079
3
                                                "4.2.1",
2080
3
                                                "arm-apple-darwin10",
2081
3
                                                 "v6");
2082
3
      break;
2083
3
2084
3
    case llvm::Triple::aarch64:
2085
3
      IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
2086
3
                                                "4.2.1",
2087
3
                                                "arm64-apple-darwin10",
2088
3
                                                "");
2089
3
      break;
2090
32
    }
2091
32
2092
32
    if (!IsBaseFound) {
2093
27
      getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
2094
27
    }
2095
32
2096
32
    break;
2097
12.6k
  }
2098
12.6k
}
2099
void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
2100
2.69k
                                      ArgStringList &CmdArgs) const {
2101
2.69k
  CXXStdlibType Type = GetCXXStdlibType(Args);
2102
2.69k
2103
2.69k
  switch (Type) {
2104
2.69k
  case ToolChain::CST_Libcxx:
2105
2.69k
    CmdArgs.push_back("-lc++");
2106
2.69k
    break;
2107
0
2108
2
  case ToolChain::CST_Libstdcxx:
2109
    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
2110
    // it was previously found in the gcc lib dir. However, for all the Darwin
2111
    // platforms we care about it was -lstdc++.6, so we search for that
2112
    // explicitly if we can't see an obvious -lstdc++ candidate.
2113
2
2114
    // Check in the sysroot first.
2115
2
    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2116
0
      SmallString<128> P(A->getValue());
2117
0
      llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
2118
0
2119
0
      if (!getVFS().exists(P)) {
2120
0
        llvm::sys::path::remove_filename(P);
2121
0
        llvm::sys::path::append(P, "libstdc++.6.dylib");
2122
0
        if (getVFS().exists(P)) {
2123
0
          CmdArgs.push_back(Args.MakeArgString(P));
2124
0
          return;
2125
0
        }
2126
2
      }
2127
0
    }
2128
2
2129
    // Otherwise, look in the root.
2130
    // FIXME: This should be removed someday when we don't have to care about
2131
    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
2132
2
    if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
2133
0
        getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
2134
0
      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
2135
0
      return;
2136
0
    }
2137
2
2138
    // Otherwise, let the linker search.
2139
2
    CmdArgs.push_back("-lstdc++");
2140
2
    break;
2141
2.69k
  }
2142
2.69k
}
2143
2144
void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
2145
2
                                   ArgStringList &CmdArgs) const {
2146
  // For Darwin platforms, use the compiler-rt-based support library
2147
  // instead of the gcc-provided one (which is also incidentally
2148
  // only present in the gcc lib dir, which makes it hard to find).
2149
2
2150
2
  SmallString<128> P(getDriver().ResourceDir);
2151
2
  llvm::sys::path::append(P, "lib", "darwin");
2152
2
2153
  // Use the newer cc_kext for iOS ARM after 6.0.
2154
2
  if (isTargetWatchOS()) {
2155
1
    llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
2156
1
  } else if (isTargetTvOS()) {
2157
1
    llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
2158
0
  } else if (isTargetIPhoneOS()) {
2159
0
    llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
2160
0
  } else {
2161
0
    llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
2162
0
  }
2163
2
2164
  // For now, allow missing resource libraries to support developers who may
2165
  // not have compiler-rt checked out or integrated into their build.
2166
2
  if (getVFS().exists(P))
2167
2
    CmdArgs.push_back(Args.MakeArgString(P));
2168
2
}
2169
2170
DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
2171
                                     StringRef BoundArch,
2172
20.9k
                                     Action::OffloadKind) const {
2173
20.9k
  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
2174
20.9k
  const OptTable &Opts = getDriver().getOpts();
2175
20.9k
2176
  // FIXME: We really want to get out of the tool chain level argument
2177
  // translation business, as it makes the driver functionality much
2178
  // more opaque. For now, we follow gcc closely solely for the
2179
  // purpose of easily achieving feature parity & testability. Once we
2180
  // have something that works, we should reevaluate each translation
2181
  // and try to push it down into tool specific logic.
2182
20.9k
2183
543k
  for (Arg *A : Args) {
2184
543k
    if (A->getOption().matches(options::OPT_Xarch__)) {
2185
      // Skip this argument unless the architecture matches either the toolchain
2186
      // triple arch, or the arch being bound.
2187
13
      llvm::Triple::ArchType XarchArch =
2188
13
          tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
2189
13
      if (!(XarchArch == getArch() ||
2190
4
            (!BoundArch.empty() &&
2191
3
             XarchArch ==
2192
3
                 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
2193
4
        continue;
2194
9
2195
9
      Arg *OriginalArg = A;
2196
9
      TranslateXarchArgs(Args, A, DAL);
2197
9
2198
      // Linker input arguments require custom handling. The problem is that we
2199
      // have already constructed the phase actions, so we can not treat them as
2200
      // "input arguments".
2201
9
      if (A->getOption().hasFlag(options::LinkerInput)) {
2202
        // Convert the argument into individual Zlinker_input_args.
2203
2
        for (const char *Value : A->getValues()) {
2204
2
          DAL->AddSeparateArg(
2205
2
              OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
2206
2
        }
2207
2
        continue;
2208
2
      }
2209
543k
    }
2210
543k
2211
    // Sob. These is strictly gcc compatible for the time being. Apple
2212
    // gcc translates options twice, which means that self-expanding
2213
    // options add duplicates.
2214
543k
    switch ((options::ID)A->getOption().getID()) {
2215
543k
    default:
2216
543k
      DAL->append(A);
2217
543k
      break;
2218
0
2219
21
    case options::OPT_mkernel:
2220
21
    case options::OPT_fapple_kext:
2221
21
      DAL->append(A);
2222
21
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
2223
21
      break;
2224
21
2225
0
    case options::OPT_dependency_file:
2226
0
      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
2227
0
      break;
2228
21
2229
0
    case options::OPT_gfull:
2230
0
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2231
0
      DAL->AddFlagArg(
2232
0
          A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
2233
0
      break;
2234
21
2235
0
    case options::OPT_gused:
2236
0
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2237
0
      DAL->AddFlagArg(
2238
0
          A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
2239
0
      break;
2240
21
2241
5
    case options::OPT_shared:
2242
5
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
2243
5
      break;
2244
21
2245
0
    case options::OPT_fconstant_cfstrings:
2246
0
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
2247
0
      break;
2248
21
2249
0
    case options::OPT_fno_constant_cfstrings:
2250
0
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
2251
0
      break;
2252
21
2253
0
    case options::OPT_Wnonportable_cfstrings:
2254
0
      DAL->AddFlagArg(A,
2255
0
                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
2256
0
      break;
2257
21
2258
0
    case options::OPT_Wno_nonportable_cfstrings:
2259
0
      DAL->AddFlagArg(
2260
0
          A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
2261
0
      break;
2262
21
2263
5
    case options::OPT_fpascal_strings:
2264
5
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
2265
5
      break;
2266
21
2267
4
    case options::OPT_fno_pascal_strings:
2268
4
      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
2269
4
      break;
2270
543k
    }
2271
543k
  }
2272
20.9k
2273
  // Add the arch options based on the particular spelling of -arch, to match
2274
  // how the driver driver works.
2275
20.9k
  if (!BoundArch.empty()) {
2276
20.6k
    StringRef Name = BoundArch;
2277
20.6k
    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
2278
20.6k
    const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ);
2279
20.6k
2280
    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
2281
    // which defines the list of which architectures we accept.
2282
20.6k
    if (Name == "ppc")
2283
0
      ;
2284
20.6k
    else if (Name == "ppc601")
2285
0
      DAL->AddJoinedArg(nullptr, MCpu, "601");
2286
20.6k
    else if (Name == "ppc603")
2287
0
      DAL->AddJoinedArg(nullptr, MCpu, "603");
2288
20.6k
    else if (Name == "ppc604")
2289
0
      DAL->AddJoinedArg(nullptr, MCpu, "604");
2290
20.6k
    else if (Name == "ppc604e")
2291
0
      DAL->AddJoinedArg(nullptr, MCpu, "604e");
2292
20.6k
    else if (Name == "ppc750")
2293
0
      DAL->AddJoinedArg(nullptr, MCpu, "750");
2294
20.6k
    else if (Name == "ppc7400")
2295
0
      DAL->AddJoinedArg(nullptr, MCpu, "7400");
2296
20.6k
    else if (Name == "ppc7450")
2297
0
      DAL->AddJoinedArg(nullptr, MCpu, "7450");
2298
20.6k
    else if (Name == "ppc970")
2299
0
      DAL->AddJoinedArg(nullptr, MCpu, "970");
2300
20.6k
2301
20.6k
    else if (Name == "ppc64" || 
Name == "ppc64le"20.6k
)
2302
0
      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
2303
20.6k
2304
20.6k
    else if (Name == "i386")
2305
119
      ;
2306
20.5k
    else if (Name == "i486")
2307
0
      DAL->AddJoinedArg(nullptr, MArch, "i486");
2308
20.5k
    else if (Name == "i586")
2309
0
      DAL->AddJoinedArg(nullptr, MArch, "i586");
2310
20.5k
    else if (Name == "i686")
2311
12
      DAL->AddJoinedArg(nullptr, MArch, "i686");
2312
20.5k
    else if (Name == "pentium")
2313
0
      DAL->AddJoinedArg(nullptr, MArch, "pentium");
2314
20.5k
    else if (Name == "pentium2")
2315
0
      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
2316
20.5k
    else if (Name == "pentpro")
2317
0
      DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
2318
20.5k
    else if (Name == "pentIIm3")
2319
0
      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
2320
20.5k
2321
20.5k
    else if (Name == "x86_64" || 
Name == "x86_64h"307
)
2322
20.2k
      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
2323
295
2324
295
    else if (Name == "arm")
2325
5
      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
2326
290
    else if (Name == "armv4t")
2327
0
      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
2328
290
    else if (Name == "armv5")
2329
1
      DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
2330
289
    else if (Name == "xscale")
2331
0
      DAL->AddJoinedArg(nullptr, MArch, "xscale");
2332
289
    else if (Name == "armv6")
2333
11
      DAL->AddJoinedArg(nullptr, MArch, "armv6k");
2334
278
    else if (Name == "armv6m")
2335
6
      DAL->AddJoinedArg(nullptr, MArch, "armv6m");
2336
272
    else if (Name == "armv7")
2337
73
      DAL->AddJoinedArg(nullptr, MArch, "armv7a");
2338
199
    else if (Name == "armv7em")
2339
8
      DAL->AddJoinedArg(nullptr, MArch, "armv7em");
2340
191
    else if (Name == "armv7k")
2341
28
      DAL->AddJoinedArg(nullptr, MArch, "armv7k");
2342
163
    else if (Name == "armv7m")
2343
9
      DAL->AddJoinedArg(nullptr, MArch, "armv7m");
2344
154
    else if (Name == "armv7s")
2345
12
      DAL->AddJoinedArg(nullptr, MArch, "armv7s");
2346
20.6k
  }
2347
20.9k
2348
20.9k
  return DAL;
2349
20.9k
}
2350
2351
void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
2352
                                  ArgStringList &CmdArgs,
2353
10
                                  bool ForceLinkBuiltinRT) const {
2354
  // Embedded targets are simple at the moment, not supporting sanitizers and
2355
  // with different libraries for each member of the product { static, PIC } x
2356
  // { hard-float, soft-float }
2357
10
  llvm::SmallString<32> CompilerRT = StringRef("");
2358
10
  CompilerRT +=
2359
10
      (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)
2360
3
          ? "hard"
2361
7
          : "soft";
2362
6
  CompilerRT += Args.hasArg(options::OPT_fPIC) ? 
"_pic"4
: "_static";
2363
10
2364
10
  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);
2365
10
}
2366
2367
18.1k
bool Darwin::isAlignedAllocationUnavailable() const {
2368
18.1k
  llvm::Triple::OSType OS;
2369
18.1k
2370
18.1k
  switch (TargetPlatform) {
2371
17.9k
  case MacOS: // Earlier than 10.13.
2372
17.9k
    OS = llvm::Triple::MacOSX;
2373
17.9k
    break;
2374
160
  case IPhoneOS:
2375
160
    OS = llvm::Triple::IOS;
2376
160
    break;
2377
35
  case TvOS: // Earlier than 11.0.
2378
35
    OS = llvm::Triple::TvOS;
2379
35
    break;
2380
42
  case WatchOS: // Earlier than 4.0.
2381
42
    OS = llvm::Triple::WatchOS;
2382
42
    break;
2383
18.1k
  }
2384
18.1k
2385
18.1k
  return TargetVersion < alignedAllocMinVersion(OS);
2386
18.1k
}
2387
2388
void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
2389
                                   llvm::opt::ArgStringList &CC1Args,
2390
18.1k
                                   Action::OffloadKind DeviceOffloadKind) const {
2391
  // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
2392
  // enabled or disabled aligned allocations.
2393
18.1k
  if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
2394
18.1k
                                options::OPT_fno_aligned_allocation) &&
2395
18.1k
      isAlignedAllocationUnavailable())
2396
479
    CC1Args.push_back("-faligned-alloc-unavailable");
2397
18.1k
2398
18.1k
  if (SDKInfo) {
2399
    /// Pass the SDK version to the compiler when the SDK information is
2400
    /// available.
2401
9.02k
    std::string Arg;
2402
9.02k
    llvm::raw_string_ostream OS(Arg);
2403
9.02k
    OS << "-target-sdk-version=" << SDKInfo->getVersion();
2404
9.02k
    CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
2405
9.02k
  }
2406
18.1k
2407
  // Enable compatibility mode for NSItemProviderCompletionHandler in
2408
  // Foundation/NSItemProvider.h.
2409
18.1k
  CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking");
2410
18.1k
2411
  // Give static local variables in inline functions hidden visibility when
2412
  // -fvisibility-inlines-hidden is enabled.
2413
18.1k
  if (!DriverArgs.getLastArgNoClaim(
2414
18.1k
          options::OPT_fvisibility_inlines_hidden_static_local_var,
2415
18.1k
          options::OPT_fno_visibility_inlines_hidden_static_local_var))
2416
18.1k
    CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");
2417
18.1k
}
2418
2419
DerivedArgList *
2420
Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
2421
20.9k
                      Action::OffloadKind DeviceOffloadKind) const {
2422
  // First get the generic Apple args, before moving onto Darwin-specific ones.
2423
20.9k
  DerivedArgList *DAL =
2424
20.9k
      MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
2425
20.9k
  const OptTable &Opts = getDriver().getOpts();
2426
20.9k
2427
  // If no architecture is bound, none of the translations here are relevant.
2428
20.9k
  if (BoundArch.empty())
2429
263
    return DAL;
2430
20.6k
2431
  // Add an explicit version min argument for the deployment target. We do this
2432
  // after argument translation because -Xarch_ arguments may add a version min
2433
  // argument.
2434
20.6k
  AddDeploymentTarget(*DAL);
2435
20.6k
2436
  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
2437
  // FIXME: It would be far better to avoid inserting those -static arguments,
2438
  // but we can't check the deployment target in the translation code until
2439
  // it is set here.
2440
20.6k
  if (isTargetWatchOSBased() ||
2441
20.6k
      (isTargetIOSBased() && 
!isIPhoneOSVersionLT(6, 0)238
)) {
2442
1.82k
    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
2443
1.61k
      Arg *A = *it;
2444
1.61k
      ++it;
2445
1.61k
      if (A->getOption().getID() != options::OPT_mkernel &&
2446
1.60k
          A->getOption().getID() != options::OPT_fapple_kext)
2447
1.60k
        continue;
2448
6
      assert(it != ie && "unexpected argument translation");
2449
6
      A = *it;
2450
6
      assert(A->getOption().getID() == options::OPT_static &&
2451
6
             "missing expected -static argument");
2452
6
      *it = nullptr;
2453
6
      ++it;
2454
6
    }
2455
211
  }
2456
20.6k
2457
20.6k
  if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
2458
19.8k
      GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
2459
19.5k
    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
2460
19.5k
                      "libc++");
2461
20.6k
2462
  // Validate the C++ standard library choice.
2463
20.6k
  CXXStdlibType Type = GetCXXStdlibType(*DAL);
2464
20.6k
  if (Type == ToolChain::CST_Libcxx) {
2465
    // Check whether the target provides libc++.
2466
20.2k
    StringRef where;
2467
20.2k
2468
    // Complain about targeting iOS < 5.0 in any way.
2469
20.2k
    if (isTargetIOSBased() && 
isIPhoneOSVersionLT(5, 0)139
)
2470
0
      where = "iOS 5.0";
2471
20.2k
2472
20.2k
    if (where != StringRef()) {
2473
0
      getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
2474
0
    }
2475
20.2k
  }
2476
20.6k
2477
20.6k
  auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch);
2478
20.6k
  if ((Arch == llvm::Triple::arm || 
Arch == llvm::Triple::thumb20.5k
)) {
2479
127
    if (Args.hasFlag(options::OPT_fomit_frame_pointer,
2480
127
                     options::OPT_fno_omit_frame_pointer, false))
2481
2
      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
2482
2
          << "-fomit-frame-pointer" << BoundArch;
2483
127
  }
2484
20.6k
2485
20.6k
  return DAL;
2486
20.6k
}
2487
2488
18.0k
bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
2489
  // Unwind tables are not emitted if -fno-exceptions is supplied (except when
2490
  // targeting x86_64).
2491
18.0k
  return getArch() == llvm::Triple::x86_64 ||
2492
327
         (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&
2493
246
          Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
2494
246
                       true));
2495
18.0k
}
2496
2497
18.1k
bool MachO::UseDwarfDebugFlags() const {
2498
18.1k
  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
2499
37
    return S[0] != '\0';
2500
18.1k
  return false;
2501
18.1k
}
2502
2503
18.3k
llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {
2504
  // Darwin uses SjLj exceptions on ARM.
2505
18.3k
  if (getTriple().getArch() != llvm::Triple::arm &&
2506
18.1k
      getTriple().getArch() != llvm::Triple::thumb)
2507
18.1k
    return llvm::ExceptionHandling::None;
2508
210
2509
  // Only watchOS uses the new DWARF/Compact unwinding method.
2510
210
  llvm::Triple Triple(ComputeLLVMTriple(Args));
2511
210
  if (Triple.isWatchABI())
2512
48
    return llvm::ExceptionHandling::DwarfCFI;
2513
162
2514
162
  return llvm::ExceptionHandling::SjLj;
2515
162
}
2516
2517
7
bool Darwin::SupportsEmbeddedBitcode() const {
2518
7
  assert(TargetInitialized && "Target not initialized!");
2519
7
  if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
2520
1
    return false;
2521
6
  return true;
2522
6
}
2523
2524
36.2k
bool MachO::isPICDefault() const { return true; }
2525
2526
18.1k
bool MachO::isPIEDefault() const { return false; }
2527
2528
18.1k
bool MachO::isPICDefaultForced() const {
2529
18.1k
  return (getArch() == llvm::Triple::x86_64 ||
2530
344
          getArch() == llvm::Triple::aarch64);
2531
18.1k
}
2532
2533
18.0k
bool MachO::SupportsProfiling() const {
2534
  // Profiling instrumentation is only supported on x86.
2535
18.0k
  return getTriple().isX86();
2536
18.0k
}
2537
2538
void Darwin::addMinVersionArgs(const ArgList &Args,
2539
85
                               ArgStringList &CmdArgs) const {
2540
85
  VersionTuple TargetVersion = getTargetVersion();
2541
85
2542
85
  if (isTargetWatchOS())
2543
8
    CmdArgs.push_back("-watchos_version_min");
2544
77
  else if (isTargetWatchOSSimulator())
2545
3
    CmdArgs.push_back("-watchos_simulator_version_min");
2546
74
  else if (isTargetTvOS())
2547
7
    CmdArgs.push_back("-tvos_version_min");
2548
67
  else if (isTargetTvOSSimulator())
2549
3
    CmdArgs.push_back("-tvos_simulator_version_min");
2550
64
  else if (isTargetIOSSimulator())
2551
7
    CmdArgs.push_back("-ios_simulator_version_min");
2552
57
  else if (isTargetIOSBased())
2553
20
    CmdArgs.push_back("-iphoneos_version_min");
2554
37
  else {
2555
37
    assert(isTargetMacOS() && "unexpected target");
2556
37
    CmdArgs.push_back("-macosx_version_min");
2557
37
  }
2558
85
2559
85
  VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
2560
85
  if (!MinTgtVers.empty() && 
MinTgtVers > TargetVersion4
)
2561
1
    TargetVersion = MinTgtVers;
2562
85
  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
2563
85
}
2564
2565
static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
2566
3.33k
                                   Darwin::DarwinEnvironmentKind Environment) {
2567
3.33k
  switch (Platform) {
2568
3.25k
  case Darwin::MacOS:
2569
3.25k
    return "macos";
2570
61
  case Darwin::IPhoneOS:
2571
61
    if (Environment == Darwin::NativeEnvironment ||
2572
10
        Environment == Darwin::Simulator)
2573
61
      return "ios";
2574
    // FIXME: Add macCatalyst support here ("\"mac catalyst\"").
2575
0
    llvm_unreachable("macCatalyst isn't yet supported");
2576
10
  case Darwin::TvOS:
2577
10
    return "tvos";
2578
10
  case Darwin::WatchOS:
2579
10
    return "watchos";
2580
0
  }
2581
0
  llvm_unreachable("invalid platform");
2582
0
}
2583
2584
void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
2585
3.33k
                                    llvm::opt::ArgStringList &CmdArgs) const {
2586
  // -platform_version <platform> <target_version> <sdk_version>
2587
  // Both the target and SDK version support only up to 3 components.
2588
3.33k
  CmdArgs.push_back("-platform_version");
2589
3.33k
  std::string PlatformName = getPlatformName(TargetPlatform, TargetEnvironment);
2590
3.33k
  if (TargetEnvironment == Darwin::Simulator)
2591
20
    PlatformName += "-simulator";
2592
3.33k
  CmdArgs.push_back(Args.MakeArgString(PlatformName));
2593
3.33k
  VersionTuple TargetVersion = getTargetVersion().withoutBuild();
2594
3.33k
  VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
2595
3.33k
  if (!MinTgtVers.empty() && 
MinTgtVers > TargetVersion13
)
2596
12
    TargetVersion = MinTgtVers;
2597
3.33k
  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
2598
3.33k
  if (SDKInfo) {
2599
2.75k
    VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
2600
2.75k
    CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
2601
585
  } else {
2602
    // Use a blank SDK version if it's not present.
2603
585
    CmdArgs.push_back("0.0.0");
2604
585
  }
2605
3.33k
}
2606
2607
// Add additional link args for the -dynamiclib option.
2608
static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args,
2609
190
                                  ArgStringList &CmdArgs) {
2610
  // Derived from darwin_dylib1 spec.
2611
190
  if (D.isTargetIPhoneOS()) {
2612
3
    if (D.isIPhoneOSVersionLT(3, 1))
2613
1
      CmdArgs.push_back("-ldylib1.o");
2614
3
    return;
2615
3
  }
2616
187
2617
187
  if (!D.isTargetMacOS())
2618
1
    return;
2619
186
  if (D.isMacosxVersionLT(10, 5))
2620
2
    CmdArgs.push_back("-ldylib1.o");
2621
184
  else if (D.isMacosxVersionLT(10, 6))
2622
1
    CmdArgs.push_back("-ldylib1.10.5.o");
2623
186
}
2624
2625
// Add additional link args for the -bundle option.
2626
static void addBundleLinkArgs(const Darwin &D, const ArgList &Args,
2627
5
                              ArgStringList &CmdArgs) {
2628
5
  if (Args.hasArg(options::OPT_static))
2629
0
    return;
2630
  // Derived from darwin_bundle1 spec.
2631
5
  if ((D.isTargetIPhoneOS() && 
D.isIPhoneOSVersionLT(3, 1)2
) ||
2632
4
      (D.isTargetMacOS() && 
D.isMacosxVersionLT(10, 6)2
))
2633
2
    CmdArgs.push_back("-lbundle1.o");
2634
5
}
2635
2636
// Add additional link args for the -pg option.
2637
static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,
2638
3
                                   ArgStringList &CmdArgs) {
2639
3
  if (D.isTargetMacOS() && 
D.isMacosxVersionLT(10, 9)2
) {
2640
1
    if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) ||
2641
1
        Args.hasArg(options::OPT_preload)) {
2642
0
      CmdArgs.push_back("-lgcrt0.o");
2643
1
    } else {
2644
1
      CmdArgs.push_back("-lgcrt1.o");
2645
1
2646
      // darwin_crt2 spec is empty.
2647
1
    }
2648
    // By default on OS X 10.8 and later, we don't link with a crt1.o
2649
    // file and the linker knows to use _main as the entry point.  But,
2650
    // when compiling with -pg, we need to link with the gcrt1.o file,
2651
    // so pass the -no_new_main option to tell the linker to use the
2652
    // "start" symbol as the entry point.
2653
1
    if (!D.isMacosxVersionLT(10, 8))
2654
1
      CmdArgs.push_back("-no_new_main");
2655
2
  } else {
2656
2
    D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
2657
2
        << D.isTargetMacOS();
2658
2
  }
2659
3
}
2660
2661
static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args,
2662
3.21k
                                  ArgStringList &CmdArgs) {
2663
  // Derived from darwin_crt1 spec.
2664
3.21k
  if (D.isTargetIPhoneOS()) {
2665
72
    if (D.getArch() == llvm::Triple::aarch64)
2666
31
      ; // iOS does not need any crt1 files for arm64
2667
41
    else if (D.isIPhoneOSVersionLT(3, 1))
2668
2
      CmdArgs.push_back("-lcrt1.o");
2669
39
    else if (D.isIPhoneOSVersionLT(6, 0))
2670
19
      CmdArgs.push_back("-lcrt1.3.1.o");
2671
72
    return;
2672
72
  }
2673
3.13k
2674
3.13k
  if (!D.isTargetMacOS())
2675
45
    return;
2676
3.09k
  if (D.isMacosxVersionLT(10, 5))
2677
2
    CmdArgs.push_back("-lcrt1.o");
2678
3.09k
  else if (D.isMacosxVersionLT(10, 6))
2679
12
    CmdArgs.push_back("-lcrt1.10.5.o");
2680
3.08k
  else if (D.isMacosxVersionLT(10, 8))
2681
56
    CmdArgs.push_back("-lcrt1.10.6.o");
2682
  // darwin_crt2 spec is empty.
2683
3.09k
}
2684
2685
void Darwin::addStartObjectFileArgs(const ArgList &Args,
2686
3.41k
                                    ArgStringList &CmdArgs) const {
2687
  // Derived from startfile spec.
2688
3.41k
  if (Args.hasArg(options::OPT_dynamiclib))
2689
190
    addDynamicLibLinkArgs(*this, Args, CmdArgs);
2690
3.22k
  else if (Args.hasArg(options::OPT_bundle))
2691
5
    addBundleLinkArgs(*this, Args, CmdArgs);
2692
3.21k
  else if (Args.hasArg(options::OPT_pg) && 
SupportsProfiling()3
)
2693
3
    addPgProfilingLinkArgs(*this, Args, CmdArgs);
2694
3.21k
  else if (Args.hasArg(options::OPT_static) ||
2695
3.21k
           Args.hasArg(options::OPT_object) ||
2696
3.21k
           Args.hasArg(options::OPT_preload))
2697
5
    CmdArgs.push_back("-lcrt0.o");
2698
3.21k
  else
2699
3.21k
    addDefaultCRTLinkArgs(*this, Args, CmdArgs);
2700
3.41k
2701
3.41k
  if (isTargetMacOS() && 
Args.hasArg(options::OPT_shared_libgcc)3.28k
&&
2702
0
      isMacosxVersionLT(10, 5)) {
2703
0
    const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
2704
0
    CmdArgs.push_back(Str);
2705
0
  }
2706
3.41k
}
2707
2708
1.26k
void Darwin::CheckObjCARC() const {
2709
1.26k
  if (isTargetIOSBased() || 
isTargetWatchOSBased()1.25k
||
2710
1.25k
      (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
2711
1.26k
    return;
2712
3
  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
2713
3
}
2714
2715
20.6k
SanitizerMask Darwin::getSupportedSanitizers() const {
2716
20.6k
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
2717
20.6k
  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
2718
20.6k
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
2719
20.6k
  Res |= SanitizerKind::Address;
2720
20.6k
  Res |= SanitizerKind::PointerCompare;
2721
20.6k
  Res |= SanitizerKind::PointerSubtract;
2722
20.6k
  Res |= SanitizerKind::Leak;
2723
20.6k
  Res |= SanitizerKind::Fuzzer;
2724
20.6k
  Res |= SanitizerKind::FuzzerNoLink;
2725
20.6k
  Res |= SanitizerKind::Function;
2726
20.6k
  Res |= SanitizerKind::ObjCCast;
2727
20.6k
2728
  // Prior to 10.9, macOS shipped a version of the C++ standard library without
2729
  // C++11 support. The same is true of iOS prior to version 5. These OS'es are
2730
  // incompatible with -fsanitize=vptr.
2731
20.6k
  if (!(isTargetMacOS() && 
isMacosxVersionLT(10, 9)20.3k
)
2732
20.3k
      && !(isTargetIPhoneOS() && 
isIPhoneOSVersionLT(5, 0)166
))
2733
20.3k
    Res |= SanitizerKind::Vptr;
2734
20.6k
2735
20.6k
  if ((IsX86_64 || 
IsAArch64361
) &&
isTargetMacOS()20.3k
) {
2736
20.2k
    Res |= SanitizerKind::Thread;
2737
408
  } else if (isTargetIOSSimulator() || 
isTargetTvOSSimulator()343
) {
2738
69
    if (IsX86_64)
2739
50
      Res |= SanitizerKind::Thread;
2740
69
  }
2741
20.6k
  return Res;
2742
20.6k
}
2743
2744
247
void Darwin::printVerboseInfo(raw_ostream &OS) const {
2745
247
  CudaInstallation.print(OS);
2746
247
  RocmInstallation.print(OS);
2747
247
}