1 //===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 #include "Arch/AArch64.h"
12 #include "CommonArgs.h"
13 #include "clang/Basic/AlignedAllocation.h"
14 #include "clang/Basic/ObjCRuntime.h"
15 #include "clang/Config/config.h"
16 #include "clang/Driver/Compilation.h"
17 #include "clang/Driver/Driver.h"
18 #include "clang/Driver/DriverDiagnostic.h"
19 #include "clang/Driver/Options.h"
20 #include "clang/Driver/SanitizerArgs.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Option/ArgList.h"
23 #include "llvm/ProfileData/InstrProf.h"
24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/ScopedPrinter.h"
26 #include "llvm/Support/Threading.h"
27 #include "llvm/Support/VirtualFileSystem.h"
28 #include "llvm/TargetParser/TargetParser.h"
29 #include "llvm/TargetParser/Triple.h"
30 #include <cstdlib> // ::getenv
32 using namespace clang::driver
;
33 using namespace clang::driver::tools
;
34 using namespace clang::driver::toolchains
;
35 using namespace clang
;
36 using namespace llvm::opt
;
38 static VersionTuple
minimumMacCatalystDeploymentTarget() {
39 return VersionTuple(13, 1);
42 llvm::Triple::ArchType
darwin::getArchTypeForMachOArchName(StringRef Str
) {
43 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
44 // archs which Darwin doesn't use.
46 // The matching this routine does is fairly pointless, since it is neither the
47 // complete architecture list, nor a reasonable subset. The problem is that
48 // historically the driver accepts this and also ties its -march=
49 // handling to the architecture name, so we need to be careful before removing
52 // This code must be kept in sync with Clang's Darwin specific argument
55 return llvm::StringSwitch
<llvm::Triple::ArchType
>(Str
)
56 .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86
)
57 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
59 .Cases("x86_64", "x86_64h", llvm::Triple::x86_64
)
60 // This is derived from the driver.
61 .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm
)
62 .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm
)
63 .Cases("armv7s", "xscale", llvm::Triple::arm
)
64 .Cases("arm64", "arm64e", llvm::Triple::aarch64
)
65 .Case("arm64_32", llvm::Triple::aarch64_32
)
66 .Case("r600", llvm::Triple::r600
)
67 .Case("amdgcn", llvm::Triple::amdgcn
)
68 .Case("nvptx", llvm::Triple::nvptx
)
69 .Case("nvptx64", llvm::Triple::nvptx64
)
70 .Case("amdil", llvm::Triple::amdil
)
71 .Case("spir", llvm::Triple::spir
)
72 .Default(llvm::Triple::UnknownArch
);
75 void darwin::setTripleTypeForMachOArchName(llvm::Triple
&T
, StringRef Str
,
76 const ArgList
&Args
) {
77 const llvm::Triple::ArchType Arch
= getArchTypeForMachOArchName(Str
);
78 llvm::ARM::ArchKind ArchKind
= llvm::ARM::parseArch(Str
);
80 if (Arch
!= llvm::Triple::UnknownArch
)
83 if (ArchKind
== llvm::ARM::ArchKind::ARMV6M
||
84 ArchKind
== llvm::ARM::ArchKind::ARMV7M
||
85 ArchKind
== llvm::ARM::ArchKind::ARMV7EM
) {
86 // Don't reject these -version-min= if we have the appropriate triple.
87 if (T
.getOS() == llvm::Triple::IOS
)
88 for (Arg
*A
: Args
.filtered(options::OPT_mios_version_min_EQ
))
89 A
->ignoreTargetSpecific();
90 if (T
.getOS() == llvm::Triple::WatchOS
)
91 for (Arg
*A
: Args
.filtered(options::OPT_mwatchos_version_min_EQ
))
92 A
->ignoreTargetSpecific();
93 if (T
.getOS() == llvm::Triple::TvOS
)
94 for (Arg
*A
: Args
.filtered(options::OPT_mtvos_version_min_EQ
))
95 A
->ignoreTargetSpecific();
97 T
.setOS(llvm::Triple::UnknownOS
);
98 T
.setObjectFormat(llvm::Triple::MachO
);
102 void darwin::Assembler::ConstructJob(Compilation
&C
, const JobAction
&JA
,
103 const InputInfo
&Output
,
104 const InputInfoList
&Inputs
,
106 const char *LinkingOutput
) const {
107 const llvm::Triple
&T(getToolChain().getTriple());
109 ArgStringList CmdArgs
;
111 assert(Inputs
.size() == 1 && "Unexpected number of inputs.");
112 const InputInfo
&Input
= Inputs
[0];
114 // Determine the original source input.
115 const Action
*SourceAction
= &JA
;
116 while (SourceAction
->getKind() != Action::InputClass
) {
117 assert(!SourceAction
->getInputs().empty() && "unexpected root action!");
118 SourceAction
= SourceAction
->getInputs()[0];
121 // If -fno-integrated-as is used add -Q to the darwin assembler driver to make
122 // sure it runs its system assembler not clang's integrated assembler.
123 // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as.
124 // FIXME: at run-time detect assembler capabilities or rely on version
125 // information forwarded by -target-assembler-version.
126 if (Args
.hasArg(options::OPT_fno_integrated_as
)) {
127 if (!(T
.isMacOSX() && T
.isMacOSXVersionLT(10, 7)))
128 CmdArgs
.push_back("-Q");
131 // Forward -g, assuming we are dealing with an actual assembly file.
132 if (SourceAction
->getType() == types::TY_Asm
||
133 SourceAction
->getType() == types::TY_PP_Asm
) {
134 if (Args
.hasArg(options::OPT_gstabs
))
135 CmdArgs
.push_back("--gstabs");
136 else if (Args
.hasArg(options::OPT_g_Group
))
137 CmdArgs
.push_back("-g");
140 // Derived from asm spec.
141 AddMachOArch(Args
, CmdArgs
);
143 // Use -force_cpusubtype_ALL on x86 by default.
144 if (T
.isX86() || Args
.hasArg(options::OPT_force__cpusubtype__ALL
))
145 CmdArgs
.push_back("-force_cpusubtype_ALL");
147 if (getToolChain().getArch() != llvm::Triple::x86_64
&&
148 (((Args
.hasArg(options::OPT_mkernel
) ||
149 Args
.hasArg(options::OPT_fapple_kext
)) &&
150 getMachOToolChain().isKernelStatic()) ||
151 Args
.hasArg(options::OPT_static
)))
152 CmdArgs
.push_back("-static");
154 Args
.AddAllArgValues(CmdArgs
, options::OPT_Wa_COMMA
, options::OPT_Xassembler
);
156 assert(Output
.isFilename() && "Unexpected lipo output.");
157 CmdArgs
.push_back("-o");
158 CmdArgs
.push_back(Output
.getFilename());
160 assert(Input
.isFilename() && "Invalid input.");
161 CmdArgs
.push_back(Input
.getFilename());
163 // asm_final spec is empty.
165 const char *Exec
= Args
.MakeArgString(getToolChain().GetProgramPath("as"));
166 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
167 Exec
, CmdArgs
, Inputs
, Output
));
170 void darwin::MachOTool::anchor() {}
172 void darwin::MachOTool::AddMachOArch(const ArgList
&Args
,
173 ArgStringList
&CmdArgs
) const {
174 StringRef ArchName
= getMachOToolChain().getMachOArchName(Args
);
176 // Derived from darwin_arch spec.
177 CmdArgs
.push_back("-arch");
178 CmdArgs
.push_back(Args
.MakeArgString(ArchName
));
180 // FIXME: Is this needed anymore?
181 if (ArchName
== "arm")
182 CmdArgs
.push_back("-force_cpusubtype_ALL");
185 bool darwin::Linker::NeedsTempPath(const InputInfoList
&Inputs
) const {
186 // We only need to generate a temp path for LTO if we aren't compiling object
187 // files. When compiling source files, we run 'dsymutil' after linking. We
188 // don't run 'dsymutil' when compiling object files.
189 for (const auto &Input
: Inputs
)
190 if (Input
.getType() != types::TY_Object
)
196 /// Pass -no_deduplicate to ld64 under certain conditions:
198 /// - Either -O0 or -O1 is explicitly specified
199 /// - No -O option is specified *and* this is a compile+link (implicit -O0)
201 /// Also do *not* add -no_deduplicate when no -O option is specified and this
202 /// is just a link (we can't imply -O0)
203 static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction
, const ArgList
&Args
) {
204 if (Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
205 if (A
->getOption().matches(options::OPT_O0
))
207 if (A
->getOption().matches(options::OPT_O
))
208 return llvm::StringSwitch
<bool>(A
->getValue())
211 return false; // OPT_Ofast & OPT_O4
214 if (!IsLinkerOnlyAction
) // Implicit -O0 for compile+linker only.
219 void darwin::Linker::AddLinkArgs(Compilation
&C
, const ArgList
&Args
,
220 ArgStringList
&CmdArgs
,
221 const InputInfoList
&Inputs
,
222 VersionTuple Version
, bool LinkerIsLLD
,
223 bool UsePlatformVersion
) const {
224 const Driver
&D
= getToolChain().getDriver();
225 const toolchains::MachO
&MachOTC
= getMachOToolChain();
227 // Newer linkers support -demangle. Pass it if supported and not disabled by
229 if ((Version
>= VersionTuple(100) || LinkerIsLLD
) &&
230 !Args
.hasArg(options::OPT_Z_Xlinker__no_demangle
))
231 CmdArgs
.push_back("-demangle");
233 if (Args
.hasArg(options::OPT_rdynamic
) &&
234 (Version
>= VersionTuple(137) || LinkerIsLLD
))
235 CmdArgs
.push_back("-export_dynamic");
237 // If we are using App Extension restrictions, pass a flag to the linker
238 // telling it that the compiled code has been audited.
239 if (Args
.hasFlag(options::OPT_fapplication_extension
,
240 options::OPT_fno_application_extension
, false))
241 CmdArgs
.push_back("-application_extension");
243 if (D
.isUsingLTO() && (Version
>= VersionTuple(116) || LinkerIsLLD
) &&
244 NeedsTempPath(Inputs
)) {
245 std::string TmpPathName
;
246 if (D
.getLTOMode() == LTOK_Full
) {
247 // If we are using full LTO, then automatically create a temporary file
248 // path for the linker to use, so that it's lifetime will extend past a
249 // possible dsymutil step.
251 D
.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object
));
252 } else if (D
.getLTOMode() == LTOK_Thin
)
253 // If we are using thin LTO, then create a directory instead.
254 TmpPathName
= D
.GetTemporaryDirectory("thinlto");
256 if (!TmpPathName
.empty()) {
257 auto *TmpPath
= C
.getArgs().MakeArgString(TmpPathName
);
258 C
.addTempFile(TmpPath
);
259 CmdArgs
.push_back("-object_path_lto");
260 CmdArgs
.push_back(TmpPath
);
264 // Use -lto_library option to specify the libLTO.dylib path. Try to find
265 // it in clang installed libraries. ld64 will only look at this argument
266 // when it actually uses LTO, so libLTO.dylib only needs to exist at link
267 // time if ld64 decides that it needs to use LTO.
268 // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
269 // next to it. That's ok since ld64 using a libLTO.dylib not matching the
270 // clang version won't work anyways.
271 // lld is built at the same revision as clang and statically links in
272 // LLVM libraries, so it doesn't need libLTO.dylib.
273 if (Version
>= VersionTuple(133) && !LinkerIsLLD
) {
274 // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
275 StringRef P
= llvm::sys::path::parent_path(D
.Dir
);
276 SmallString
<128> LibLTOPath(P
);
277 llvm::sys::path::append(LibLTOPath
, "lib");
278 llvm::sys::path::append(LibLTOPath
, "libLTO.dylib");
279 CmdArgs
.push_back("-lto_library");
280 CmdArgs
.push_back(C
.getArgs().MakeArgString(LibLTOPath
));
283 // ld64 version 262 and above runs the deduplicate pass by default.
284 // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe`
285 // if `!shouldLinkerNotDedup()` if LinkerIsLLD here?
286 if (Version
>= VersionTuple(262) &&
287 shouldLinkerNotDedup(C
.getJobs().empty(), Args
))
288 CmdArgs
.push_back("-no_deduplicate");
290 // Derived from the "link" spec.
291 Args
.AddAllArgs(CmdArgs
, options::OPT_static
);
292 if (!Args
.hasArg(options::OPT_static
))
293 CmdArgs
.push_back("-dynamic");
294 if (Args
.hasArg(options::OPT_fgnu_runtime
)) {
295 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
296 // here. How do we wish to handle such things?
299 if (!Args
.hasArg(options::OPT_dynamiclib
)) {
300 AddMachOArch(Args
, CmdArgs
);
301 // FIXME: Why do this only on this path?
302 Args
.AddLastArg(CmdArgs
, options::OPT_force__cpusubtype__ALL
);
304 Args
.AddLastArg(CmdArgs
, options::OPT_bundle
);
305 Args
.AddAllArgs(CmdArgs
, options::OPT_bundle__loader
);
306 Args
.AddAllArgs(CmdArgs
, options::OPT_client__name
);
309 if ((A
= Args
.getLastArg(options::OPT_compatibility__version
)) ||
310 (A
= Args
.getLastArg(options::OPT_current__version
)) ||
311 (A
= Args
.getLastArg(options::OPT_install__name
)))
312 D
.Diag(diag::err_drv_argument_only_allowed_with
) << A
->getAsString(Args
)
315 Args
.AddLastArg(CmdArgs
, options::OPT_force__flat__namespace
);
316 Args
.AddLastArg(CmdArgs
, options::OPT_keep__private__externs
);
317 Args
.AddLastArg(CmdArgs
, options::OPT_private__bundle
);
319 CmdArgs
.push_back("-dylib");
322 if ((A
= Args
.getLastArg(options::OPT_bundle
)) ||
323 (A
= Args
.getLastArg(options::OPT_bundle__loader
)) ||
324 (A
= Args
.getLastArg(options::OPT_client__name
)) ||
325 (A
= Args
.getLastArg(options::OPT_force__flat__namespace
)) ||
326 (A
= Args
.getLastArg(options::OPT_keep__private__externs
)) ||
327 (A
= Args
.getLastArg(options::OPT_private__bundle
)))
328 D
.Diag(diag::err_drv_argument_not_allowed_with
) << A
->getAsString(Args
)
331 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_compatibility__version
,
332 "-dylib_compatibility_version");
333 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_current__version
,
334 "-dylib_current_version");
336 AddMachOArch(Args
, CmdArgs
);
338 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_install__name
,
339 "-dylib_install_name");
342 Args
.AddLastArg(CmdArgs
, options::OPT_all__load
);
343 Args
.AddAllArgs(CmdArgs
, options::OPT_allowable__client
);
344 Args
.AddLastArg(CmdArgs
, options::OPT_bind__at__load
);
345 if (MachOTC
.isTargetIOSBased())
346 Args
.AddLastArg(CmdArgs
, options::OPT_arch__errors__fatal
);
347 Args
.AddLastArg(CmdArgs
, options::OPT_dead__strip
);
348 Args
.AddLastArg(CmdArgs
, options::OPT_no__dead__strip__inits__and__terms
);
349 Args
.AddAllArgs(CmdArgs
, options::OPT_dylib__file
);
350 Args
.AddLastArg(CmdArgs
, options::OPT_dynamic
);
351 Args
.AddAllArgs(CmdArgs
, options::OPT_exported__symbols__list
);
352 Args
.AddLastArg(CmdArgs
, options::OPT_flat__namespace
);
353 Args
.AddAllArgs(CmdArgs
, options::OPT_force__load
);
354 Args
.AddAllArgs(CmdArgs
, options::OPT_headerpad__max__install__names
);
355 Args
.AddAllArgs(CmdArgs
, options::OPT_image__base
);
356 Args
.AddAllArgs(CmdArgs
, options::OPT_init
);
358 // Add the deployment target.
359 if (Version
>= VersionTuple(520) || LinkerIsLLD
|| UsePlatformVersion
)
360 MachOTC
.addPlatformVersionArgs(Args
, CmdArgs
);
362 MachOTC
.addMinVersionArgs(Args
, CmdArgs
);
364 Args
.AddLastArg(CmdArgs
, options::OPT_nomultidefs
);
365 Args
.AddLastArg(CmdArgs
, options::OPT_multi__module
);
366 Args
.AddLastArg(CmdArgs
, options::OPT_single__module
);
367 Args
.AddAllArgs(CmdArgs
, options::OPT_multiply__defined
);
368 Args
.AddAllArgs(CmdArgs
, options::OPT_multiply__defined__unused
);
371 Args
.getLastArg(options::OPT_fpie
, options::OPT_fPIE
,
372 options::OPT_fno_pie
, options::OPT_fno_PIE
)) {
373 if (A
->getOption().matches(options::OPT_fpie
) ||
374 A
->getOption().matches(options::OPT_fPIE
))
375 CmdArgs
.push_back("-pie");
377 CmdArgs
.push_back("-no_pie");
380 // for embed-bitcode, use -bitcode_bundle in linker command
381 if (C
.getDriver().embedBitcodeEnabled()) {
382 // Check if the toolchain supports bitcode build flow.
383 if (MachOTC
.SupportsEmbeddedBitcode()) {
384 CmdArgs
.push_back("-bitcode_bundle");
385 // FIXME: Pass this if LinkerIsLLD too, once it implements this flag.
386 if (C
.getDriver().embedBitcodeMarkerOnly() &&
387 Version
>= VersionTuple(278)) {
388 CmdArgs
.push_back("-bitcode_process_mode");
389 CmdArgs
.push_back("marker");
392 D
.Diag(diag::err_drv_bitcode_unsupported_on_toolchain
);
395 // If GlobalISel is enabled, pass it through to LLVM.
396 if (Arg
*A
= Args
.getLastArg(options::OPT_fglobal_isel
,
397 options::OPT_fno_global_isel
)) {
398 if (A
->getOption().matches(options::OPT_fglobal_isel
)) {
399 CmdArgs
.push_back("-mllvm");
400 CmdArgs
.push_back("-global-isel");
401 // Disable abort and fall back to SDAG silently.
402 CmdArgs
.push_back("-mllvm");
403 CmdArgs
.push_back("-global-isel-abort=0");
407 if (Args
.hasArg(options::OPT_mkernel
) ||
408 Args
.hasArg(options::OPT_fapple_kext
) ||
409 Args
.hasArg(options::OPT_ffreestanding
)) {
410 CmdArgs
.push_back("-mllvm");
411 CmdArgs
.push_back("-disable-atexit-based-global-dtor-lowering");
414 Args
.AddLastArg(CmdArgs
, options::OPT_prebind
);
415 Args
.AddLastArg(CmdArgs
, options::OPT_noprebind
);
416 Args
.AddLastArg(CmdArgs
, options::OPT_nofixprebinding
);
417 Args
.AddLastArg(CmdArgs
, options::OPT_prebind__all__twolevel__modules
);
418 Args
.AddLastArg(CmdArgs
, options::OPT_read__only__relocs
);
419 Args
.AddAllArgs(CmdArgs
, options::OPT_sectcreate
);
420 Args
.AddAllArgs(CmdArgs
, options::OPT_sectorder
);
421 Args
.AddAllArgs(CmdArgs
, options::OPT_seg1addr
);
422 Args
.AddAllArgs(CmdArgs
, options::OPT_segprot
);
423 Args
.AddAllArgs(CmdArgs
, options::OPT_segaddr
);
424 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__only__addr
);
425 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__write__addr
);
426 Args
.AddAllArgs(CmdArgs
, options::OPT_seg__addr__table
);
427 Args
.AddAllArgs(CmdArgs
, options::OPT_seg__addr__table__filename
);
428 Args
.AddAllArgs(CmdArgs
, options::OPT_sub__library
);
429 Args
.AddAllArgs(CmdArgs
, options::OPT_sub__umbrella
);
431 // Give --sysroot= preference, over the Apple specific behavior to also use
432 // --isysroot as the syslibroot.
433 // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we
434 // prioritise command line arguments over configuration of `DEFAULT_SYSROOT`.
435 if (const Arg
*A
= Args
.getLastArg(options::OPT__sysroot_EQ
)) {
436 CmdArgs
.push_back("-syslibroot");
437 CmdArgs
.push_back(A
->getValue());
438 } else if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
439 CmdArgs
.push_back("-syslibroot");
440 CmdArgs
.push_back(A
->getValue());
441 } else if (StringRef sysroot
= C
.getSysRoot(); sysroot
!= "") {
442 CmdArgs
.push_back("-syslibroot");
443 CmdArgs
.push_back(C
.getArgs().MakeArgString(sysroot
));
446 Args
.AddLastArg(CmdArgs
, options::OPT_twolevel__namespace
);
447 Args
.AddLastArg(CmdArgs
, options::OPT_twolevel__namespace__hints
);
448 Args
.AddAllArgs(CmdArgs
, options::OPT_umbrella
);
449 Args
.AddAllArgs(CmdArgs
, options::OPT_undefined
);
450 Args
.AddAllArgs(CmdArgs
, options::OPT_unexported__symbols__list
);
451 Args
.AddAllArgs(CmdArgs
, options::OPT_weak__reference__mismatches
);
452 Args
.AddLastArg(CmdArgs
, options::OPT_X_Flag
);
453 Args
.AddAllArgs(CmdArgs
, options::OPT_y
);
454 Args
.AddLastArg(CmdArgs
, options::OPT_w
);
455 Args
.AddAllArgs(CmdArgs
, options::OPT_pagezero__size
);
456 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__
);
457 Args
.AddLastArg(CmdArgs
, options::OPT_seglinkedit
);
458 Args
.AddLastArg(CmdArgs
, options::OPT_noseglinkedit
);
459 Args
.AddAllArgs(CmdArgs
, options::OPT_sectalign
);
460 Args
.AddAllArgs(CmdArgs
, options::OPT_sectobjectsymbols
);
461 Args
.AddAllArgs(CmdArgs
, options::OPT_segcreate
);
462 Args
.AddLastArg(CmdArgs
, options::OPT_why_load
);
463 Args
.AddLastArg(CmdArgs
, options::OPT_whatsloaded
);
464 Args
.AddAllArgs(CmdArgs
, options::OPT_dylinker__install__name
);
465 Args
.AddLastArg(CmdArgs
, options::OPT_dylinker
);
466 Args
.AddLastArg(CmdArgs
, options::OPT_Mach
);
469 if (auto *CSPGOGenerateArg
= getLastCSProfileGenerateArg(Args
)) {
470 SmallString
<128> Path(CSPGOGenerateArg
->getNumValues() == 0
472 : CSPGOGenerateArg
->getValue());
473 llvm::sys::path::append(Path
, "default_%m.profraw");
474 CmdArgs
.push_back("--cs-profile-generate");
475 CmdArgs
.push_back(Args
.MakeArgString(Twine("--cs-profile-path=") + Path
));
476 } else if (auto *ProfileUseArg
= getLastProfileUseArg(Args
)) {
477 SmallString
<128> Path(
478 ProfileUseArg
->getNumValues() == 0 ? "" : ProfileUseArg
->getValue());
479 if (Path
.empty() || llvm::sys::fs::is_directory(Path
))
480 llvm::sys::path::append(Path
, "default.profdata");
481 CmdArgs
.push_back(Args
.MakeArgString(Twine("--cs-profile-path=") + Path
));
484 auto *CodeGenDataGenArg
=
485 Args
.getLastArg(options::OPT_fcodegen_data_generate_EQ
);
486 if (CodeGenDataGenArg
)
488 Args
.MakeArgString(Twine("--codegen-data-generate-path=") +
489 CodeGenDataGenArg
->getValue()));
493 /// Determine whether we are linking the ObjC runtime.
494 static bool isObjCRuntimeLinked(const ArgList
&Args
) {
495 if (isObjCAutoRefCount(Args
)) {
496 Args
.ClaimAllArgs(options::OPT_fobjc_link_runtime
);
499 return Args
.hasArg(options::OPT_fobjc_link_runtime
);
502 static bool checkRemarksOptions(const Driver
&D
, const ArgList
&Args
,
503 const llvm::Triple
&Triple
) {
504 // When enabling remarks, we need to error if:
505 // * The remark file is specified but we're targeting multiple architectures,
506 // which means more than one remark file is being generated.
507 bool hasMultipleInvocations
=
508 Args
.getAllArgValues(options::OPT_arch
).size() > 1;
509 bool hasExplicitOutputFile
=
510 Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
511 if (hasMultipleInvocations
&& hasExplicitOutputFile
) {
512 D
.Diag(diag::err_drv_invalid_output_with_multiple_archs
)
513 << "-foptimization-record-file";
519 static void renderRemarksOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
520 const llvm::Triple
&Triple
,
521 const InputInfo
&Output
, const JobAction
&JA
) {
522 StringRef Format
= "yaml";
523 if (const Arg
*A
= Args
.getLastArg(options::OPT_fsave_optimization_record_EQ
))
524 Format
= A
->getValue();
526 CmdArgs
.push_back("-mllvm");
527 CmdArgs
.push_back("-lto-pass-remarks-output");
528 CmdArgs
.push_back("-mllvm");
530 const Arg
*A
= Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
532 CmdArgs
.push_back(A
->getValue());
534 assert(Output
.isFilename() && "Unexpected ld output.");
536 F
= Output
.getFilename();
540 CmdArgs
.push_back(Args
.MakeArgString(F
));
544 Args
.getLastArg(options::OPT_foptimization_record_passes_EQ
)) {
545 CmdArgs
.push_back("-mllvm");
547 std::string("-lto-pass-remarks-filter=") + A
->getValue();
548 CmdArgs
.push_back(Args
.MakeArgString(Passes
));
551 if (!Format
.empty()) {
552 CmdArgs
.push_back("-mllvm");
553 Twine FormatArg
= Twine("-lto-pass-remarks-format=") + Format
;
554 CmdArgs
.push_back(Args
.MakeArgString(FormatArg
));
557 if (getLastProfileUseArg(Args
)) {
558 CmdArgs
.push_back("-mllvm");
559 CmdArgs
.push_back("-lto-pass-remarks-with-hotness");
562 Args
.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ
)) {
563 CmdArgs
.push_back("-mllvm");
565 std::string("-lto-pass-remarks-hotness-threshold=") + A
->getValue();
566 CmdArgs
.push_back(Args
.MakeArgString(Opt
));
571 static void AppendPlatformPrefix(SmallString
<128> &Path
, const llvm::Triple
&T
);
573 void darwin::Linker::ConstructJob(Compilation
&C
, const JobAction
&JA
,
574 const InputInfo
&Output
,
575 const InputInfoList
&Inputs
,
577 const char *LinkingOutput
) const {
578 assert(Output
.getType() == types::TY_Image
&& "Invalid linker output type.");
580 // If the number of arguments surpasses the system limits, we will encode the
581 // input files in a separate file, shortening the command line. To this end,
582 // build a list of input file names that can be passed via a file with the
583 // -filelist linker option.
584 llvm::opt::ArgStringList InputFileList
;
586 // The logic here is derived from gcc's behavior; most of which
587 // comes from specs (starting with link_command). Consult gcc for
589 ArgStringList CmdArgs
;
591 /// Hack(tm) to ignore linking errors when we are doing ARC migration.
592 if (Args
.hasArg(options::OPT_ccc_arcmt_check
,
593 options::OPT_ccc_arcmt_migrate
)) {
594 for (const auto &Arg
: Args
)
597 Args
.MakeArgString(getToolChain().GetProgramPath("touch"));
598 CmdArgs
.push_back(Output
.getFilename());
599 C
.addCommand(std::make_unique
<Command
>(JA
, *this,
600 ResponseFileSupport::None(), Exec
,
601 CmdArgs
, std::nullopt
, Output
));
605 VersionTuple Version
= getMachOToolChain().getLinkerVersion(Args
);
609 Args
.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD
));
611 // xrOS always uses -platform-version.
612 bool UsePlatformVersion
= getToolChain().getTriple().isXROS();
614 // I'm not sure why this particular decomposition exists in gcc, but
615 // we follow suite for ease of comparison.
616 AddLinkArgs(C
, Args
, CmdArgs
, Inputs
, Version
, LinkerIsLLD
,
619 if (willEmitRemarks(Args
) &&
620 checkRemarksOptions(getToolChain().getDriver(), Args
,
621 getToolChain().getTriple()))
622 renderRemarksOptions(Args
, CmdArgs
, getToolChain().getTriple(), Output
, JA
);
624 // Propagate the -moutline flag to the linker in LTO.
626 Args
.getLastArg(options::OPT_moutline
, options::OPT_mno_outline
)) {
627 if (A
->getOption().matches(options::OPT_moutline
)) {
628 if (getMachOToolChain().getMachOArchName(Args
) == "arm64") {
629 CmdArgs
.push_back("-mllvm");
630 CmdArgs
.push_back("-enable-machine-outliner");
633 // Disable all outlining behaviour if we have mno-outline. We need to do
634 // this explicitly, because targets which support default outlining will
635 // try to do work if we don't.
636 CmdArgs
.push_back("-mllvm");
637 CmdArgs
.push_back("-enable-machine-outliner=never");
641 // Outline from linkonceodr functions by default in LTO, whenever the outliner
642 // is enabled. Note that the target may enable the machine outliner
643 // independently of -moutline.
644 CmdArgs
.push_back("-mllvm");
645 CmdArgs
.push_back("-enable-linkonceodr-outlining");
647 // Propagate codegen data flags to the linker for the LLVM backend.
648 auto *CodeGenDataGenArg
=
649 Args
.getLastArg(options::OPT_fcodegen_data_generate_EQ
);
650 auto *CodeGenDataUseArg
= Args
.getLastArg(options::OPT_fcodegen_data_use_EQ
);
652 // We only allow one of them to be specified.
653 const Driver
&D
= getToolChain().getDriver();
654 if (CodeGenDataGenArg
&& CodeGenDataUseArg
)
655 D
.Diag(diag::err_drv_argument_not_allowed_with
)
656 << CodeGenDataGenArg
->getAsString(Args
)
657 << CodeGenDataUseArg
->getAsString(Args
);
659 // For codegen data gen, the output file is passed to the linker
660 // while a boolean flag is passed to the LLVM backend.
661 if (CodeGenDataGenArg
) {
662 CmdArgs
.push_back("-mllvm");
663 CmdArgs
.push_back("-codegen-data-generate");
666 // For codegen data use, the input file is passed to the LLVM backend.
667 if (CodeGenDataUseArg
) {
668 CmdArgs
.push_back("-mllvm");
669 CmdArgs
.push_back(Args
.MakeArgString(Twine("-codegen-data-use-path=") +
670 CodeGenDataUseArg
->getValue()));
673 // Setup statistics file output.
674 SmallString
<128> StatsFile
=
675 getStatsFileName(Args
, Output
, Inputs
[0], getToolChain().getDriver());
676 if (!StatsFile
.empty()) {
677 CmdArgs
.push_back("-mllvm");
678 CmdArgs
.push_back(Args
.MakeArgString("-lto-stats-file=" + StatsFile
.str()));
681 // It seems that the 'e' option is completely ignored for dynamic executables
682 // (the default), and with static executables, the last one wins, as expected.
683 Args
.addAllArgs(CmdArgs
, {options::OPT_d_Flag
, options::OPT_s
, options::OPT_t
,
684 options::OPT_Z_Flag
, options::OPT_u_Group
});
686 // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
687 // members of static archive libraries which implement Objective-C classes or
689 if (Args
.hasArg(options::OPT_ObjC
) || Args
.hasArg(options::OPT_ObjCXX
))
690 CmdArgs
.push_back("-ObjC");
692 CmdArgs
.push_back("-o");
693 CmdArgs
.push_back(Output
.getFilename());
695 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nostartfiles
))
696 getMachOToolChain().addStartObjectFileArgs(Args
, CmdArgs
);
698 Args
.AddAllArgs(CmdArgs
, options::OPT_L
);
700 AddLinkerInputs(getToolChain(), Inputs
, Args
, CmdArgs
, JA
);
701 // Build the input file for -filelist (list of linker input files) in case we
703 for (const auto &II
: Inputs
) {
704 if (!II
.isFilename()) {
705 // This is a linker input argument.
706 // We cannot mix input arguments and file names in a -filelist input, thus
707 // we prematurely stop our list (remaining files shall be passed as
709 if (InputFileList
.size() > 0)
715 InputFileList
.push_back(II
.getFilename());
718 // Additional linker set-up and flags for Fortran. This is required in order
719 // to generate executables.
720 if (getToolChain().getDriver().IsFlangMode() &&
721 !Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
722 addFortranRuntimeLibraryPath(getToolChain(), Args
, CmdArgs
);
723 addFortranRuntimeLibs(getToolChain(), Args
, CmdArgs
);
726 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
))
727 addOpenMPRuntime(C
, CmdArgs
, getToolChain(), Args
);
729 if (isObjCRuntimeLinked(Args
) &&
730 !Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
731 // We use arclite library for both ARC and subscripting support.
732 getMachOToolChain().AddLinkARCArgs(Args
, CmdArgs
);
734 CmdArgs
.push_back("-framework");
735 CmdArgs
.push_back("Foundation");
737 CmdArgs
.push_back("-lobjc");
741 CmdArgs
.push_back("-arch_multiple");
742 CmdArgs
.push_back("-final_output");
743 CmdArgs
.push_back(LinkingOutput
);
746 if (Args
.hasArg(options::OPT_fnested_functions
))
747 CmdArgs
.push_back("-allow_stack_execute");
749 getMachOToolChain().addProfileRTLibs(Args
, CmdArgs
);
751 StringRef Parallelism
= getLTOParallelism(Args
, getToolChain().getDriver());
752 if (!Parallelism
.empty()) {
753 CmdArgs
.push_back("-mllvm");
754 unsigned NumThreads
=
755 llvm::get_threadpool_strategy(Parallelism
)->compute_thread_count();
756 CmdArgs
.push_back(Args
.MakeArgString("-threads=" + Twine(NumThreads
)));
759 if (getToolChain().ShouldLinkCXXStdlib(Args
))
760 getToolChain().AddCXXStdlibLibArgs(Args
, CmdArgs
);
762 bool NoStdOrDefaultLibs
=
763 Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
);
764 bool ForceLinkBuiltins
= Args
.hasArg(options::OPT_fapple_link_rtlib
);
765 if (!NoStdOrDefaultLibs
|| ForceLinkBuiltins
) {
766 // link_ssp spec is empty.
768 // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then
769 // we just want to link the builtins, not the other libs like libSystem.
770 if (NoStdOrDefaultLibs
&& ForceLinkBuiltins
) {
771 getMachOToolChain().AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
773 // Let the tool chain choose which runtime library to link.
774 getMachOToolChain().AddLinkRuntimeLibArgs(Args
, CmdArgs
,
777 // No need to do anything for pthreads. Claim argument to avoid warning.
778 Args
.ClaimAllArgs(options::OPT_pthread
);
779 Args
.ClaimAllArgs(options::OPT_pthreads
);
783 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nostartfiles
)) {
784 // endfile_spec is empty.
787 Args
.AddAllArgs(CmdArgs
, options::OPT_T_Group
);
788 Args
.AddAllArgs(CmdArgs
, options::OPT_F
);
790 // -iframework should be forwarded as -F.
791 for (const Arg
*A
: Args
.filtered(options::OPT_iframework
))
792 CmdArgs
.push_back(Args
.MakeArgString(std::string("-F") + A
->getValue()));
794 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
795 if (Arg
*A
= Args
.getLastArg(options::OPT_fveclib
)) {
796 if (A
->getValue() == StringRef("Accelerate")) {
797 CmdArgs
.push_back("-framework");
798 CmdArgs
.push_back("Accelerate");
803 // Add non-standard, platform-specific search paths, e.g., for DriverKit:
804 // -L<sysroot>/System/DriverKit/usr/lib
805 // -F<sysroot>/System/DriverKit/System/Library/Framework
807 bool NonStandardSearchPath
= false;
808 const auto &Triple
= getToolChain().getTriple();
809 if (Triple
.isDriverKit()) {
810 // ld64 fixed the implicit -F and -L paths in ld64-605.1+.
811 NonStandardSearchPath
=
812 Version
.getMajor() < 605 ||
813 (Version
.getMajor() == 605 && Version
.getMinor().value_or(0) < 1);
816 if (NonStandardSearchPath
) {
817 if (auto *Sysroot
= Args
.getLastArg(options::OPT_isysroot
)) {
818 auto AddSearchPath
= [&](StringRef Flag
, StringRef SearchPath
) {
819 SmallString
<128> P(Sysroot
->getValue());
820 AppendPlatformPrefix(P
, Triple
);
821 llvm::sys::path::append(P
, SearchPath
);
822 if (getToolChain().getVFS().exists(P
)) {
823 CmdArgs
.push_back(Args
.MakeArgString(Flag
+ P
));
826 AddSearchPath("-L", "/usr/lib");
827 AddSearchPath("-F", "/System/Library/Frameworks");
832 ResponseFileSupport ResponseSupport
;
833 if (Version
>= VersionTuple(705) || LinkerIsLLD
) {
834 ResponseSupport
= ResponseFileSupport::AtFileUTF8();
836 // For older versions of the linker, use the legacy filelist method instead.
837 ResponseSupport
= {ResponseFileSupport::RF_FileList
, llvm::sys::WEM_UTF8
,
841 std::unique_ptr
<Command
> Cmd
= std::make_unique
<Command
>(
842 JA
, *this, ResponseSupport
, Exec
, CmdArgs
, Inputs
, Output
);
843 Cmd
->setInputFileList(std::move(InputFileList
));
844 C
.addCommand(std::move(Cmd
));
847 void darwin::StaticLibTool::ConstructJob(Compilation
&C
, const JobAction
&JA
,
848 const InputInfo
&Output
,
849 const InputInfoList
&Inputs
,
851 const char *LinkingOutput
) const {
852 const Driver
&D
= getToolChain().getDriver();
854 // Silence warning for "clang -g foo.o -o foo"
855 Args
.ClaimAllArgs(options::OPT_g_Group
);
856 // and "clang -emit-llvm foo.o -o foo"
857 Args
.ClaimAllArgs(options::OPT_emit_llvm
);
858 // and for "clang -w foo.o -o foo". Other warning options are already
859 // handled somewhere else.
860 Args
.ClaimAllArgs(options::OPT_w
);
861 // Silence warnings when linking C code with a C++ '-stdlib' argument.
862 Args
.ClaimAllArgs(options::OPT_stdlib_EQ
);
864 // libtool <options> <output_file> <input_files>
865 ArgStringList CmdArgs
;
866 // Create and insert file members with a deterministic index.
867 CmdArgs
.push_back("-static");
868 CmdArgs
.push_back("-D");
869 CmdArgs
.push_back("-no_warning_for_no_symbols");
870 CmdArgs
.push_back("-o");
871 CmdArgs
.push_back(Output
.getFilename());
873 for (const auto &II
: Inputs
) {
874 if (II
.isFilename()) {
875 CmdArgs
.push_back(II
.getFilename());
879 // Delete old output archive file if it already exists before generating a new
881 const auto *OutputFileName
= Output
.getFilename();
882 if (Output
.isFilename() && llvm::sys::fs::exists(OutputFileName
)) {
883 if (std::error_code EC
= llvm::sys::fs::remove(OutputFileName
)) {
884 D
.Diag(diag::err_drv_unable_to_remove_file
) << EC
.message();
889 const char *Exec
= Args
.MakeArgString(getToolChain().GetStaticLibToolPath());
890 C
.addCommand(std::make_unique
<Command
>(JA
, *this,
891 ResponseFileSupport::AtFileUTF8(),
892 Exec
, CmdArgs
, Inputs
, Output
));
895 void darwin::Lipo::ConstructJob(Compilation
&C
, const JobAction
&JA
,
896 const InputInfo
&Output
,
897 const InputInfoList
&Inputs
,
899 const char *LinkingOutput
) const {
900 ArgStringList CmdArgs
;
902 CmdArgs
.push_back("-create");
903 assert(Output
.isFilename() && "Unexpected lipo output.");
905 CmdArgs
.push_back("-output");
906 CmdArgs
.push_back(Output
.getFilename());
908 for (const auto &II
: Inputs
) {
909 assert(II
.isFilename() && "Unexpected lipo input.");
910 CmdArgs
.push_back(II
.getFilename());
913 const char *Exec
= Args
.MakeArgString(getToolChain().GetProgramPath("lipo"));
914 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
915 Exec
, CmdArgs
, Inputs
, Output
));
918 void darwin::Dsymutil::ConstructJob(Compilation
&C
, const JobAction
&JA
,
919 const InputInfo
&Output
,
920 const InputInfoList
&Inputs
,
922 const char *LinkingOutput
) const {
923 ArgStringList CmdArgs
;
925 CmdArgs
.push_back("-o");
926 CmdArgs
.push_back(Output
.getFilename());
928 assert(Inputs
.size() == 1 && "Unable to handle multiple inputs.");
929 const InputInfo
&Input
= Inputs
[0];
930 assert(Input
.isFilename() && "Unexpected dsymutil input.");
931 CmdArgs
.push_back(Input
.getFilename());
934 Args
.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
935 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
936 Exec
, CmdArgs
, Inputs
, Output
));
939 void darwin::VerifyDebug::ConstructJob(Compilation
&C
, const JobAction
&JA
,
940 const InputInfo
&Output
,
941 const InputInfoList
&Inputs
,
943 const char *LinkingOutput
) const {
944 ArgStringList CmdArgs
;
945 CmdArgs
.push_back("--verify");
946 CmdArgs
.push_back("--debug-info");
947 CmdArgs
.push_back("--eh-frame");
948 CmdArgs
.push_back("--quiet");
950 assert(Inputs
.size() == 1 && "Unable to handle multiple inputs.");
951 const InputInfo
&Input
= Inputs
[0];
952 assert(Input
.isFilename() && "Unexpected verify input");
954 // Grabbing the output of the earlier dsymutil run.
955 CmdArgs
.push_back(Input
.getFilename());
958 Args
.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
959 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
960 Exec
, CmdArgs
, Inputs
, Output
));
963 MachO::MachO(const Driver
&D
, const llvm::Triple
&Triple
, const ArgList
&Args
)
964 : ToolChain(D
, Triple
, Args
) {
965 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
966 getProgramPaths().push_back(getDriver().Dir
);
969 /// Darwin - Darwin tool chain for i386 and x86_64.
970 Darwin::Darwin(const Driver
&D
, const llvm::Triple
&Triple
, const ArgList
&Args
)
971 : MachO(D
, Triple
, Args
), TargetInitialized(false),
972 CudaInstallation(D
, Triple
, Args
), RocmInstallation(D
, Triple
, Args
) {}
974 types::ID
MachO::LookupTypeForExtension(StringRef Ext
) const {
975 types::ID Ty
= ToolChain::LookupTypeForExtension(Ext
);
977 // Darwin always preprocesses assembly files (unless -x is used explicitly).
978 if (Ty
== types::TY_PP_Asm
)
979 return types::TY_Asm
;
984 bool MachO::HasNativeLLVMSupport() const { return true; }
986 ToolChain::CXXStdlibType
Darwin::GetDefaultCXXStdlibType() const {
987 // Always use libc++ by default
988 return ToolChain::CST_Libcxx
;
991 /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
992 ObjCRuntime
Darwin::getDefaultObjCRuntime(bool isNonFragile
) const {
993 if (isTargetWatchOSBased())
994 return ObjCRuntime(ObjCRuntime::WatchOS
, TargetVersion
);
995 if (isTargetIOSBased())
996 return ObjCRuntime(ObjCRuntime::iOS
, TargetVersion
);
997 if (isTargetXROS()) {
998 // XROS uses the iOS runtime.
999 auto T
= llvm::Triple(Twine("arm64-apple-") +
1000 llvm::Triple::getOSTypeName(llvm::Triple::XROS
) +
1001 TargetVersion
.getAsString());
1002 return ObjCRuntime(ObjCRuntime::iOS
, T
.getiOSVersion());
1005 return ObjCRuntime(ObjCRuntime::MacOSX
, TargetVersion
);
1006 return ObjCRuntime(ObjCRuntime::FragileMacOSX
, TargetVersion
);
1009 /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
1010 bool Darwin::hasBlocksRuntime() const {
1011 if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS())
1013 else if (isTargetIOSBased())
1014 return !isIPhoneOSVersionLT(3, 2);
1016 assert(isTargetMacOSBased() && "unexpected darwin target");
1017 return !isMacosxVersionLT(10, 6);
1021 void Darwin::AddCudaIncludeArgs(const ArgList
&DriverArgs
,
1022 ArgStringList
&CC1Args
) const {
1023 CudaInstallation
->AddCudaIncludeArgs(DriverArgs
, CC1Args
);
1026 void Darwin::AddHIPIncludeArgs(const ArgList
&DriverArgs
,
1027 ArgStringList
&CC1Args
) const {
1028 RocmInstallation
->AddHIPIncludeArgs(DriverArgs
, CC1Args
);
1031 // This is just a MachO name translation routine and there's no
1032 // way to join this into ARMTargetParser without breaking all
1033 // other assumptions. Maybe MachO should consider standardising
1034 // their nomenclature.
1035 static const char *ArmMachOArchName(StringRef Arch
) {
1036 return llvm::StringSwitch
<const char *>(Arch
)
1037 .Case("armv6k", "armv6")
1038 .Case("armv6m", "armv6m")
1039 .Case("armv5tej", "armv5")
1040 .Case("xscale", "xscale")
1041 .Case("armv4t", "armv4t")
1042 .Case("armv7", "armv7")
1043 .Cases("armv7a", "armv7-a", "armv7")
1044 .Cases("armv7r", "armv7-r", "armv7")
1045 .Cases("armv7em", "armv7e-m", "armv7em")
1046 .Cases("armv7k", "armv7-k", "armv7k")
1047 .Cases("armv7m", "armv7-m", "armv7m")
1048 .Cases("armv7s", "armv7-s", "armv7s")
1052 static const char *ArmMachOArchNameCPU(StringRef CPU
) {
1053 llvm::ARM::ArchKind ArchKind
= llvm::ARM::parseCPUArch(CPU
);
1054 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
1056 StringRef Arch
= llvm::ARM::getArchName(ArchKind
);
1058 // FIXME: Make sure this MachO triple mangling is really necessary.
1059 // ARMv5* normalises to ARMv5.
1060 if (Arch
.starts_with("armv5"))
1061 Arch
= Arch
.substr(0, 5);
1062 // ARMv6*, except ARMv6M, normalises to ARMv6.
1063 else if (Arch
.starts_with("armv6") && !Arch
.ends_with("6m"))
1064 Arch
= Arch
.substr(0, 5);
1065 // ARMv7A normalises to ARMv7.
1066 else if (Arch
.ends_with("v7a"))
1067 Arch
= Arch
.substr(0, 5);
1071 StringRef
MachO::getMachOArchName(const ArgList
&Args
) const {
1072 switch (getTriple().getArch()) {
1074 return getDefaultUniversalArchName();
1076 case llvm::Triple::aarch64_32
:
1079 case llvm::Triple::aarch64
: {
1080 if (getTriple().isArm64e())
1085 case llvm::Triple::thumb
:
1086 case llvm::Triple::arm
:
1087 if (const Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_march_EQ
))
1088 if (const char *Arch
= ArmMachOArchName(A
->getValue()))
1091 if (const Arg
*A
= Args
.getLastArg(options::OPT_mcpu_EQ
))
1092 if (const char *Arch
= ArmMachOArchNameCPU(A
->getValue()))
1099 VersionTuple
MachO::getLinkerVersion(const llvm::opt::ArgList
&Args
) const {
1100 if (LinkerVersion
) {
1102 VersionTuple NewLinkerVersion
;
1103 if (Arg
*A
= Args
.getLastArg(options::OPT_mlinker_version_EQ
))
1104 (void)NewLinkerVersion
.tryParse(A
->getValue());
1105 assert(NewLinkerVersion
== LinkerVersion
);
1107 return *LinkerVersion
;
1110 VersionTuple NewLinkerVersion
;
1111 if (Arg
*A
= Args
.getLastArg(options::OPT_mlinker_version_EQ
))
1112 if (NewLinkerVersion
.tryParse(A
->getValue()))
1113 getDriver().Diag(diag::err_drv_invalid_version_number
)
1114 << A
->getAsString(Args
);
1116 LinkerVersion
= NewLinkerVersion
;
1117 return *LinkerVersion
;
1120 Darwin::~Darwin() {}
1124 std::string
Darwin::ComputeEffectiveClangTriple(const ArgList
&Args
,
1125 types::ID InputType
) const {
1126 llvm::Triple
Triple(ComputeLLVMTriple(Args
, InputType
));
1128 // If the target isn't initialized (e.g., an unknown Darwin platform, return
1129 // the default triple).
1130 if (!isTargetInitialized())
1131 return Triple
.getTriple();
1133 SmallString
<16> Str
;
1134 if (isTargetWatchOSBased())
1136 else if (isTargetTvOSBased())
1138 else if (isTargetDriverKit())
1140 else if (isTargetIOSBased() || isTargetMacCatalyst())
1142 else if (isTargetXROS())
1143 Str
+= llvm::Triple::getOSTypeName(llvm::Triple::XROS
);
1146 Str
+= getTripleTargetVersion().getAsString();
1147 Triple
.setOSName(Str
);
1149 return Triple
.getTriple();
1152 Tool
*MachO::getTool(Action::ActionClass AC
) const {
1154 case Action::LipoJobClass
:
1156 Lipo
.reset(new tools::darwin::Lipo(*this));
1158 case Action::DsymutilJobClass
:
1160 Dsymutil
.reset(new tools::darwin::Dsymutil(*this));
1161 return Dsymutil
.get();
1162 case Action::VerifyDebugInfoJobClass
:
1164 VerifyDebug
.reset(new tools::darwin::VerifyDebug(*this));
1165 return VerifyDebug
.get();
1167 return ToolChain::getTool(AC
);
1171 Tool
*MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
1173 Tool
*MachO::buildStaticLibTool() const {
1174 return new tools::darwin::StaticLibTool(*this);
1177 Tool
*MachO::buildAssembler() const {
1178 return new tools::darwin::Assembler(*this);
1181 DarwinClang::DarwinClang(const Driver
&D
, const llvm::Triple
&Triple
,
1182 const ArgList
&Args
)
1183 : Darwin(D
, Triple
, Args
) {}
1185 void DarwinClang::addClangWarningOptions(ArgStringList
&CC1Args
) const {
1186 // Always error about undefined 'TARGET_OS_*' macros.
1187 CC1Args
.push_back("-Wundef-prefix=TARGET_OS_");
1188 CC1Args
.push_back("-Werror=undef-prefix");
1190 // For modern targets, promote certain warnings to errors.
1191 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
1192 // Always enable -Wdeprecated-objc-isa-usage and promote it
1194 CC1Args
.push_back("-Wdeprecated-objc-isa-usage");
1195 CC1Args
.push_back("-Werror=deprecated-objc-isa-usage");
1197 // For iOS and watchOS, also error about implicit function declarations,
1198 // as that can impact calling conventions.
1199 if (!isTargetMacOS())
1200 CC1Args
.push_back("-Werror=implicit-function-declaration");
1204 /// Take a path that speculatively points into Xcode and return the
1205 /// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path
1207 static StringRef
getXcodeDeveloperPath(StringRef PathIntoXcode
) {
1208 static constexpr llvm::StringLiteral
XcodeAppSuffix(
1209 ".app/Contents/Developer");
1210 size_t Index
= PathIntoXcode
.find(XcodeAppSuffix
);
1211 if (Index
== StringRef::npos
)
1213 return PathIntoXcode
.take_front(Index
+ XcodeAppSuffix
.size());
1216 void DarwinClang::AddLinkARCArgs(const ArgList
&Args
,
1217 ArgStringList
&CmdArgs
) const {
1218 // Avoid linking compatibility stubs on i386 mac.
1219 if (isTargetMacOSBased() && getArch() == llvm::Triple::x86
)
1221 if (isTargetAppleSiliconMac())
1223 // ARC runtime is supported everywhere on arm64e.
1224 if (getTriple().isArm64e())
1229 ObjCRuntime runtime
= getDefaultObjCRuntime(/*nonfragile*/ true);
1231 if ((runtime
.hasNativeARC() || !isObjCAutoRefCount(Args
)) &&
1232 runtime
.hasSubscripting())
1235 SmallString
<128> P(getDriver().ClangExecutable
);
1236 llvm::sys::path::remove_filename(P
); // 'clang'
1237 llvm::sys::path::remove_filename(P
); // 'bin'
1238 llvm::sys::path::append(P
, "lib", "arc");
1240 // 'libarclite' usually lives in the same toolchain as 'clang'. However, the
1241 // Swift open source toolchains for macOS distribute Clang without libarclite.
1242 // In that case, to allow the linker to find 'libarclite', we point to the
1243 // 'libarclite' in the XcodeDefault toolchain instead.
1244 if (!getVFS().exists(P
)) {
1245 auto updatePath
= [&](const Arg
*A
) {
1246 // Try to infer the path to 'libarclite' in the toolchain from the
1247 // specified SDK path.
1248 StringRef XcodePathForSDK
= getXcodeDeveloperPath(A
->getValue());
1249 if (XcodePathForSDK
.empty())
1252 P
= XcodePathForSDK
;
1253 llvm::sys::path::append(P
, "Toolchains/XcodeDefault.xctoolchain/usr",
1255 return getVFS().exists(P
);
1258 bool updated
= false;
1259 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
))
1260 updated
= updatePath(A
);
1263 if (const Arg
*A
= Args
.getLastArg(options::OPT__sysroot_EQ
))
1268 CmdArgs
.push_back("-force_load");
1269 llvm::sys::path::append(P
, "libarclite_");
1270 // Mash in the platform.
1271 if (isTargetWatchOSSimulator())
1272 P
+= "watchsimulator";
1273 else if (isTargetWatchOS())
1275 else if (isTargetTvOSSimulator())
1276 P
+= "appletvsimulator";
1277 else if (isTargetTvOS())
1279 else if (isTargetIOSSimulator())
1280 P
+= "iphonesimulator";
1281 else if (isTargetIPhoneOS())
1287 if (!getVFS().exists(P
))
1288 getDriver().Diag(clang::diag::err_drv_darwin_sdk_missing_arclite
) << P
;
1290 CmdArgs
.push_back(Args
.MakeArgString(P
));
1293 unsigned DarwinClang::GetDefaultDwarfVersion() const {
1294 // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
1295 if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) ||
1296 (isTargetIOSBased() && isIPhoneOSVersionLT(9)))
1298 // Default to use DWARF 4 on OS X 10.11 - macOS 14 / iOS 9 - iOS 17.
1299 if ((isTargetMacOSBased() && isMacosxVersionLT(15)) ||
1300 (isTargetIOSBased() && isIPhoneOSVersionLT(18)) ||
1301 (isTargetWatchOSBased() && TargetVersion
< llvm::VersionTuple(11)) ||
1302 (isTargetXROS() && TargetVersion
< llvm::VersionTuple(2)) ||
1303 (isTargetDriverKit() && TargetVersion
< llvm::VersionTuple(24)) ||
1304 (isTargetMacOSBased() &&
1305 TargetVersion
.empty())) // apple-darwin, no version.
1310 void MachO::AddLinkRuntimeLib(const ArgList
&Args
, ArgStringList
&CmdArgs
,
1311 StringRef Component
, RuntimeLinkOptions Opts
,
1312 bool IsShared
) const {
1313 std::string P
= getCompilerRT(
1314 Args
, Component
, IsShared
? ToolChain::FT_Shared
: ToolChain::FT_Static
);
1316 // For now, allow missing resource libraries to support developers who may
1317 // not have compiler-rt checked out or integrated into their build (unless
1318 // we explicitly force linking with this library).
1319 if ((Opts
& RLO_AlwaysLink
) || getVFS().exists(P
)) {
1320 const char *LibArg
= Args
.MakeArgString(P
);
1321 CmdArgs
.push_back(LibArg
);
1324 // Adding the rpaths might negatively interact when other rpaths are involved,
1325 // so we should make sure we add the rpaths last, after all user-specified
1326 // rpaths. This is currently true from this place, but we need to be
1327 // careful if this function is ever called before user's rpaths are emitted.
1328 if (Opts
& RLO_AddRPath
) {
1329 assert(StringRef(P
).ends_with(".dylib") && "must be a dynamic library");
1331 // Add @executable_path to rpath to support having the dylib copied with
1333 CmdArgs
.push_back("-rpath");
1334 CmdArgs
.push_back("@executable_path");
1336 // Add the compiler-rt library's directory to rpath to support using the
1337 // dylib from the default location without copying.
1338 CmdArgs
.push_back("-rpath");
1339 CmdArgs
.push_back(Args
.MakeArgString(llvm::sys::path::parent_path(P
)));
1343 std::string
MachO::getCompilerRT(const ArgList
&, StringRef Component
,
1344 FileType Type
) const {
1345 assert(Type
!= ToolChain::FT_Object
&&
1346 "it doesn't make sense to ask for the compiler-rt library name as an "
1348 SmallString
<64> MachOLibName
= StringRef("libclang_rt");
1349 // On MachO, the builtins component is not in the library name
1350 if (Component
!= "builtins") {
1351 MachOLibName
+= '.';
1352 MachOLibName
+= Component
;
1354 MachOLibName
+= Type
== ToolChain::FT_Shared
? "_dynamic.dylib" : ".a";
1356 SmallString
<128> FullPath(getDriver().ResourceDir
);
1357 llvm::sys::path::append(FullPath
, "lib", "darwin", "macho_embedded",
1359 return std::string(FullPath
);
1362 std::string
Darwin::getCompilerRT(const ArgList
&, StringRef Component
,
1363 FileType Type
) const {
1364 assert(Type
!= ToolChain::FT_Object
&&
1365 "it doesn't make sense to ask for the compiler-rt library name as an "
1367 SmallString
<64> DarwinLibName
= StringRef("libclang_rt.");
1368 // On Darwin, the builtins component is not in the library name
1369 if (Component
!= "builtins") {
1370 DarwinLibName
+= Component
;
1371 DarwinLibName
+= '_';
1373 DarwinLibName
+= getOSLibraryNameSuffix();
1374 DarwinLibName
+= Type
== ToolChain::FT_Shared
? "_dynamic.dylib" : ".a";
1376 SmallString
<128> FullPath(getDriver().ResourceDir
);
1377 llvm::sys::path::append(FullPath
, "lib", "darwin", DarwinLibName
);
1378 return std::string(FullPath
);
1381 StringRef
Darwin::getPlatformFamily() const {
1382 switch (TargetPlatform
) {
1383 case DarwinPlatformKind::MacOS
:
1385 case DarwinPlatformKind::IPhoneOS
:
1386 if (TargetEnvironment
== MacCatalyst
)
1389 case DarwinPlatformKind::TvOS
:
1391 case DarwinPlatformKind::WatchOS
:
1393 case DarwinPlatformKind::DriverKit
:
1395 case DarwinPlatformKind::XROS
:
1398 llvm_unreachable("Unsupported platform");
1401 StringRef
Darwin::getSDKName(StringRef isysroot
) {
1402 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
1403 auto BeginSDK
= llvm::sys::path::rbegin(isysroot
);
1404 auto EndSDK
= llvm::sys::path::rend(isysroot
);
1405 for (auto IT
= BeginSDK
; IT
!= EndSDK
; ++IT
) {
1406 StringRef SDK
= *IT
;
1407 if (SDK
.ends_with(".sdk"))
1408 return SDK
.slice(0, SDK
.size() - 4);
1413 StringRef
Darwin::getOSLibraryNameSuffix(bool IgnoreSim
) const {
1414 switch (TargetPlatform
) {
1415 case DarwinPlatformKind::MacOS
:
1417 case DarwinPlatformKind::IPhoneOS
:
1418 if (TargetEnvironment
== MacCatalyst
)
1420 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "ios"
1422 case DarwinPlatformKind::TvOS
:
1423 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "tvos"
1425 case DarwinPlatformKind::WatchOS
:
1426 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "watchos"
1428 case DarwinPlatformKind::XROS
:
1429 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "xros"
1431 case DarwinPlatformKind::DriverKit
:
1434 llvm_unreachable("Unsupported platform");
1437 /// Check if the link command contains a symbol export directive.
1438 static bool hasExportSymbolDirective(const ArgList
&Args
) {
1439 for (Arg
*A
: Args
) {
1440 if (A
->getOption().matches(options::OPT_exported__symbols__list
))
1442 if (!A
->getOption().matches(options::OPT_Wl_COMMA
) &&
1443 !A
->getOption().matches(options::OPT_Xlinker
))
1445 if (A
->containsValue("-exported_symbols_list") ||
1446 A
->containsValue("-exported_symbol"))
1452 /// Add an export directive for \p Symbol to the link command.
1453 static void addExportedSymbol(ArgStringList
&CmdArgs
, const char *Symbol
) {
1454 CmdArgs
.push_back("-exported_symbol");
1455 CmdArgs
.push_back(Symbol
);
1458 /// Add a sectalign directive for \p Segment and \p Section to the maximum
1459 /// expected page size for Darwin.
1461 /// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K.
1462 /// Use a common alignment constant (16K) for now, and reduce the alignment on
1463 /// macOS if it proves important.
1464 static void addSectalignToPage(const ArgList
&Args
, ArgStringList
&CmdArgs
,
1465 StringRef Segment
, StringRef Section
) {
1466 for (const char *A
: {"-sectalign", Args
.MakeArgString(Segment
),
1467 Args
.MakeArgString(Section
), "0x4000"})
1468 CmdArgs
.push_back(A
);
1471 void Darwin::addProfileRTLibs(const ArgList
&Args
,
1472 ArgStringList
&CmdArgs
) const {
1473 if (!needsProfileRT(Args
) && !needsGCovInstrumentation(Args
))
1476 AddLinkRuntimeLib(Args
, CmdArgs
, "profile",
1477 RuntimeLinkOptions(RLO_AlwaysLink
));
1479 bool ForGCOV
= needsGCovInstrumentation(Args
);
1481 // If we have a symbol export directive and we're linking in the profile
1482 // runtime, automatically export symbols necessary to implement some of the
1483 // runtime's functionality.
1484 if (hasExportSymbolDirective(Args
) && ForGCOV
) {
1485 addExportedSymbol(CmdArgs
, "___gcov_dump");
1486 addExportedSymbol(CmdArgs
, "___gcov_reset");
1487 addExportedSymbol(CmdArgs
, "_writeout_fn_list");
1488 addExportedSymbol(CmdArgs
, "_reset_fn_list");
1491 // Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page
1492 // alignment. This allows profile counters to be mmap()'d to disk. Note that
1493 // it's not enough to just page-align __llvm_prf_cnts: the following section
1494 // must also be page-aligned so that its data is not clobbered by mmap().
1496 // The section alignment is only needed when continuous profile sync is
1497 // enabled, but this is expected to be the default in Xcode. Specifying the
1498 // extra alignment also allows the same binary to be used with/without sync
1501 for (auto IPSK
: {llvm::IPSK_cnts
, llvm::IPSK_bitmap
, llvm::IPSK_data
}) {
1503 Args
, CmdArgs
, "__DATA",
1504 llvm::getInstrProfSectionName(IPSK
, llvm::Triple::MachO
,
1505 /*AddSegmentInfo=*/false));
1510 void DarwinClang::AddLinkSanitizerLibArgs(const ArgList
&Args
,
1511 ArgStringList
&CmdArgs
,
1512 StringRef Sanitizer
,
1513 bool Shared
) const {
1514 auto RLO
= RuntimeLinkOptions(RLO_AlwaysLink
| (Shared
? RLO_AddRPath
: 0U));
1515 AddLinkRuntimeLib(Args
, CmdArgs
, Sanitizer
, RLO
, Shared
);
1518 ToolChain::RuntimeLibType
DarwinClang::GetRuntimeLibType(
1519 const ArgList
&Args
) const {
1520 if (Arg
* A
= Args
.getLastArg(options::OPT_rtlib_EQ
)) {
1521 StringRef Value
= A
->getValue();
1522 if (Value
!= "compiler-rt" && Value
!= "platform")
1523 getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform
)
1524 << Value
<< "darwin";
1527 return ToolChain::RLT_CompilerRT
;
1530 void DarwinClang::AddLinkRuntimeLibArgs(const ArgList
&Args
,
1531 ArgStringList
&CmdArgs
,
1532 bool ForceLinkBuiltinRT
) const {
1533 // Call once to ensure diagnostic is printed if wrong value was specified
1534 GetRuntimeLibType(Args
);
1536 // Darwin doesn't support real static executables, don't link any runtime
1537 // libraries with -static.
1538 if (Args
.hasArg(options::OPT_static
) ||
1539 Args
.hasArg(options::OPT_fapple_kext
) ||
1540 Args
.hasArg(options::OPT_mkernel
)) {
1541 if (ForceLinkBuiltinRT
)
1542 AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
1546 // Reject -static-libgcc for now, we can deal with this when and if someone
1547 // cares. This is useful in situations where someone wants to statically link
1548 // something like libstdc++, and needs its runtime support routines.
1549 if (const Arg
*A
= Args
.getLastArg(options::OPT_static_libgcc
)) {
1550 getDriver().Diag(diag::err_drv_unsupported_opt
) << A
->getAsString(Args
);
1554 const SanitizerArgs
&Sanitize
= getSanitizerArgs(Args
);
1556 if (!Sanitize
.needsSharedRt()) {
1557 const char *sanitizer
= nullptr;
1558 if (Sanitize
.needsUbsanRt()) {
1559 sanitizer
= "UndefinedBehaviorSanitizer";
1560 } else if (Sanitize
.needsRtsanRt()) {
1561 sanitizer
= "RealtimeSanitizer";
1562 } else if (Sanitize
.needsAsanRt()) {
1563 sanitizer
= "AddressSanitizer";
1564 } else if (Sanitize
.needsTsanRt()) {
1565 sanitizer
= "ThreadSanitizer";
1568 getDriver().Diag(diag::err_drv_unsupported_static_sanitizer_darwin
)
1574 if (Sanitize
.linkRuntimes()) {
1575 if (Sanitize
.needsAsanRt()) {
1576 if (Sanitize
.needsStableAbi()) {
1577 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "asan_abi", /*shared=*/false);
1579 assert(Sanitize
.needsSharedRt() &&
1580 "Static sanitizer runtimes not supported");
1581 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "asan");
1584 if (Sanitize
.needsRtsanRt()) {
1585 assert(Sanitize
.needsSharedRt() &&
1586 "Static sanitizer runtimes not supported");
1587 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "rtsan");
1589 if (Sanitize
.needsLsanRt())
1590 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "lsan");
1591 if (Sanitize
.needsUbsanRt()) {
1592 assert(Sanitize
.needsSharedRt() &&
1593 "Static sanitizer runtimes not supported");
1594 AddLinkSanitizerLibArgs(
1596 Sanitize
.requiresMinimalRuntime() ? "ubsan_minimal" : "ubsan");
1598 if (Sanitize
.needsTsanRt()) {
1599 assert(Sanitize
.needsSharedRt() &&
1600 "Static sanitizer runtimes not supported");
1601 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "tsan");
1603 if (Sanitize
.needsFuzzer() && !Args
.hasArg(options::OPT_dynamiclib
)) {
1604 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "fuzzer", /*shared=*/false);
1606 // Libfuzzer is written in C++ and requires libcxx.
1607 AddCXXStdlibLibArgs(Args
, CmdArgs
);
1609 if (Sanitize
.needsStatsRt()) {
1610 AddLinkRuntimeLib(Args
, CmdArgs
, "stats_client", RLO_AlwaysLink
);
1611 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "stats");
1615 const XRayArgs
&XRay
= getXRayArgs();
1616 if (XRay
.needsXRayRt()) {
1617 AddLinkRuntimeLib(Args
, CmdArgs
, "xray");
1618 AddLinkRuntimeLib(Args
, CmdArgs
, "xray-basic");
1619 AddLinkRuntimeLib(Args
, CmdArgs
, "xray-fdr");
1622 if (isTargetDriverKit() && !Args
.hasArg(options::OPT_nodriverkitlib
)) {
1623 CmdArgs
.push_back("-framework");
1624 CmdArgs
.push_back("DriverKit");
1627 // Otherwise link libSystem, then the dynamic runtime library, and finally any
1628 // target specific static runtime library.
1629 if (!isTargetDriverKit())
1630 CmdArgs
.push_back("-lSystem");
1632 // Select the dynamic runtime library and the target specific static library.
1633 if (isTargetIOSBased()) {
1634 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
1635 // it never went into the SDK.
1636 // Linking against libgcc_s.1 isn't needed for iOS 5.0+
1637 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
1638 getTriple().getArch() != llvm::Triple::aarch64
)
1639 CmdArgs
.push_back("-lgcc_s.1");
1641 AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
1644 /// Returns the most appropriate macOS target version for the current process.
1646 /// If the macOS SDK version is the same or earlier than the system version,
1647 /// then the SDK version is returned. Otherwise the system version is returned.
1648 static std::string
getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion
) {
1649 llvm::Triple
SystemTriple(llvm::sys::getProcessTriple());
1650 if (!SystemTriple
.isMacOSX())
1651 return std::string(MacOSSDKVersion
);
1652 VersionTuple SystemVersion
;
1653 SystemTriple
.getMacOSXVersion(SystemVersion
);
1655 unsigned Major
, Minor
, Micro
;
1657 if (!Driver::GetReleaseVersion(MacOSSDKVersion
, Major
, Minor
, Micro
,
1659 return std::string(MacOSSDKVersion
);
1660 VersionTuple
SDKVersion(Major
, Minor
, Micro
);
1662 if (SDKVersion
> SystemVersion
)
1663 return SystemVersion
.getAsString();
1664 return std::string(MacOSSDKVersion
);
1669 /// The Darwin OS that was selected or inferred from arguments / environment.
1670 struct DarwinPlatform
{
1672 /// The OS was specified using the -target argument.
1674 /// The OS was specified using the -mtargetos= argument.
1676 /// The OS was specified using the -m<os>-version-min argument.
1678 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
1679 DeploymentTargetEnv
,
1680 /// The OS was inferred from the SDK.
1682 /// The OS was inferred from the -arch.
1686 using DarwinPlatformKind
= Darwin::DarwinPlatformKind
;
1687 using DarwinEnvironmentKind
= Darwin::DarwinEnvironmentKind
;
1689 DarwinPlatformKind
getPlatform() const { return Platform
; }
1691 DarwinEnvironmentKind
getEnvironment() const { return Environment
; }
1693 void setEnvironment(DarwinEnvironmentKind Kind
) {
1695 InferSimulatorFromArch
= false;
1698 StringRef
getOSVersion() const {
1699 if (Kind
== OSVersionArg
)
1700 return Argument
->getValue();
1704 void setOSVersion(StringRef S
) {
1705 assert(Kind
== TargetArg
&& "Unexpected kind!");
1706 OSVersion
= std::string(S
);
1709 bool hasOSVersion() const { return HasOSVersion
; }
1711 VersionTuple
getNativeTargetVersion() const {
1712 assert(Environment
== DarwinEnvironmentKind::MacCatalyst
&&
1713 "native target version is specified only for Mac Catalyst");
1714 return NativeTargetVersion
;
1717 /// Returns true if the target OS was explicitly specified.
1718 bool isExplicitlySpecified() const { return Kind
<= DeploymentTargetEnv
; }
1720 /// Returns true if the simulator environment can be inferred from the arch.
1721 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch
; }
1723 const std::optional
<llvm::Triple
> &getTargetVariantTriple() const {
1724 return TargetVariantTriple
;
1727 /// Adds the -m<os>-version-min argument to the compiler invocation.
1728 void addOSVersionMinArgument(DerivedArgList
&Args
, const OptTable
&Opts
) {
1731 assert(Kind
!= TargetArg
&& Kind
!= MTargetOSArg
&& Kind
!= OSVersionArg
&&
1735 case DarwinPlatformKind::MacOS
:
1736 Opt
= options::OPT_mmacos_version_min_EQ
;
1738 case DarwinPlatformKind::IPhoneOS
:
1739 Opt
= options::OPT_mios_version_min_EQ
;
1741 case DarwinPlatformKind::TvOS
:
1742 Opt
= options::OPT_mtvos_version_min_EQ
;
1744 case DarwinPlatformKind::WatchOS
:
1745 Opt
= options::OPT_mwatchos_version_min_EQ
;
1747 case DarwinPlatformKind::XROS
:
1748 // xrOS always explicitly provides a version in the triple.
1750 case DarwinPlatformKind::DriverKit
:
1751 // DriverKit always explicitly provides a version in the triple.
1754 Argument
= Args
.MakeJoinedArg(nullptr, Opts
.getOption(Opt
), OSVersion
);
1755 Args
.append(Argument
);
1758 /// Returns the OS version with the argument / environment variable that
1760 std::string
getAsString(DerivedArgList
&Args
, const OptTable
&Opts
) {
1765 case InferredFromSDK
:
1766 case InferredFromArch
:
1767 assert(Argument
&& "OS version argument not yet inferred");
1768 return Argument
->getAsString(Args
);
1769 case DeploymentTargetEnv
:
1770 return (llvm::Twine(EnvVarName
) + "=" + OSVersion
).str();
1772 llvm_unreachable("Unsupported Darwin Source Kind");
1775 void setEnvironment(llvm::Triple::EnvironmentType EnvType
,
1776 const VersionTuple
&OSVersion
,
1777 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
1779 case llvm::Triple::Simulator
:
1780 Environment
= DarwinEnvironmentKind::Simulator
;
1782 case llvm::Triple::MacABI
: {
1783 Environment
= DarwinEnvironmentKind::MacCatalyst
;
1784 // The minimum native macOS target for MacCatalyst is macOS 10.15.
1785 NativeTargetVersion
= VersionTuple(10, 15);
1786 if (HasOSVersion
&& SDKInfo
) {
1787 if (const auto *MacCatalystToMacOSMapping
= SDKInfo
->getVersionMapping(
1788 DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
1789 if (auto MacOSVersion
= MacCatalystToMacOSMapping
->map(
1790 OSVersion
, NativeTargetVersion
, std::nullopt
)) {
1791 NativeTargetVersion
= *MacOSVersion
;
1795 // In a zippered build, we could be building for a macOS target that's
1796 // lower than the version that's implied by the OS version. In that case
1797 // we need to use the minimum version as the native target version.
1798 if (TargetVariantTriple
) {
1799 auto TargetVariantVersion
= TargetVariantTriple
->getOSVersion();
1800 if (TargetVariantVersion
.getMajor()) {
1801 if (TargetVariantVersion
< NativeTargetVersion
)
1802 NativeTargetVersion
= TargetVariantVersion
;
1812 static DarwinPlatform
1813 createFromTarget(const llvm::Triple
&TT
, StringRef OSVersion
, Arg
*A
,
1814 std::optional
<llvm::Triple
> TargetVariantTriple
,
1815 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
1816 DarwinPlatform
Result(TargetArg
, getPlatformFromOS(TT
.getOS()), OSVersion
,
1818 VersionTuple OsVersion
= TT
.getOSVersion();
1819 if (OsVersion
.getMajor() == 0)
1820 Result
.HasOSVersion
= false;
1821 Result
.TargetVariantTriple
= TargetVariantTriple
;
1822 Result
.setEnvironment(TT
.getEnvironment(), OsVersion
, SDKInfo
);
1825 static DarwinPlatform
1826 createFromMTargetOS(llvm::Triple::OSType OS
, VersionTuple OSVersion
,
1827 llvm::Triple::EnvironmentType Environment
, Arg
*A
,
1828 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
1829 DarwinPlatform
Result(MTargetOSArg
, getPlatformFromOS(OS
),
1830 OSVersion
.getAsString(), A
);
1831 Result
.InferSimulatorFromArch
= false;
1832 Result
.setEnvironment(Environment
, OSVersion
, SDKInfo
);
1835 static DarwinPlatform
createOSVersionArg(DarwinPlatformKind Platform
, Arg
*A
,
1837 DarwinPlatform Result
{OSVersionArg
, Platform
, A
};
1839 Result
.Environment
= DarwinEnvironmentKind::Simulator
;
1842 static DarwinPlatform
createDeploymentTargetEnv(DarwinPlatformKind Platform
,
1843 StringRef EnvVarName
,
1845 DarwinPlatform
Result(DeploymentTargetEnv
, Platform
, Value
);
1846 Result
.EnvVarName
= EnvVarName
;
1849 static DarwinPlatform
createFromSDK(DarwinPlatformKind Platform
,
1851 bool IsSimulator
= false) {
1852 DarwinPlatform
Result(InferredFromSDK
, Platform
, Value
);
1854 Result
.Environment
= DarwinEnvironmentKind::Simulator
;
1855 Result
.InferSimulatorFromArch
= false;
1858 static DarwinPlatform
createFromArch(llvm::Triple::OSType OS
,
1860 return DarwinPlatform(InferredFromArch
, getPlatformFromOS(OS
), Value
);
1863 /// Constructs an inferred SDKInfo value based on the version inferred from
1864 /// the SDK path itself. Only works for values that were created by inferring
1865 /// the platform from the SDKPath.
1866 DarwinSDKInfo
inferSDKInfo() {
1867 assert(Kind
== InferredFromSDK
&& "can infer SDK info only");
1868 llvm::VersionTuple Version
;
1869 bool IsValid
= !Version
.tryParse(OSVersion
);
1871 assert(IsValid
&& "invalid SDK version");
1872 return DarwinSDKInfo(
1874 /*MaximumDeploymentTarget=*/VersionTuple(Version
.getMajor(), 0, 99));
1878 DarwinPlatform(SourceKind Kind
, DarwinPlatformKind Platform
, Arg
*Argument
)
1879 : Kind(Kind
), Platform(Platform
), Argument(Argument
) {}
1880 DarwinPlatform(SourceKind Kind
, DarwinPlatformKind Platform
, StringRef Value
,
1881 Arg
*Argument
= nullptr)
1882 : Kind(Kind
), Platform(Platform
), OSVersion(Value
), Argument(Argument
) {}
1884 static DarwinPlatformKind
getPlatformFromOS(llvm::Triple::OSType OS
) {
1886 case llvm::Triple::Darwin
:
1887 case llvm::Triple::MacOSX
:
1888 return DarwinPlatformKind::MacOS
;
1889 case llvm::Triple::IOS
:
1890 return DarwinPlatformKind::IPhoneOS
;
1891 case llvm::Triple::TvOS
:
1892 return DarwinPlatformKind::TvOS
;
1893 case llvm::Triple::WatchOS
:
1894 return DarwinPlatformKind::WatchOS
;
1895 case llvm::Triple::XROS
:
1896 return DarwinPlatformKind::XROS
;
1897 case llvm::Triple::DriverKit
:
1898 return DarwinPlatformKind::DriverKit
;
1900 llvm_unreachable("Unable to infer Darwin variant");
1905 DarwinPlatformKind Platform
;
1906 DarwinEnvironmentKind Environment
= DarwinEnvironmentKind::NativeEnvironment
;
1907 VersionTuple NativeTargetVersion
;
1908 std::string OSVersion
;
1909 bool HasOSVersion
= true, InferSimulatorFromArch
= true;
1911 StringRef EnvVarName
;
1912 std::optional
<llvm::Triple
> TargetVariantTriple
;
1915 /// Returns the deployment target that's specified using the -m<os>-version-min
1917 std::optional
<DarwinPlatform
>
1918 getDeploymentTargetFromOSVersionArg(DerivedArgList
&Args
,
1919 const Driver
&TheDriver
) {
1920 Arg
*macOSVersion
= Args
.getLastArg(options::OPT_mmacos_version_min_EQ
);
1921 Arg
*iOSVersion
= Args
.getLastArg(options::OPT_mios_version_min_EQ
,
1922 options::OPT_mios_simulator_version_min_EQ
);
1924 Args
.getLastArg(options::OPT_mtvos_version_min_EQ
,
1925 options::OPT_mtvos_simulator_version_min_EQ
);
1926 Arg
*WatchOSVersion
=
1927 Args
.getLastArg(options::OPT_mwatchos_version_min_EQ
,
1928 options::OPT_mwatchos_simulator_version_min_EQ
);
1930 if (iOSVersion
|| TvOSVersion
|| WatchOSVersion
) {
1931 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1932 << macOSVersion
->getAsString(Args
)
1933 << (iOSVersion
? iOSVersion
1934 : TvOSVersion
? TvOSVersion
: WatchOSVersion
)
1935 ->getAsString(Args
);
1937 return DarwinPlatform::createOSVersionArg(Darwin::MacOS
, macOSVersion
,
1938 /*IsSimulator=*/false);
1939 } else if (iOSVersion
) {
1940 if (TvOSVersion
|| WatchOSVersion
) {
1941 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1942 << iOSVersion
->getAsString(Args
)
1943 << (TvOSVersion
? TvOSVersion
: WatchOSVersion
)->getAsString(Args
);
1945 return DarwinPlatform::createOSVersionArg(
1946 Darwin::IPhoneOS
, iOSVersion
,
1947 iOSVersion
->getOption().getID() ==
1948 options::OPT_mios_simulator_version_min_EQ
);
1949 } else if (TvOSVersion
) {
1950 if (WatchOSVersion
) {
1951 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1952 << TvOSVersion
->getAsString(Args
)
1953 << WatchOSVersion
->getAsString(Args
);
1955 return DarwinPlatform::createOSVersionArg(
1956 Darwin::TvOS
, TvOSVersion
,
1957 TvOSVersion
->getOption().getID() ==
1958 options::OPT_mtvos_simulator_version_min_EQ
);
1959 } else if (WatchOSVersion
)
1960 return DarwinPlatform::createOSVersionArg(
1961 Darwin::WatchOS
, WatchOSVersion
,
1962 WatchOSVersion
->getOption().getID() ==
1963 options::OPT_mwatchos_simulator_version_min_EQ
);
1964 return std::nullopt
;
1967 /// Returns the deployment target that's specified using the
1968 /// OS_DEPLOYMENT_TARGET environment variable.
1969 std::optional
<DarwinPlatform
>
1970 getDeploymentTargetFromEnvironmentVariables(const Driver
&TheDriver
,
1971 const llvm::Triple
&Triple
) {
1972 std::string Targets
[Darwin::LastDarwinPlatform
+ 1];
1973 const char *EnvVars
[] = {
1974 "MACOSX_DEPLOYMENT_TARGET",
1975 "IPHONEOS_DEPLOYMENT_TARGET",
1976 "TVOS_DEPLOYMENT_TARGET",
1977 "WATCHOS_DEPLOYMENT_TARGET",
1978 "DRIVERKIT_DEPLOYMENT_TARGET",
1979 "XROS_DEPLOYMENT_TARGET"
1981 static_assert(std::size(EnvVars
) == Darwin::LastDarwinPlatform
+ 1,
1982 "Missing platform");
1983 for (const auto &I
: llvm::enumerate(llvm::ArrayRef(EnvVars
))) {
1984 if (char *Env
= ::getenv(I
.value()))
1985 Targets
[I
.index()] = Env
;
1988 // Allow conflicts among OSX and iOS for historical reasons, but choose the
1989 // default platform.
1990 if (!Targets
[Darwin::MacOS
].empty() &&
1991 (!Targets
[Darwin::IPhoneOS
].empty() ||
1992 !Targets
[Darwin::WatchOS
].empty() || !Targets
[Darwin::TvOS
].empty() ||
1993 !Targets
[Darwin::XROS
].empty())) {
1994 if (Triple
.getArch() == llvm::Triple::arm
||
1995 Triple
.getArch() == llvm::Triple::aarch64
||
1996 Triple
.getArch() == llvm::Triple::thumb
)
1997 Targets
[Darwin::MacOS
] = "";
1999 Targets
[Darwin::IPhoneOS
] = Targets
[Darwin::WatchOS
] =
2000 Targets
[Darwin::TvOS
] = Targets
[Darwin::XROS
] = "";
2002 // Don't allow conflicts in any other platform.
2003 unsigned FirstTarget
= std::size(Targets
);
2004 for (unsigned I
= 0; I
!= std::size(Targets
); ++I
) {
2005 if (Targets
[I
].empty())
2007 if (FirstTarget
== std::size(Targets
))
2010 TheDriver
.Diag(diag::err_drv_conflicting_deployment_targets
)
2011 << Targets
[FirstTarget
] << Targets
[I
];
2015 for (const auto &Target
: llvm::enumerate(llvm::ArrayRef(Targets
))) {
2016 if (!Target
.value().empty())
2017 return DarwinPlatform::createDeploymentTargetEnv(
2018 (Darwin::DarwinPlatformKind
)Target
.index(), EnvVars
[Target
.index()],
2021 return std::nullopt
;
2024 /// Returns the SDK name without the optional prefix that ends with a '.' or an
2025 /// empty string otherwise.
2026 static StringRef
dropSDKNamePrefix(StringRef SDKName
) {
2027 size_t PrefixPos
= SDKName
.find('.');
2028 if (PrefixPos
== StringRef::npos
)
2030 return SDKName
.substr(PrefixPos
+ 1);
2033 /// Tries to infer the deployment target from the SDK specified by -isysroot
2034 /// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
2036 std::optional
<DarwinPlatform
>
2037 inferDeploymentTargetFromSDK(DerivedArgList
&Args
,
2038 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
2039 const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
);
2041 return std::nullopt
;
2042 StringRef isysroot
= A
->getValue();
2043 StringRef SDK
= Darwin::getSDKName(isysroot
);
2045 return std::nullopt
;
2047 std::string Version
;
2049 // Get the version from the SDKSettings.json if it's available.
2050 Version
= SDKInfo
->getVersion().getAsString();
2052 // Slice the version number out.
2053 // Version number is between the first and the last number.
2054 size_t StartVer
= SDK
.find_first_of("0123456789");
2055 size_t EndVer
= SDK
.find_last_of("0123456789");
2056 if (StartVer
!= StringRef::npos
&& EndVer
> StartVer
)
2057 Version
= std::string(SDK
.slice(StartVer
, EndVer
+ 1));
2059 if (Version
.empty())
2060 return std::nullopt
;
2062 auto CreatePlatformFromSDKName
=
2063 [&](StringRef SDK
) -> std::optional
<DarwinPlatform
> {
2064 if (SDK
.starts_with("iPhoneOS") || SDK
.starts_with("iPhoneSimulator"))
2065 return DarwinPlatform::createFromSDK(
2066 Darwin::IPhoneOS
, Version
,
2067 /*IsSimulator=*/SDK
.starts_with("iPhoneSimulator"));
2068 else if (SDK
.starts_with("MacOSX"))
2069 return DarwinPlatform::createFromSDK(Darwin::MacOS
,
2070 getSystemOrSDKMacOSVersion(Version
));
2071 else if (SDK
.starts_with("WatchOS") || SDK
.starts_with("WatchSimulator"))
2072 return DarwinPlatform::createFromSDK(
2073 Darwin::WatchOS
, Version
,
2074 /*IsSimulator=*/SDK
.starts_with("WatchSimulator"));
2075 else if (SDK
.starts_with("AppleTVOS") ||
2076 SDK
.starts_with("AppleTVSimulator"))
2077 return DarwinPlatform::createFromSDK(
2078 Darwin::TvOS
, Version
,
2079 /*IsSimulator=*/SDK
.starts_with("AppleTVSimulator"));
2080 else if (SDK
.starts_with("XR"))
2081 return DarwinPlatform::createFromSDK(
2082 Darwin::XROS
, Version
,
2083 /*IsSimulator=*/SDK
.contains("Simulator"));
2084 else if (SDK
.starts_with("DriverKit"))
2085 return DarwinPlatform::createFromSDK(Darwin::DriverKit
, Version
);
2086 return std::nullopt
;
2088 if (auto Result
= CreatePlatformFromSDKName(SDK
))
2090 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
2091 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK
));
2094 std::string
getOSVersion(llvm::Triple::OSType OS
, const llvm::Triple
&Triple
,
2095 const Driver
&TheDriver
) {
2096 VersionTuple OsVersion
;
2097 llvm::Triple
SystemTriple(llvm::sys::getProcessTriple());
2099 case llvm::Triple::Darwin
:
2100 case llvm::Triple::MacOSX
:
2101 // If there is no version specified on triple, and both host and target are
2102 // macos, use the host triple to infer OS version.
2103 if (Triple
.isMacOSX() && SystemTriple
.isMacOSX() &&
2104 !Triple
.getOSMajorVersion())
2105 SystemTriple
.getMacOSXVersion(OsVersion
);
2106 else if (!Triple
.getMacOSXVersion(OsVersion
))
2107 TheDriver
.Diag(diag::err_drv_invalid_darwin_version
)
2108 << Triple
.getOSName();
2110 case llvm::Triple::IOS
:
2111 if (Triple
.isMacCatalystEnvironment() && !Triple
.getOSMajorVersion()) {
2112 OsVersion
= VersionTuple(13, 1);
2114 OsVersion
= Triple
.getiOSVersion();
2116 case llvm::Triple::TvOS
:
2117 OsVersion
= Triple
.getOSVersion();
2119 case llvm::Triple::WatchOS
:
2120 OsVersion
= Triple
.getWatchOSVersion();
2122 case llvm::Triple::XROS
:
2123 OsVersion
= Triple
.getOSVersion();
2124 if (!OsVersion
.getMajor())
2125 OsVersion
= OsVersion
.withMajorReplaced(1);
2127 case llvm::Triple::DriverKit
:
2128 OsVersion
= Triple
.getDriverKitVersion();
2131 llvm_unreachable("Unexpected OS type");
2135 std::string OSVersion
;
2136 llvm::raw_string_ostream(OSVersion
)
2137 << OsVersion
.getMajor() << '.' << OsVersion
.getMinor().value_or(0) << '.'
2138 << OsVersion
.getSubminor().value_or(0);
2142 /// Tries to infer the target OS from the -arch.
2143 std::optional
<DarwinPlatform
>
2144 inferDeploymentTargetFromArch(DerivedArgList
&Args
, const Darwin
&Toolchain
,
2145 const llvm::Triple
&Triple
,
2146 const Driver
&TheDriver
) {
2147 llvm::Triple::OSType OSTy
= llvm::Triple::UnknownOS
;
2149 StringRef MachOArchName
= Toolchain
.getMachOArchName(Args
);
2150 if (MachOArchName
== "arm64" || MachOArchName
== "arm64e")
2151 OSTy
= llvm::Triple::MacOSX
;
2152 else if (MachOArchName
== "armv7" || MachOArchName
== "armv7s")
2153 OSTy
= llvm::Triple::IOS
;
2154 else if (MachOArchName
== "armv7k" || MachOArchName
== "arm64_32")
2155 OSTy
= llvm::Triple::WatchOS
;
2156 else if (MachOArchName
!= "armv6m" && MachOArchName
!= "armv7m" &&
2157 MachOArchName
!= "armv7em")
2158 OSTy
= llvm::Triple::MacOSX
;
2159 if (OSTy
== llvm::Triple::UnknownOS
)
2160 return std::nullopt
;
2161 return DarwinPlatform::createFromArch(OSTy
,
2162 getOSVersion(OSTy
, Triple
, TheDriver
));
2165 /// Returns the deployment target that's specified using the -target option.
2166 std::optional
<DarwinPlatform
> getDeploymentTargetFromTargetArg(
2167 DerivedArgList
&Args
, const llvm::Triple
&Triple
, const Driver
&TheDriver
,
2168 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
2169 if (!Args
.hasArg(options::OPT_target
))
2170 return std::nullopt
;
2171 if (Triple
.getOS() == llvm::Triple::Darwin
||
2172 Triple
.getOS() == llvm::Triple::UnknownOS
)
2173 return std::nullopt
;
2174 std::string OSVersion
= getOSVersion(Triple
.getOS(), Triple
, TheDriver
);
2175 std::optional
<llvm::Triple
> TargetVariantTriple
;
2176 for (const Arg
*A
: Args
.filtered(options::OPT_darwin_target_variant
)) {
2177 llvm::Triple
TVT(A
->getValue());
2178 // Find a matching <arch>-<vendor> target variant triple that can be used.
2179 if ((Triple
.getArch() == llvm::Triple::aarch64
||
2180 TVT
.getArchName() == Triple
.getArchName()) &&
2181 TVT
.getArch() == Triple
.getArch() &&
2182 TVT
.getSubArch() == Triple
.getSubArch() &&
2183 TVT
.getVendor() == Triple
.getVendor()) {
2184 if (TargetVariantTriple
)
2187 // Accept a -target-variant triple when compiling code that may run on
2188 // macOS or Mac Catalyst.
2189 if ((Triple
.isMacOSX() && TVT
.getOS() == llvm::Triple::IOS
&&
2190 TVT
.isMacCatalystEnvironment()) ||
2191 (TVT
.isMacOSX() && Triple
.getOS() == llvm::Triple::IOS
&&
2192 Triple
.isMacCatalystEnvironment())) {
2193 TargetVariantTriple
= TVT
;
2196 TheDriver
.Diag(diag::err_drv_target_variant_invalid
)
2197 << A
->getSpelling() << A
->getValue();
2200 return DarwinPlatform::createFromTarget(Triple
, OSVersion
,
2201 Args
.getLastArg(options::OPT_target
),
2202 TargetVariantTriple
, SDKInfo
);
2205 /// Returns the deployment target that's specified using the -mtargetos option.
2206 std::optional
<DarwinPlatform
> getDeploymentTargetFromMTargetOSArg(
2207 DerivedArgList
&Args
, const Driver
&TheDriver
,
2208 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
2209 auto *A
= Args
.getLastArg(options::OPT_mtargetos_EQ
);
2211 return std::nullopt
;
2212 llvm::Triple
TT(llvm::Twine("unknown-apple-") + A
->getValue());
2213 switch (TT
.getOS()) {
2214 case llvm::Triple::MacOSX
:
2215 case llvm::Triple::IOS
:
2216 case llvm::Triple::TvOS
:
2217 case llvm::Triple::WatchOS
:
2218 case llvm::Triple::XROS
:
2221 TheDriver
.Diag(diag::err_drv_invalid_os_in_arg
)
2222 << TT
.getOSName() << A
->getAsString(Args
);
2223 return std::nullopt
;
2226 VersionTuple Version
= TT
.getOSVersion();
2227 if (!Version
.getMajor()) {
2228 TheDriver
.Diag(diag::err_drv_invalid_version_number
)
2229 << A
->getAsString(Args
);
2230 return std::nullopt
;
2232 return DarwinPlatform::createFromMTargetOS(TT
.getOS(), Version
,
2233 TT
.getEnvironment(), A
, SDKInfo
);
2236 std::optional
<DarwinSDKInfo
> parseSDKSettings(llvm::vfs::FileSystem
&VFS
,
2237 const ArgList
&Args
,
2238 const Driver
&TheDriver
) {
2239 const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
);
2241 return std::nullopt
;
2242 StringRef isysroot
= A
->getValue();
2243 auto SDKInfoOrErr
= parseDarwinSDKInfo(VFS
, isysroot
);
2244 if (!SDKInfoOrErr
) {
2245 llvm::consumeError(SDKInfoOrErr
.takeError());
2246 TheDriver
.Diag(diag::warn_drv_darwin_sdk_invalid_settings
);
2247 return std::nullopt
;
2249 return *SDKInfoOrErr
;
2254 void Darwin::AddDeploymentTarget(DerivedArgList
&Args
) const {
2255 const OptTable
&Opts
= getDriver().getOpts();
2257 // Support allowing the SDKROOT environment variable used by xcrun and other
2258 // Xcode tools to define the default sysroot, by making it the default for
2260 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2261 // Warn if the path does not exist.
2262 if (!getVFS().exists(A
->getValue()))
2263 getDriver().Diag(clang::diag::warn_missing_sysroot
) << A
->getValue();
2265 if (char *env
= ::getenv("SDKROOT")) {
2266 // We only use this value as the default if it is an absolute path,
2267 // exists, and it is not the root path.
2268 if (llvm::sys::path::is_absolute(env
) && getVFS().exists(env
) &&
2269 StringRef(env
) != "/") {
2270 Args
.append(Args
.MakeSeparateArg(
2271 nullptr, Opts
.getOption(options::OPT_isysroot
), env
));
2276 // Read the SDKSettings.json file for more information, like the SDK version
2277 // that we can pass down to the compiler.
2278 SDKInfo
= parseSDKSettings(getVFS(), Args
, getDriver());
2280 // The OS and the version can be specified using the -target argument.
2281 std::optional
<DarwinPlatform
> OSTarget
=
2282 getDeploymentTargetFromTargetArg(Args
, getTriple(), getDriver(), SDKInfo
);
2284 // Disallow mixing -target and -mtargetos=.
2285 if (const auto *MTargetOSArg
= Args
.getLastArg(options::OPT_mtargetos_EQ
)) {
2286 std::string TargetArgStr
= OSTarget
->getAsString(Args
, Opts
);
2287 std::string MTargetOSArgStr
= MTargetOSArg
->getAsString(Args
);
2288 getDriver().Diag(diag::err_drv_cannot_mix_options
)
2289 << TargetArgStr
<< MTargetOSArgStr
;
2291 std::optional
<DarwinPlatform
> OSVersionArgTarget
=
2292 getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2293 if (OSVersionArgTarget
) {
2294 unsigned TargetMajor
, TargetMinor
, TargetMicro
;
2296 unsigned ArgMajor
, ArgMinor
, ArgMicro
;
2298 if (OSTarget
->getPlatform() != OSVersionArgTarget
->getPlatform() ||
2299 (Driver::GetReleaseVersion(OSTarget
->getOSVersion(), TargetMajor
,
2300 TargetMinor
, TargetMicro
, TargetExtra
) &&
2301 Driver::GetReleaseVersion(OSVersionArgTarget
->getOSVersion(),
2302 ArgMajor
, ArgMinor
, ArgMicro
, ArgExtra
) &&
2303 (VersionTuple(TargetMajor
, TargetMinor
, TargetMicro
) !=
2304 VersionTuple(ArgMajor
, ArgMinor
, ArgMicro
) ||
2305 TargetExtra
!= ArgExtra
))) {
2306 // Select the OS version from the -m<os>-version-min argument when
2307 // the -target does not include an OS version.
2308 if (OSTarget
->getPlatform() == OSVersionArgTarget
->getPlatform() &&
2309 !OSTarget
->hasOSVersion()) {
2310 OSTarget
->setOSVersion(OSVersionArgTarget
->getOSVersion());
2312 // Warn about -m<os>-version-min that doesn't match the OS version
2313 // that's specified in the target.
2314 std::string OSVersionArg
=
2315 OSVersionArgTarget
->getAsString(Args
, Opts
);
2316 std::string TargetArg
= OSTarget
->getAsString(Args
, Opts
);
2317 getDriver().Diag(clang::diag::warn_drv_overriding_option
)
2318 << OSVersionArg
<< TargetArg
;
2322 } else if ((OSTarget
= getDeploymentTargetFromMTargetOSArg(Args
, getDriver(),
2324 // The OS target can be specified using the -mtargetos= argument.
2325 // Disallow mixing -mtargetos= and -m<os>version-min=.
2326 std::optional
<DarwinPlatform
> OSVersionArgTarget
=
2327 getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2328 if (OSVersionArgTarget
) {
2329 std::string MTargetOSArgStr
= OSTarget
->getAsString(Args
, Opts
);
2330 std::string OSVersionArgStr
= OSVersionArgTarget
->getAsString(Args
, Opts
);
2331 getDriver().Diag(diag::err_drv_cannot_mix_options
)
2332 << MTargetOSArgStr
<< OSVersionArgStr
;
2335 // The OS target can be specified using the -m<os>version-min argument.
2336 OSTarget
= getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2337 // If no deployment target was specified on the command line, check for
2338 // environment defines.
2341 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
2343 // Don't infer simulator from the arch when the SDK is also specified.
2344 std::optional
<DarwinPlatform
> SDKTarget
=
2345 inferDeploymentTargetFromSDK(Args
, SDKInfo
);
2347 OSTarget
->setEnvironment(SDKTarget
->getEnvironment());
2350 // If there is no command-line argument to specify the Target version and
2351 // no environment variable defined, see if we can set the default based
2352 // on -isysroot using SDKSettings.json if it exists.
2354 OSTarget
= inferDeploymentTargetFromSDK(Args
, SDKInfo
);
2355 /// If the target was successfully constructed from the SDK path, try to
2356 /// infer the SDK info if the SDK doesn't have it.
2357 if (OSTarget
&& !SDKInfo
)
2358 SDKInfo
= OSTarget
->inferSDKInfo();
2360 // If no OS targets have been specified, try to guess platform from -target
2361 // or arch name and compute the version from the triple.
2364 inferDeploymentTargetFromArch(Args
, *this, getTriple(), getDriver());
2367 assert(OSTarget
&& "Unable to infer Darwin variant");
2368 OSTarget
->addOSVersionMinArgument(Args
, Opts
);
2369 DarwinPlatformKind Platform
= OSTarget
->getPlatform();
2371 unsigned Major
, Minor
, Micro
;
2373 // The major version should not be over this number.
2374 const unsigned MajorVersionLimit
= 1000;
2375 // Set the tool chain target information.
2376 if (Platform
== MacOS
) {
2377 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2379 HadExtra
|| Major
< 10 || Major
>= MajorVersionLimit
|| Minor
>= 100 ||
2381 getDriver().Diag(diag::err_drv_invalid_version_number
)
2382 << OSTarget
->getAsString(Args
, Opts
);
2383 } else if (Platform
== IPhoneOS
) {
2384 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2386 HadExtra
|| Major
>= MajorVersionLimit
|| Minor
>= 100 || Micro
>= 100)
2387 getDriver().Diag(diag::err_drv_invalid_version_number
)
2388 << OSTarget
->getAsString(Args
, Opts
);
2390 if (OSTarget
->getEnvironment() == MacCatalyst
&&
2391 (Major
< 13 || (Major
== 13 && Minor
< 1))) {
2392 getDriver().Diag(diag::err_drv_invalid_version_number
)
2393 << OSTarget
->getAsString(Args
, Opts
);
2398 // For 32-bit targets, the deployment target for iOS has to be earlier than
2400 if (getTriple().isArch32Bit() && Major
>= 11) {
2401 // If the deployment target is explicitly specified, print a diagnostic.
2402 if (OSTarget
->isExplicitlySpecified()) {
2403 if (OSTarget
->getEnvironment() == MacCatalyst
)
2404 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target
);
2406 getDriver().Diag(diag::warn_invalid_ios_deployment_target
)
2407 << OSTarget
->getAsString(Args
, Opts
);
2408 // Otherwise, set it to 10.99.99.
2415 } else if (Platform
== TvOS
) {
2416 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2418 HadExtra
|| Major
>= MajorVersionLimit
|| Minor
>= 100 || Micro
>= 100)
2419 getDriver().Diag(diag::err_drv_invalid_version_number
)
2420 << OSTarget
->getAsString(Args
, Opts
);
2421 } else if (Platform
== WatchOS
) {
2422 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2424 HadExtra
|| Major
>= MajorVersionLimit
|| Minor
>= 100 || Micro
>= 100)
2425 getDriver().Diag(diag::err_drv_invalid_version_number
)
2426 << OSTarget
->getAsString(Args
, Opts
);
2427 } else if (Platform
== DriverKit
) {
2428 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2430 HadExtra
|| Major
< 19 || Major
>= MajorVersionLimit
|| Minor
>= 100 ||
2432 getDriver().Diag(diag::err_drv_invalid_version_number
)
2433 << OSTarget
->getAsString(Args
, Opts
);
2434 } else if (Platform
== XROS
) {
2435 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2437 HadExtra
|| Major
< 1 || Major
>= MajorVersionLimit
|| Minor
>= 100 ||
2439 getDriver().Diag(diag::err_drv_invalid_version_number
)
2440 << OSTarget
->getAsString(Args
, Opts
);
2442 llvm_unreachable("unknown kind of Darwin platform");
2444 DarwinEnvironmentKind Environment
= OSTarget
->getEnvironment();
2445 // Recognize iOS targets with an x86 architecture as the iOS simulator.
2446 if (Environment
== NativeEnvironment
&& Platform
!= MacOS
&&
2447 Platform
!= DriverKit
&& OSTarget
->canInferSimulatorFromArch() &&
2448 getTriple().isX86())
2449 Environment
= Simulator
;
2451 VersionTuple NativeTargetVersion
;
2452 if (Environment
== MacCatalyst
)
2453 NativeTargetVersion
= OSTarget
->getNativeTargetVersion();
2454 setTarget(Platform
, Environment
, Major
, Minor
, Micro
, NativeTargetVersion
);
2455 TargetVariantTriple
= OSTarget
->getTargetVariantTriple();
2457 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2458 StringRef SDK
= getSDKName(A
->getValue());
2459 if (SDK
.size() > 0) {
2460 size_t StartVer
= SDK
.find_first_of("0123456789");
2461 StringRef SDKName
= SDK
.slice(0, StartVer
);
2462 if (!SDKName
.starts_with(getPlatformFamily()) &&
2463 !dropSDKNamePrefix(SDKName
).starts_with(getPlatformFamily()))
2464 getDriver().Diag(diag::warn_incompatible_sysroot
)
2465 << SDKName
<< getPlatformFamily();
2470 // For certain platforms/environments almost all resources (e.g., headers) are
2471 // located in sub-directories, e.g., for DriverKit they live in
2472 // <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).
2473 static void AppendPlatformPrefix(SmallString
<128> &Path
,
2474 const llvm::Triple
&T
) {
2475 if (T
.isDriverKit()) {
2476 llvm::sys::path::append(Path
, "System", "DriverKit");
2480 // Returns the effective sysroot from either -isysroot or --sysroot, plus the
2481 // platform prefix (if any).
2482 llvm::SmallString
<128>
2483 DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList
&DriverArgs
) const {
2484 llvm::SmallString
<128> Path("/");
2485 if (DriverArgs
.hasArg(options::OPT_isysroot
))
2486 Path
= DriverArgs
.getLastArgValue(options::OPT_isysroot
);
2487 else if (!getDriver().SysRoot
.empty())
2488 Path
= getDriver().SysRoot
;
2490 if (hasEffectiveTriple()) {
2491 AppendPlatformPrefix(Path
, getEffectiveTriple());
2496 void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList
&DriverArgs
,
2497 llvm::opt::ArgStringList
&CC1Args
) const {
2498 const Driver
&D
= getDriver();
2500 llvm::SmallString
<128> Sysroot
= GetEffectiveSysroot(DriverArgs
);
2502 bool NoStdInc
= DriverArgs
.hasArg(options::OPT_nostdinc
);
2503 bool NoStdlibInc
= DriverArgs
.hasArg(options::OPT_nostdlibinc
);
2504 bool NoBuiltinInc
= DriverArgs
.hasFlag(
2505 options::OPT_nobuiltininc
, options::OPT_ibuiltininc
, /*Default=*/false);
2506 bool ForceBuiltinInc
= DriverArgs
.hasFlag(
2507 options::OPT_ibuiltininc
, options::OPT_nobuiltininc
, /*Default=*/false);
2509 // Add <sysroot>/usr/local/include
2510 if (!NoStdInc
&& !NoStdlibInc
) {
2511 SmallString
<128> P(Sysroot
);
2512 llvm::sys::path::append(P
, "usr", "local", "include");
2513 addSystemInclude(DriverArgs
, CC1Args
, P
);
2516 // Add the Clang builtin headers (<resource>/include)
2517 if (!(NoStdInc
&& !ForceBuiltinInc
) && !NoBuiltinInc
) {
2518 SmallString
<128> P(D
.ResourceDir
);
2519 llvm::sys::path::append(P
, "include");
2520 addSystemInclude(DriverArgs
, CC1Args
, P
);
2523 if (NoStdInc
|| NoStdlibInc
)
2526 // Check for configure-time C include directories.
2527 llvm::StringRef
CIncludeDirs(C_INCLUDE_DIRS
);
2528 if (!CIncludeDirs
.empty()) {
2529 llvm::SmallVector
<llvm::StringRef
, 5> dirs
;
2530 CIncludeDirs
.split(dirs
, ":");
2531 for (llvm::StringRef dir
: dirs
) {
2532 llvm::StringRef Prefix
=
2533 llvm::sys::path::is_absolute(dir
) ? "" : llvm::StringRef(Sysroot
);
2534 addExternCSystemInclude(DriverArgs
, CC1Args
, Prefix
+ dir
);
2537 // Otherwise, add <sysroot>/usr/include.
2538 SmallString
<128> P(Sysroot
);
2539 llvm::sys::path::append(P
, "usr", "include");
2540 addExternCSystemInclude(DriverArgs
, CC1Args
, P
.str());
2544 bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList
&DriverArgs
,
2545 llvm::opt::ArgStringList
&CC1Args
,
2546 llvm::SmallString
<128> Base
,
2547 llvm::StringRef Version
,
2548 llvm::StringRef ArchDir
,
2549 llvm::StringRef BitDir
) const {
2550 llvm::sys::path::append(Base
, Version
);
2553 addSystemInclude(DriverArgs
, CC1Args
, Base
);
2555 // Add the multilib dirs
2557 llvm::SmallString
<128> P
= Base
;
2558 if (!ArchDir
.empty())
2559 llvm::sys::path::append(P
, ArchDir
);
2560 if (!BitDir
.empty())
2561 llvm::sys::path::append(P
, BitDir
);
2562 addSystemInclude(DriverArgs
, CC1Args
, P
);
2565 // Add the backward dir
2567 llvm::SmallString
<128> P
= Base
;
2568 llvm::sys::path::append(P
, "backward");
2569 addSystemInclude(DriverArgs
, CC1Args
, P
);
2572 return getVFS().exists(Base
);
2575 void DarwinClang::AddClangCXXStdlibIncludeArgs(
2576 const llvm::opt::ArgList
&DriverArgs
,
2577 llvm::opt::ArgStringList
&CC1Args
) const {
2578 // The implementation from a base class will pass through the -stdlib to
2580 // FIXME: this should not be necessary, remove usages in the frontend
2581 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
2582 // Also check whether this is used for setting library search paths.
2583 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs
, CC1Args
);
2585 if (DriverArgs
.hasArg(options::OPT_nostdinc
, options::OPT_nostdlibinc
,
2586 options::OPT_nostdincxx
))
2589 llvm::SmallString
<128> Sysroot
= GetEffectiveSysroot(DriverArgs
);
2591 switch (GetCXXStdlibType(DriverArgs
)) {
2592 case ToolChain::CST_Libcxx
: {
2593 // On Darwin, libc++ can be installed in one of the following places:
2594 // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
2595 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
2597 // The precedence of paths is as listed above, i.e. we take the first path
2598 // that exists. Note that we never include libc++ twice -- we take the first
2599 // path that exists and don't send the other paths to CC1 (otherwise
2600 // include_next could break).
2603 // Get from '<install>/bin' to '<install>/include/c++/v1'.
2604 // Note that InstallBin can be relative, so we use '..' instead of
2606 llvm::SmallString
<128> InstallBin(getDriver().Dir
); // <install>/bin
2607 llvm::sys::path::append(InstallBin
, "..", "include", "c++", "v1");
2608 if (getVFS().exists(InstallBin
)) {
2609 addSystemInclude(DriverArgs
, CC1Args
, InstallBin
);
2611 } else if (DriverArgs
.hasArg(options::OPT_v
)) {
2612 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
2616 // Otherwise, check for (2)
2617 llvm::SmallString
<128> SysrootUsr
= Sysroot
;
2618 llvm::sys::path::append(SysrootUsr
, "usr", "include", "c++", "v1");
2619 if (getVFS().exists(SysrootUsr
)) {
2620 addSystemInclude(DriverArgs
, CC1Args
, SysrootUsr
);
2622 } else if (DriverArgs
.hasArg(options::OPT_v
)) {
2623 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
2627 // Otherwise, don't add any path.
2631 case ToolChain::CST_Libstdcxx
:
2632 llvm::SmallString
<128> UsrIncludeCxx
= Sysroot
;
2633 llvm::sys::path::append(UsrIncludeCxx
, "usr", "include", "c++");
2635 llvm::Triple::ArchType arch
= getTriple().getArch();
2636 bool IsBaseFound
= true;
2640 case llvm::Triple::x86
:
2641 case llvm::Triple::x86_64
:
2642 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2644 "i686-apple-darwin10",
2645 arch
== llvm::Triple::x86_64
? "x86_64" : "");
2646 IsBaseFound
|= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2647 "4.0.0", "i686-apple-darwin8",
2651 case llvm::Triple::arm
:
2652 case llvm::Triple::thumb
:
2653 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2655 "arm-apple-darwin10",
2657 IsBaseFound
|= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2659 "arm-apple-darwin10",
2663 case llvm::Triple::aarch64
:
2664 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2666 "arm64-apple-darwin10",
2672 getDriver().Diag(diag::warn_drv_libstdcxx_not_found
);
2679 void DarwinClang::AddCXXStdlibLibArgs(const ArgList
&Args
,
2680 ArgStringList
&CmdArgs
) const {
2681 CXXStdlibType Type
= GetCXXStdlibType(Args
);
2684 case ToolChain::CST_Libcxx
:
2685 CmdArgs
.push_back("-lc++");
2686 if (Args
.hasArg(options::OPT_fexperimental_library
))
2687 CmdArgs
.push_back("-lc++experimental");
2690 case ToolChain::CST_Libstdcxx
:
2691 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
2692 // it was previously found in the gcc lib dir. However, for all the Darwin
2693 // platforms we care about it was -lstdc++.6, so we search for that
2694 // explicitly if we can't see an obvious -lstdc++ candidate.
2696 // Check in the sysroot first.
2697 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2698 SmallString
<128> P(A
->getValue());
2699 llvm::sys::path::append(P
, "usr", "lib", "libstdc++.dylib");
2701 if (!getVFS().exists(P
)) {
2702 llvm::sys::path::remove_filename(P
);
2703 llvm::sys::path::append(P
, "libstdc++.6.dylib");
2704 if (getVFS().exists(P
)) {
2705 CmdArgs
.push_back(Args
.MakeArgString(P
));
2711 // Otherwise, look in the root.
2712 // FIXME: This should be removed someday when we don't have to care about
2713 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
2714 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
2715 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
2716 CmdArgs
.push_back("/usr/lib/libstdc++.6.dylib");
2720 // Otherwise, let the linker search.
2721 CmdArgs
.push_back("-lstdc++");
2726 void DarwinClang::AddCCKextLibArgs(const ArgList
&Args
,
2727 ArgStringList
&CmdArgs
) const {
2728 // For Darwin platforms, use the compiler-rt-based support library
2729 // instead of the gcc-provided one (which is also incidentally
2730 // only present in the gcc lib dir, which makes it hard to find).
2732 SmallString
<128> P(getDriver().ResourceDir
);
2733 llvm::sys::path::append(P
, "lib", "darwin");
2735 // Use the newer cc_kext for iOS ARM after 6.0.
2736 if (isTargetWatchOS()) {
2737 llvm::sys::path::append(P
, "libclang_rt.cc_kext_watchos.a");
2738 } else if (isTargetTvOS()) {
2739 llvm::sys::path::append(P
, "libclang_rt.cc_kext_tvos.a");
2740 } else if (isTargetIPhoneOS()) {
2741 llvm::sys::path::append(P
, "libclang_rt.cc_kext_ios.a");
2742 } else if (isTargetDriverKit()) {
2743 // DriverKit doesn't want extra runtime support.
2744 } else if (isTargetXROSDevice()) {
2745 llvm::sys::path::append(
2746 P
, llvm::Twine("libclang_rt.cc_kext_") +
2747 llvm::Triple::getOSTypeName(llvm::Triple::XROS
) + ".a");
2749 llvm::sys::path::append(P
, "libclang_rt.cc_kext.a");
2752 // For now, allow missing resource libraries to support developers who may
2753 // not have compiler-rt checked out or integrated into their build.
2754 if (getVFS().exists(P
))
2755 CmdArgs
.push_back(Args
.MakeArgString(P
));
2758 DerivedArgList
*MachO::TranslateArgs(const DerivedArgList
&Args
,
2759 StringRef BoundArch
,
2760 Action::OffloadKind
) const {
2761 DerivedArgList
*DAL
= new DerivedArgList(Args
.getBaseArgs());
2762 const OptTable
&Opts
= getDriver().getOpts();
2764 // FIXME: We really want to get out of the tool chain level argument
2765 // translation business, as it makes the driver functionality much
2766 // more opaque. For now, we follow gcc closely solely for the
2767 // purpose of easily achieving feature parity & testability. Once we
2768 // have something that works, we should reevaluate each translation
2769 // and try to push it down into tool specific logic.
2771 for (Arg
*A
: Args
) {
2772 if (A
->getOption().matches(options::OPT_Xarch__
)) {
2773 // Skip this argument unless the architecture matches either the toolchain
2774 // triple arch, or the arch being bound.
2775 StringRef XarchArch
= A
->getValue(0);
2776 if (!(XarchArch
== getArchName() ||
2777 (!BoundArch
.empty() && XarchArch
== BoundArch
)))
2780 Arg
*OriginalArg
= A
;
2781 TranslateXarchArgs(Args
, A
, DAL
);
2783 // Linker input arguments require custom handling. The problem is that we
2784 // have already constructed the phase actions, so we can not treat them as
2785 // "input arguments".
2786 if (A
->getOption().hasFlag(options::LinkerInput
)) {
2787 // Convert the argument into individual Zlinker_input_args.
2788 for (const char *Value
: A
->getValues()) {
2789 DAL
->AddSeparateArg(
2790 OriginalArg
, Opts
.getOption(options::OPT_Zlinker_input
), Value
);
2796 // Sob. These is strictly gcc compatible for the time being. Apple
2797 // gcc translates options twice, which means that self-expanding
2798 // options add duplicates.
2799 switch ((options::ID
)A
->getOption().getID()) {
2804 case options::OPT_mkernel
:
2805 case options::OPT_fapple_kext
:
2807 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_static
));
2810 case options::OPT_dependency_file
:
2811 DAL
->AddSeparateArg(A
, Opts
.getOption(options::OPT_MF
), A
->getValue());
2814 case options::OPT_gfull
:
2815 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
));
2817 A
, Opts
.getOption(options::OPT_fno_eliminate_unused_debug_symbols
));
2820 case options::OPT_gused
:
2821 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
));
2823 A
, Opts
.getOption(options::OPT_feliminate_unused_debug_symbols
));
2826 case options::OPT_shared
:
2827 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_dynamiclib
));
2830 case options::OPT_fconstant_cfstrings
:
2831 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_mconstant_cfstrings
));
2834 case options::OPT_fno_constant_cfstrings
:
2835 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_mno_constant_cfstrings
));
2838 case options::OPT_Wnonportable_cfstrings
:
2840 Opts
.getOption(options::OPT_mwarn_nonportable_cfstrings
));
2843 case options::OPT_Wno_nonportable_cfstrings
:
2845 A
, Opts
.getOption(options::OPT_mno_warn_nonportable_cfstrings
));
2850 // Add the arch options based on the particular spelling of -arch, to match
2851 // how the driver works.
2852 if (!BoundArch
.empty()) {
2853 StringRef Name
= BoundArch
;
2854 const Option MCpu
= Opts
.getOption(options::OPT_mcpu_EQ
);
2855 const Option MArch
= Opts
.getOption(clang::driver::options::OPT_march_EQ
);
2857 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
2858 // which defines the list of which architectures we accept.
2861 else if (Name
== "ppc601")
2862 DAL
->AddJoinedArg(nullptr, MCpu
, "601");
2863 else if (Name
== "ppc603")
2864 DAL
->AddJoinedArg(nullptr, MCpu
, "603");
2865 else if (Name
== "ppc604")
2866 DAL
->AddJoinedArg(nullptr, MCpu
, "604");
2867 else if (Name
== "ppc604e")
2868 DAL
->AddJoinedArg(nullptr, MCpu
, "604e");
2869 else if (Name
== "ppc750")
2870 DAL
->AddJoinedArg(nullptr, MCpu
, "750");
2871 else if (Name
== "ppc7400")
2872 DAL
->AddJoinedArg(nullptr, MCpu
, "7400");
2873 else if (Name
== "ppc7450")
2874 DAL
->AddJoinedArg(nullptr, MCpu
, "7450");
2875 else if (Name
== "ppc970")
2876 DAL
->AddJoinedArg(nullptr, MCpu
, "970");
2878 else if (Name
== "ppc64" || Name
== "ppc64le")
2879 DAL
->AddFlagArg(nullptr, Opts
.getOption(options::OPT_m64
));
2881 else if (Name
== "i386")
2883 else if (Name
== "i486")
2884 DAL
->AddJoinedArg(nullptr, MArch
, "i486");
2885 else if (Name
== "i586")
2886 DAL
->AddJoinedArg(nullptr, MArch
, "i586");
2887 else if (Name
== "i686")
2888 DAL
->AddJoinedArg(nullptr, MArch
, "i686");
2889 else if (Name
== "pentium")
2890 DAL
->AddJoinedArg(nullptr, MArch
, "pentium");
2891 else if (Name
== "pentium2")
2892 DAL
->AddJoinedArg(nullptr, MArch
, "pentium2");
2893 else if (Name
== "pentpro")
2894 DAL
->AddJoinedArg(nullptr, MArch
, "pentiumpro");
2895 else if (Name
== "pentIIm3")
2896 DAL
->AddJoinedArg(nullptr, MArch
, "pentium2");
2898 else if (Name
== "x86_64" || Name
== "x86_64h")
2899 DAL
->AddFlagArg(nullptr, Opts
.getOption(options::OPT_m64
));
2901 else if (Name
== "arm")
2902 DAL
->AddJoinedArg(nullptr, MArch
, "armv4t");
2903 else if (Name
== "armv4t")
2904 DAL
->AddJoinedArg(nullptr, MArch
, "armv4t");
2905 else if (Name
== "armv5")
2906 DAL
->AddJoinedArg(nullptr, MArch
, "armv5tej");
2907 else if (Name
== "xscale")
2908 DAL
->AddJoinedArg(nullptr, MArch
, "xscale");
2909 else if (Name
== "armv6")
2910 DAL
->AddJoinedArg(nullptr, MArch
, "armv6k");
2911 else if (Name
== "armv6m")
2912 DAL
->AddJoinedArg(nullptr, MArch
, "armv6m");
2913 else if (Name
== "armv7")
2914 DAL
->AddJoinedArg(nullptr, MArch
, "armv7a");
2915 else if (Name
== "armv7em")
2916 DAL
->AddJoinedArg(nullptr, MArch
, "armv7em");
2917 else if (Name
== "armv7k")
2918 DAL
->AddJoinedArg(nullptr, MArch
, "armv7k");
2919 else if (Name
== "armv7m")
2920 DAL
->AddJoinedArg(nullptr, MArch
, "armv7m");
2921 else if (Name
== "armv7s")
2922 DAL
->AddJoinedArg(nullptr, MArch
, "armv7s");
2928 void MachO::AddLinkRuntimeLibArgs(const ArgList
&Args
,
2929 ArgStringList
&CmdArgs
,
2930 bool ForceLinkBuiltinRT
) const {
2931 // Embedded targets are simple at the moment, not supporting sanitizers and
2932 // with different libraries for each member of the product { static, PIC } x
2933 // { hard-float, soft-float }
2934 llvm::SmallString
<32> CompilerRT
= StringRef("");
2936 (tools::arm::getARMFloatABI(*this, Args
) == tools::arm::FloatABI::Hard
)
2939 CompilerRT
+= Args
.hasArg(options::OPT_fPIC
) ? "_pic" : "_static";
2941 AddLinkRuntimeLib(Args
, CmdArgs
, CompilerRT
, RLO_IsEmbedded
);
2944 bool Darwin::isAlignedAllocationUnavailable() const {
2945 llvm::Triple::OSType OS
;
2947 if (isTargetMacCatalyst())
2948 return TargetVersion
< alignedAllocMinVersion(llvm::Triple::MacOSX
);
2949 switch (TargetPlatform
) {
2950 case MacOS
: // Earlier than 10.13.
2951 OS
= llvm::Triple::MacOSX
;
2954 OS
= llvm::Triple::IOS
;
2956 case TvOS
: // Earlier than 11.0.
2957 OS
= llvm::Triple::TvOS
;
2959 case WatchOS
: // Earlier than 4.0.
2960 OS
= llvm::Triple::WatchOS
;
2962 case XROS
: // Always available.
2964 case DriverKit
: // Always available.
2968 return TargetVersion
< alignedAllocMinVersion(OS
);
2971 static bool sdkSupportsBuiltinModules(
2972 const Darwin::DarwinPlatformKind
&TargetPlatform
,
2973 const Darwin::DarwinEnvironmentKind
&TargetEnvironment
,
2974 const std::optional
<DarwinSDKInfo
> &SDKInfo
) {
2975 if (TargetEnvironment
== Darwin::NativeEnvironment
||
2976 TargetEnvironment
== Darwin::Simulator
||
2977 TargetEnvironment
== Darwin::MacCatalyst
) {
2978 // Standard xnu/Mach/Darwin based environments
2979 // depend on the SDK version.
2981 // All other environments support builtin modules from the start.
2986 // If there is no SDK info, assume this is building against a
2987 // pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those
2988 // don't support modules anyway, but the headers definitely
2989 // don't support builtin modules either. It might also be some
2990 // kind of degenerate build environment, err on the side of
2991 // the old behavior which is to not use builtin modules.
2994 VersionTuple SDKVersion
= SDKInfo
->getVersion();
2995 switch (TargetPlatform
) {
2996 // Existing SDKs added support for builtin modules in the fall
2997 // 2024 major releases.
2999 return SDKVersion
>= VersionTuple(15U);
3000 case Darwin::IPhoneOS
:
3001 switch (TargetEnvironment
) {
3002 case Darwin::MacCatalyst
:
3003 // Mac Catalyst uses `-target arm64-apple-ios18.0-macabi` so the platform
3004 // is iOS, but it builds with the macOS SDK, so it's the macOS SDK version
3006 return SDKVersion
>= VersionTuple(15U);
3008 return SDKVersion
>= VersionTuple(18U);
3011 return SDKVersion
>= VersionTuple(18U);
3012 case Darwin::WatchOS
:
3013 return SDKVersion
>= VersionTuple(11U);
3015 return SDKVersion
>= VersionTuple(2U);
3017 // New SDKs support builtin modules from the start.
3023 static inline llvm::VersionTuple
3024 sizedDeallocMinVersion(llvm::Triple::OSType OS
) {
3028 case llvm::Triple::Darwin
:
3029 case llvm::Triple::MacOSX
: // Earliest supporting version is 10.12.
3030 return llvm::VersionTuple(10U, 12U);
3031 case llvm::Triple::IOS
:
3032 case llvm::Triple::TvOS
: // Earliest supporting version is 10.0.0.
3033 return llvm::VersionTuple(10U);
3034 case llvm::Triple::WatchOS
: // Earliest supporting version is 3.0.0.
3035 return llvm::VersionTuple(3U);
3038 llvm_unreachable("Unexpected OS");
3041 bool Darwin::isSizedDeallocationUnavailable() const {
3042 llvm::Triple::OSType OS
;
3044 if (isTargetMacCatalyst())
3045 return TargetVersion
< sizedDeallocMinVersion(llvm::Triple::MacOSX
);
3046 switch (TargetPlatform
) {
3047 case MacOS
: // Earlier than 10.12.
3048 OS
= llvm::Triple::MacOSX
;
3051 OS
= llvm::Triple::IOS
;
3053 case TvOS
: // Earlier than 10.0.
3054 OS
= llvm::Triple::TvOS
;
3056 case WatchOS
: // Earlier than 3.0.
3057 OS
= llvm::Triple::WatchOS
;
3061 // Always available.
3065 return TargetVersion
< sizedDeallocMinVersion(OS
);
3068 void Darwin::addClangTargetOptions(
3069 const llvm::opt::ArgList
&DriverArgs
, llvm::opt::ArgStringList
&CC1Args
,
3070 Action::OffloadKind DeviceOffloadKind
) const {
3071 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
3072 // enabled or disabled aligned allocations.
3073 if (!DriverArgs
.hasArgNoClaim(options::OPT_faligned_allocation
,
3074 options::OPT_fno_aligned_allocation
) &&
3075 isAlignedAllocationUnavailable())
3076 CC1Args
.push_back("-faligned-alloc-unavailable");
3078 // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
3079 // or disabled sized deallocations.
3080 if (!DriverArgs
.hasArgNoClaim(options::OPT_fsized_deallocation
,
3081 options::OPT_fno_sized_deallocation
) &&
3082 isSizedDeallocationUnavailable())
3083 CC1Args
.push_back("-fno-sized-deallocation");
3085 addClangCC1ASTargetOptions(DriverArgs
, CC1Args
);
3087 // Enable compatibility mode for NSItemProviderCompletionHandler in
3088 // Foundation/NSItemProvider.h.
3089 CC1Args
.push_back("-fcompatibility-qualified-id-block-type-checking");
3091 // Give static local variables in inline functions hidden visibility when
3092 // -fvisibility-inlines-hidden is enabled.
3093 if (!DriverArgs
.getLastArgNoClaim(
3094 options::OPT_fvisibility_inlines_hidden_static_local_var
,
3095 options::OPT_fno_visibility_inlines_hidden_static_local_var
))
3096 CC1Args
.push_back("-fvisibility-inlines-hidden-static-local-var");
3098 // Earlier versions of the darwin SDK have the C standard library headers
3099 // all together in the Darwin module. That leads to module cycles with
3100 // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.
3101 // The builtin <stdint.h> include-nexts <stdint.h>. When both of those
3102 // darwin headers are in the Darwin module, there's a module cycle Darwin ->
3103 // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->
3104 // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,
3105 // but until then, the builtin headers need to join the system modules.
3106 // i.e. when the builtin stdint.h is in the Darwin module too, the cycle
3107 // goes away. Note that -fbuiltin-headers-in-system-modules does nothing
3108 // to fix the same problem with C++ headers, and is generally fragile.
3109 if (!sdkSupportsBuiltinModules(TargetPlatform
, TargetEnvironment
, SDKInfo
))
3110 CC1Args
.push_back("-fbuiltin-headers-in-system-modules");
3112 if (!DriverArgs
.hasArgNoClaim(options::OPT_fdefine_target_os_macros
,
3113 options::OPT_fno_define_target_os_macros
))
3114 CC1Args
.push_back("-fdefine-target-os-macros");
3116 // Disable subdirectory modulemap search on sufficiently recent SDKs.
3118 !DriverArgs
.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search
,
3119 options::OPT_fno_modulemap_allow_subdirectory_search
,
3121 bool RequiresSubdirectorySearch
;
3122 VersionTuple SDKVersion
= SDKInfo
->getVersion();
3123 switch (TargetPlatform
) {
3125 RequiresSubdirectorySearch
= true;
3128 RequiresSubdirectorySearch
= SDKVersion
< VersionTuple(15, 0);
3132 RequiresSubdirectorySearch
= SDKVersion
< VersionTuple(18, 0);
3135 RequiresSubdirectorySearch
= SDKVersion
< VersionTuple(11, 0);
3138 RequiresSubdirectorySearch
= SDKVersion
< VersionTuple(2, 0);
3141 if (!RequiresSubdirectorySearch
)
3142 CC1Args
.push_back("-fno-modulemap-allow-subdirectory-search");
3146 void Darwin::addClangCC1ASTargetOptions(
3147 const llvm::opt::ArgList
&Args
, llvm::opt::ArgStringList
&CC1ASArgs
) const {
3148 if (TargetVariantTriple
) {
3149 CC1ASArgs
.push_back("-darwin-target-variant-triple");
3150 CC1ASArgs
.push_back(Args
.MakeArgString(TargetVariantTriple
->getTriple()));
3154 /// Pass the SDK version to the compiler when the SDK information is
3156 auto EmitTargetSDKVersionArg
= [&](const VersionTuple
&V
) {
3158 llvm::raw_string_ostream
OS(Arg
);
3159 OS
<< "-target-sdk-version=" << V
;
3160 CC1ASArgs
.push_back(Args
.MakeArgString(Arg
));
3163 if (isTargetMacCatalyst()) {
3164 if (const auto *MacOStoMacCatalystMapping
= SDKInfo
->getVersionMapping(
3165 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
3166 std::optional
<VersionTuple
> SDKVersion
= MacOStoMacCatalystMapping
->map(
3167 SDKInfo
->getVersion(), minimumMacCatalystDeploymentTarget(),
3169 EmitTargetSDKVersionArg(
3170 SDKVersion
? *SDKVersion
: minimumMacCatalystDeploymentTarget());
3173 EmitTargetSDKVersionArg(SDKInfo
->getVersion());
3176 /// Pass the target variant SDK version to the compiler when the SDK
3177 /// information is available and is required for target variant.
3178 if (TargetVariantTriple
) {
3179 if (isTargetMacCatalyst()) {
3181 llvm::raw_string_ostream
OS(Arg
);
3182 OS
<< "-darwin-target-variant-sdk-version=" << SDKInfo
->getVersion();
3183 CC1ASArgs
.push_back(Args
.MakeArgString(Arg
));
3184 } else if (const auto *MacOStoMacCatalystMapping
=
3185 SDKInfo
->getVersionMapping(
3186 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
3187 if (std::optional
<VersionTuple
> SDKVersion
=
3188 MacOStoMacCatalystMapping
->map(
3189 SDKInfo
->getVersion(), minimumMacCatalystDeploymentTarget(),
3192 llvm::raw_string_ostream
OS(Arg
);
3193 OS
<< "-darwin-target-variant-sdk-version=" << *SDKVersion
;
3194 CC1ASArgs
.push_back(Args
.MakeArgString(Arg
));
3202 Darwin::TranslateArgs(const DerivedArgList
&Args
, StringRef BoundArch
,
3203 Action::OffloadKind DeviceOffloadKind
) const {
3204 // First get the generic Apple args, before moving onto Darwin-specific ones.
3205 DerivedArgList
*DAL
=
3206 MachO::TranslateArgs(Args
, BoundArch
, DeviceOffloadKind
);
3208 // If no architecture is bound, none of the translations here are relevant.
3209 if (BoundArch
.empty())
3212 // Add an explicit version min argument for the deployment target. We do this
3213 // after argument translation because -Xarch_ arguments may add a version min
3215 AddDeploymentTarget(*DAL
);
3217 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
3218 // FIXME: It would be far better to avoid inserting those -static arguments,
3219 // but we can't check the deployment target in the translation code until
3221 if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS() ||
3222 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
3223 for (ArgList::iterator it
= DAL
->begin(), ie
= DAL
->end(); it
!= ie
; ) {
3226 if (A
->getOption().getID() != options::OPT_mkernel
&&
3227 A
->getOption().getID() != options::OPT_fapple_kext
)
3229 assert(it
!= ie
&& "unexpected argument translation");
3231 assert(A
->getOption().getID() == options::OPT_static
&&
3232 "missing expected -static argument");
3238 auto Arch
= tools::darwin::getArchTypeForMachOArchName(BoundArch
);
3239 if ((Arch
== llvm::Triple::arm
|| Arch
== llvm::Triple::thumb
)) {
3240 if (Args
.hasFlag(options::OPT_fomit_frame_pointer
,
3241 options::OPT_fno_omit_frame_pointer
, false))
3242 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target
)
3243 << "-fomit-frame-pointer" << BoundArch
;
3249 ToolChain::UnwindTableLevel
MachO::getDefaultUnwindTableLevel(const ArgList
&Args
) const {
3250 // Unwind tables are not emitted if -fno-exceptions is supplied (except when
3251 // targeting x86_64).
3252 if (getArch() == llvm::Triple::x86_64
||
3253 (GetExceptionModel(Args
) != llvm::ExceptionHandling::SjLj
&&
3254 Args
.hasFlag(options::OPT_fexceptions
, options::OPT_fno_exceptions
,
3256 return (getArch() == llvm::Triple::aarch64
||
3257 getArch() == llvm::Triple::aarch64_32
)
3258 ? UnwindTableLevel::Synchronous
3259 : UnwindTableLevel::Asynchronous
;
3261 return UnwindTableLevel::None
;
3264 bool MachO::UseDwarfDebugFlags() const {
3265 if (const char *S
= ::getenv("RC_DEBUG_OPTIONS"))
3266 return S
[0] != '\0';
3270 std::string
MachO::GetGlobalDebugPathRemapping() const {
3271 if (const char *S
= ::getenv("RC_DEBUG_PREFIX_MAP"))
3276 llvm::ExceptionHandling
Darwin::GetExceptionModel(const ArgList
&Args
) const {
3277 // Darwin uses SjLj exceptions on ARM.
3278 if (getTriple().getArch() != llvm::Triple::arm
&&
3279 getTriple().getArch() != llvm::Triple::thumb
)
3280 return llvm::ExceptionHandling::None
;
3282 // Only watchOS uses the new DWARF/Compact unwinding method.
3283 llvm::Triple
Triple(ComputeLLVMTriple(Args
));
3284 if (Triple
.isWatchABI())
3285 return llvm::ExceptionHandling::DwarfCFI
;
3287 return llvm::ExceptionHandling::SjLj
;
3290 bool Darwin::SupportsEmbeddedBitcode() const {
3291 assert(TargetInitialized
&& "Target not initialized!");
3292 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
3297 bool MachO::isPICDefault() const { return true; }
3299 bool MachO::isPIEDefault(const llvm::opt::ArgList
&Args
) const { return false; }
3301 bool MachO::isPICDefaultForced() const {
3302 return (getArch() == llvm::Triple::x86_64
||
3303 getArch() == llvm::Triple::aarch64
);
3306 bool MachO::SupportsProfiling() const {
3307 // Profiling instrumentation is only supported on x86.
3308 return getTriple().isX86();
3311 void Darwin::addMinVersionArgs(const ArgList
&Args
,
3312 ArgStringList
&CmdArgs
) const {
3313 VersionTuple TargetVersion
= getTripleTargetVersion();
3315 assert(!isTargetXROS() && "xrOS always uses -platform-version");
3317 if (isTargetWatchOS())
3318 CmdArgs
.push_back("-watchos_version_min");
3319 else if (isTargetWatchOSSimulator())
3320 CmdArgs
.push_back("-watchos_simulator_version_min");
3321 else if (isTargetTvOS())
3322 CmdArgs
.push_back("-tvos_version_min");
3323 else if (isTargetTvOSSimulator())
3324 CmdArgs
.push_back("-tvos_simulator_version_min");
3325 else if (isTargetDriverKit())
3326 CmdArgs
.push_back("-driverkit_version_min");
3327 else if (isTargetIOSSimulator())
3328 CmdArgs
.push_back("-ios_simulator_version_min");
3329 else if (isTargetIOSBased())
3330 CmdArgs
.push_back("-iphoneos_version_min");
3331 else if (isTargetMacCatalyst())
3332 CmdArgs
.push_back("-maccatalyst_version_min");
3334 assert(isTargetMacOS() && "unexpected target");
3335 CmdArgs
.push_back("-macosx_version_min");
3338 VersionTuple MinTgtVers
= getEffectiveTriple().getMinimumSupportedOSVersion();
3339 if (!MinTgtVers
.empty() && MinTgtVers
> TargetVersion
)
3340 TargetVersion
= MinTgtVers
;
3341 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3342 if (TargetVariantTriple
) {
3343 assert(isTargetMacOSBased() && "unexpected target");
3344 VersionTuple VariantTargetVersion
;
3345 if (TargetVariantTriple
->isMacOSX()) {
3346 CmdArgs
.push_back("-macosx_version_min");
3347 TargetVariantTriple
->getMacOSXVersion(VariantTargetVersion
);
3349 assert(TargetVariantTriple
->isiOS() &&
3350 TargetVariantTriple
->isMacCatalystEnvironment() &&
3351 "unexpected target variant triple");
3352 CmdArgs
.push_back("-maccatalyst_version_min");
3353 VariantTargetVersion
= TargetVariantTriple
->getiOSVersion();
3355 VersionTuple MinTgtVers
=
3356 TargetVariantTriple
->getMinimumSupportedOSVersion();
3357 if (MinTgtVers
.getMajor() && MinTgtVers
> VariantTargetVersion
)
3358 VariantTargetVersion
= MinTgtVers
;
3359 CmdArgs
.push_back(Args
.MakeArgString(VariantTargetVersion
.getAsString()));
3363 static const char *getPlatformName(Darwin::DarwinPlatformKind Platform
,
3364 Darwin::DarwinEnvironmentKind Environment
) {
3368 case Darwin::IPhoneOS
:
3369 if (Environment
== Darwin::MacCatalyst
)
3370 return "mac catalyst";
3374 case Darwin::WatchOS
:
3378 case Darwin::DriverKit
:
3381 llvm_unreachable("invalid platform");
3384 void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList
&Args
,
3385 llvm::opt::ArgStringList
&CmdArgs
) const {
3386 auto EmitPlatformVersionArg
=
3387 [&](const VersionTuple
&TV
, Darwin::DarwinPlatformKind TargetPlatform
,
3388 Darwin::DarwinEnvironmentKind TargetEnvironment
,
3389 const llvm::Triple
&TT
) {
3390 // -platform_version <platform> <target_version> <sdk_version>
3391 // Both the target and SDK version support only up to 3 components.
3392 CmdArgs
.push_back("-platform_version");
3393 std::string PlatformName
=
3394 getPlatformName(TargetPlatform
, TargetEnvironment
);
3395 if (TargetEnvironment
== Darwin::Simulator
)
3396 PlatformName
+= "-simulator";
3397 CmdArgs
.push_back(Args
.MakeArgString(PlatformName
));
3398 VersionTuple TargetVersion
= TV
.withoutBuild();
3399 if ((TargetPlatform
== Darwin::IPhoneOS
||
3400 TargetPlatform
== Darwin::TvOS
) &&
3401 getTriple().getArchName() == "arm64e" &&
3402 TargetVersion
.getMajor() < 14) {
3403 // arm64e slice is supported on iOS/tvOS 14+ only.
3404 TargetVersion
= VersionTuple(14, 0);
3406 VersionTuple MinTgtVers
= TT
.getMinimumSupportedOSVersion();
3407 if (!MinTgtVers
.empty() && MinTgtVers
> TargetVersion
)
3408 TargetVersion
= MinTgtVers
;
3409 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3411 if (TargetPlatform
== IPhoneOS
&& TargetEnvironment
== MacCatalyst
) {
3412 // Mac Catalyst programs must use the appropriate iOS SDK version
3413 // that corresponds to the macOS SDK version used for the compilation.
3414 std::optional
<VersionTuple
> iOSSDKVersion
;
3416 if (const auto *MacOStoMacCatalystMapping
=
3417 SDKInfo
->getVersionMapping(
3418 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
3419 iOSSDKVersion
= MacOStoMacCatalystMapping
->map(
3420 SDKInfo
->getVersion().withoutBuild(),
3421 minimumMacCatalystDeploymentTarget(), std::nullopt
);
3424 CmdArgs
.push_back(Args
.MakeArgString(
3425 (iOSSDKVersion
? *iOSSDKVersion
3426 : minimumMacCatalystDeploymentTarget())
3432 VersionTuple SDKVersion
= SDKInfo
->getVersion().withoutBuild();
3433 if (!SDKVersion
.getMinor())
3434 SDKVersion
= VersionTuple(SDKVersion
.getMajor(), 0);
3435 CmdArgs
.push_back(Args
.MakeArgString(SDKVersion
.getAsString()));
3437 // Use an SDK version that's matching the deployment target if the SDK
3438 // version is missing. This is preferred over an empty SDK version
3439 // (0.0.0) as the system's runtime might expect the linked binary to
3440 // contain a valid SDK version in order for the binary to work
3441 // correctly. It's reasonable to use the deployment target version as
3442 // a proxy for the SDK version because older SDKs don't guarantee
3443 // support for deployment targets newer than the SDK versions, so that
3444 // rules out using some predetermined older SDK version, which leaves
3445 // the deployment target version as the only reasonable choice.
3446 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3449 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform
,
3450 TargetEnvironment
, getEffectiveTriple());
3451 if (!TargetVariantTriple
)
3453 Darwin::DarwinPlatformKind Platform
;
3454 Darwin::DarwinEnvironmentKind Environment
;
3455 VersionTuple TargetVariantVersion
;
3456 if (TargetVariantTriple
->isMacOSX()) {
3457 TargetVariantTriple
->getMacOSXVersion(TargetVariantVersion
);
3458 Platform
= Darwin::MacOS
;
3459 Environment
= Darwin::NativeEnvironment
;
3461 assert(TargetVariantTriple
->isiOS() &&
3462 TargetVariantTriple
->isMacCatalystEnvironment() &&
3463 "unexpected target variant triple");
3464 TargetVariantVersion
= TargetVariantTriple
->getiOSVersion();
3465 Platform
= Darwin::IPhoneOS
;
3466 Environment
= Darwin::MacCatalyst
;
3468 EmitPlatformVersionArg(TargetVariantVersion
, Platform
, Environment
,
3469 *TargetVariantTriple
);
3472 // Add additional link args for the -dynamiclib option.
3473 static void addDynamicLibLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3474 ArgStringList
&CmdArgs
) {
3475 // Derived from darwin_dylib1 spec.
3476 if (D
.isTargetIPhoneOS()) {
3477 if (D
.isIPhoneOSVersionLT(3, 1))
3478 CmdArgs
.push_back("-ldylib1.o");
3482 if (!D
.isTargetMacOS())
3484 if (D
.isMacosxVersionLT(10, 5))
3485 CmdArgs
.push_back("-ldylib1.o");
3486 else if (D
.isMacosxVersionLT(10, 6))
3487 CmdArgs
.push_back("-ldylib1.10.5.o");
3490 // Add additional link args for the -bundle option.
3491 static void addBundleLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3492 ArgStringList
&CmdArgs
) {
3493 if (Args
.hasArg(options::OPT_static
))
3495 // Derived from darwin_bundle1 spec.
3496 if ((D
.isTargetIPhoneOS() && D
.isIPhoneOSVersionLT(3, 1)) ||
3497 (D
.isTargetMacOS() && D
.isMacosxVersionLT(10, 6)))
3498 CmdArgs
.push_back("-lbundle1.o");
3501 // Add additional link args for the -pg option.
3502 static void addPgProfilingLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3503 ArgStringList
&CmdArgs
) {
3504 if (D
.isTargetMacOS() && D
.isMacosxVersionLT(10, 9)) {
3505 if (Args
.hasArg(options::OPT_static
) || Args
.hasArg(options::OPT_object
) ||
3506 Args
.hasArg(options::OPT_preload
)) {
3507 CmdArgs
.push_back("-lgcrt0.o");
3509 CmdArgs
.push_back("-lgcrt1.o");
3511 // darwin_crt2 spec is empty.
3513 // By default on OS X 10.8 and later, we don't link with a crt1.o
3514 // file and the linker knows to use _main as the entry point. But,
3515 // when compiling with -pg, we need to link with the gcrt1.o file,
3516 // so pass the -no_new_main option to tell the linker to use the
3517 // "start" symbol as the entry point.
3518 if (!D
.isMacosxVersionLT(10, 8))
3519 CmdArgs
.push_back("-no_new_main");
3521 D
.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin
)
3522 << D
.isTargetMacOSBased();
3526 static void addDefaultCRTLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3527 ArgStringList
&CmdArgs
) {
3528 // Derived from darwin_crt1 spec.
3529 if (D
.isTargetIPhoneOS()) {
3530 if (D
.getArch() == llvm::Triple::aarch64
)
3531 ; // iOS does not need any crt1 files for arm64
3532 else if (D
.isIPhoneOSVersionLT(3, 1))
3533 CmdArgs
.push_back("-lcrt1.o");
3534 else if (D
.isIPhoneOSVersionLT(6, 0))
3535 CmdArgs
.push_back("-lcrt1.3.1.o");
3539 if (!D
.isTargetMacOS())
3541 if (D
.isMacosxVersionLT(10, 5))
3542 CmdArgs
.push_back("-lcrt1.o");
3543 else if (D
.isMacosxVersionLT(10, 6))
3544 CmdArgs
.push_back("-lcrt1.10.5.o");
3545 else if (D
.isMacosxVersionLT(10, 8))
3546 CmdArgs
.push_back("-lcrt1.10.6.o");
3547 // darwin_crt2 spec is empty.
3550 void Darwin::addStartObjectFileArgs(const ArgList
&Args
,
3551 ArgStringList
&CmdArgs
) const {
3552 // Derived from startfile spec.
3553 if (Args
.hasArg(options::OPT_dynamiclib
))
3554 addDynamicLibLinkArgs(*this, Args
, CmdArgs
);
3555 else if (Args
.hasArg(options::OPT_bundle
))
3556 addBundleLinkArgs(*this, Args
, CmdArgs
);
3557 else if (Args
.hasArg(options::OPT_pg
) && SupportsProfiling())
3558 addPgProfilingLinkArgs(*this, Args
, CmdArgs
);
3559 else if (Args
.hasArg(options::OPT_static
) ||
3560 Args
.hasArg(options::OPT_object
) ||
3561 Args
.hasArg(options::OPT_preload
))
3562 CmdArgs
.push_back("-lcrt0.o");
3564 addDefaultCRTLinkArgs(*this, Args
, CmdArgs
);
3566 if (isTargetMacOS() && Args
.hasArg(options::OPT_shared_libgcc
) &&
3567 isMacosxVersionLT(10, 5)) {
3568 const char *Str
= Args
.MakeArgString(GetFilePath("crt3.o"));
3569 CmdArgs
.push_back(Str
);
3573 void Darwin::CheckObjCARC() const {
3574 if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() ||
3575 (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)))
3577 getDriver().Diag(diag::err_arc_unsupported_on_toolchain
);
3580 SanitizerMask
Darwin::getSupportedSanitizers() const {
3581 const bool IsX86_64
= getTriple().getArch() == llvm::Triple::x86_64
;
3582 const bool IsAArch64
= getTriple().getArch() == llvm::Triple::aarch64
;
3583 SanitizerMask Res
= ToolChain::getSupportedSanitizers();
3584 Res
|= SanitizerKind::Address
;
3585 Res
|= SanitizerKind::PointerCompare
;
3586 Res
|= SanitizerKind::PointerSubtract
;
3587 Res
|= SanitizerKind::Realtime
;
3588 Res
|= SanitizerKind::Leak
;
3589 Res
|= SanitizerKind::Fuzzer
;
3590 Res
|= SanitizerKind::FuzzerNoLink
;
3591 Res
|= SanitizerKind::ObjCCast
;
3593 // Prior to 10.9, macOS shipped a version of the C++ standard library without
3594 // C++11 support. The same is true of iOS prior to version 5. These OS'es are
3595 // incompatible with -fsanitize=vptr.
3596 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
3597 !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
3598 Res
|= SanitizerKind::Vptr
;
3600 if ((IsX86_64
|| IsAArch64
) &&
3601 (isTargetMacOSBased() || isTargetIOSSimulator() ||
3602 isTargetTvOSSimulator() || isTargetWatchOSSimulator())) {
3603 Res
|= SanitizerKind::Thread
;
3607 Res
|= SanitizerKind::NumericalStability
;
3612 void Darwin::printVerboseInfo(raw_ostream
&OS
) const {
3613 CudaInstallation
->print(OS
);
3614 RocmInstallation
->print(OS
);