Coverage Report

Created: 2020-02-25 14:32

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