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/TargetParser.h"
27 #include "llvm/Support/Threading.h"
28 #include "llvm/Support/VirtualFileSystem.h"
29 #include <cstdlib> // ::getenv
31 using namespace clang::driver
;
32 using namespace clang::driver::tools
;
33 using namespace clang::driver::toolchains
;
34 using namespace clang
;
35 using namespace llvm::opt
;
37 static VersionTuple
minimumMacCatalystDeploymentTarget() {
38 return VersionTuple(13, 1);
41 llvm::Triple::ArchType
darwin::getArchTypeForMachOArchName(StringRef Str
) {
42 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
43 // archs which Darwin doesn't use.
45 // The matching this routine does is fairly pointless, since it is neither the
46 // complete architecture list, nor a reasonable subset. The problem is that
47 // historically the driver driver accepts this and also ties its -march=
48 // handling to the architecture name, so we need to be careful before removing
51 // This code must be kept in sync with Clang's Darwin specific argument
54 return llvm::StringSwitch
<llvm::Triple::ArchType
>(Str
)
55 .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc
)
56 .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc
)
57 .Case("ppc64", llvm::Triple::ppc64
)
58 .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86
)
59 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
61 .Cases("x86_64", "x86_64h", llvm::Triple::x86_64
)
62 // This is derived from the driver driver.
63 .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm
)
64 .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm
)
65 .Cases("armv7s", "xscale", llvm::Triple::arm
)
66 .Cases("arm64", "arm64e", llvm::Triple::aarch64
)
67 .Case("arm64_32", llvm::Triple::aarch64_32
)
68 .Case("r600", llvm::Triple::r600
)
69 .Case("amdgcn", llvm::Triple::amdgcn
)
70 .Case("nvptx", llvm::Triple::nvptx
)
71 .Case("nvptx64", llvm::Triple::nvptx64
)
72 .Case("amdil", llvm::Triple::amdil
)
73 .Case("spir", llvm::Triple::spir
)
74 .Default(llvm::Triple::UnknownArch
);
77 void darwin::setTripleTypeForMachOArchName(llvm::Triple
&T
, StringRef Str
) {
78 const llvm::Triple::ArchType Arch
= getArchTypeForMachOArchName(Str
);
79 llvm::ARM::ArchKind ArchKind
= llvm::ARM::parseArch(Str
);
81 if (Arch
!= llvm::Triple::UnknownArch
)
84 if (ArchKind
== llvm::ARM::ArchKind::ARMV6M
||
85 ArchKind
== llvm::ARM::ArchKind::ARMV7M
||
86 ArchKind
== llvm::ARM::ArchKind::ARMV7EM
) {
87 T
.setOS(llvm::Triple::UnknownOS
);
88 T
.setObjectFormat(llvm::Triple::MachO
);
92 void darwin::Assembler::ConstructJob(Compilation
&C
, const JobAction
&JA
,
93 const InputInfo
&Output
,
94 const InputInfoList
&Inputs
,
96 const char *LinkingOutput
) const {
97 const llvm::Triple
&T(getToolChain().getTriple());
99 ArgStringList CmdArgs
;
101 assert(Inputs
.size() == 1 && "Unexpected number of inputs.");
102 const InputInfo
&Input
= Inputs
[0];
104 // Determine the original source input.
105 const Action
*SourceAction
= &JA
;
106 while (SourceAction
->getKind() != Action::InputClass
) {
107 assert(!SourceAction
->getInputs().empty() && "unexpected root action!");
108 SourceAction
= SourceAction
->getInputs()[0];
111 // If -fno-integrated-as is used add -Q to the darwin assembler driver to make
112 // sure it runs its system assembler not clang's integrated assembler.
113 // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as.
114 // FIXME: at run-time detect assembler capabilities or rely on version
115 // information forwarded by -target-assembler-version.
116 if (Args
.hasArg(options::OPT_fno_integrated_as
)) {
117 if (!(T
.isMacOSX() && T
.isMacOSXVersionLT(10, 7)))
118 CmdArgs
.push_back("-Q");
121 // Forward -g, assuming we are dealing with an actual assembly file.
122 if (SourceAction
->getType() == types::TY_Asm
||
123 SourceAction
->getType() == types::TY_PP_Asm
) {
124 if (Args
.hasArg(options::OPT_gstabs
))
125 CmdArgs
.push_back("--gstabs");
126 else if (Args
.hasArg(options::OPT_g_Group
))
127 CmdArgs
.push_back("-g");
130 // Derived from asm spec.
131 AddMachOArch(Args
, CmdArgs
);
133 // Use -force_cpusubtype_ALL on x86 by default.
134 if (T
.isX86() || Args
.hasArg(options::OPT_force__cpusubtype__ALL
))
135 CmdArgs
.push_back("-force_cpusubtype_ALL");
137 if (getToolChain().getArch() != llvm::Triple::x86_64
&&
138 (((Args
.hasArg(options::OPT_mkernel
) ||
139 Args
.hasArg(options::OPT_fapple_kext
)) &&
140 getMachOToolChain().isKernelStatic()) ||
141 Args
.hasArg(options::OPT_static
)))
142 CmdArgs
.push_back("-static");
144 Args
.AddAllArgValues(CmdArgs
, options::OPT_Wa_COMMA
, options::OPT_Xassembler
);
146 assert(Output
.isFilename() && "Unexpected lipo output.");
147 CmdArgs
.push_back("-o");
148 CmdArgs
.push_back(Output
.getFilename());
150 assert(Input
.isFilename() && "Invalid input.");
151 CmdArgs
.push_back(Input
.getFilename());
153 // asm_final spec is empty.
155 const char *Exec
= Args
.MakeArgString(getToolChain().GetProgramPath("as"));
156 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
157 Exec
, CmdArgs
, Inputs
, Output
));
160 void darwin::MachOTool::anchor() {}
162 void darwin::MachOTool::AddMachOArch(const ArgList
&Args
,
163 ArgStringList
&CmdArgs
) const {
164 StringRef ArchName
= getMachOToolChain().getMachOArchName(Args
);
166 // Derived from darwin_arch spec.
167 CmdArgs
.push_back("-arch");
168 CmdArgs
.push_back(Args
.MakeArgString(ArchName
));
170 // FIXME: Is this needed anymore?
171 if (ArchName
== "arm")
172 CmdArgs
.push_back("-force_cpusubtype_ALL");
175 bool darwin::Linker::NeedsTempPath(const InputInfoList
&Inputs
) const {
176 // We only need to generate a temp path for LTO if we aren't compiling object
177 // files. When compiling source files, we run 'dsymutil' after linking. We
178 // don't run 'dsymutil' when compiling object files.
179 for (const auto &Input
: Inputs
)
180 if (Input
.getType() != types::TY_Object
)
186 /// Pass -no_deduplicate to ld64 under certain conditions:
188 /// - Either -O0 or -O1 is explicitly specified
189 /// - No -O option is specified *and* this is a compile+link (implicit -O0)
191 /// Also do *not* add -no_deduplicate when no -O option is specified and this
192 /// is just a link (we can't imply -O0)
193 static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction
, const ArgList
&Args
) {
194 if (Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
195 if (A
->getOption().matches(options::OPT_O0
))
197 if (A
->getOption().matches(options::OPT_O
))
198 return llvm::StringSwitch
<bool>(A
->getValue())
201 return false; // OPT_Ofast & OPT_O4
204 if (!IsLinkerOnlyAction
) // Implicit -O0 for compile+linker only.
209 void darwin::Linker::AddLinkArgs(Compilation
&C
, const ArgList
&Args
,
210 ArgStringList
&CmdArgs
,
211 const InputInfoList
&Inputs
,
212 VersionTuple Version
, bool LinkerIsLLD
) const {
213 const Driver
&D
= getToolChain().getDriver();
214 const toolchains::MachO
&MachOTC
= getMachOToolChain();
216 // Newer linkers support -demangle. Pass it if supported and not disabled by
218 if ((Version
>= VersionTuple(100) || LinkerIsLLD
) &&
219 !Args
.hasArg(options::OPT_Z_Xlinker__no_demangle
))
220 CmdArgs
.push_back("-demangle");
222 if (Args
.hasArg(options::OPT_rdynamic
) &&
223 (Version
>= VersionTuple(137) || LinkerIsLLD
))
224 CmdArgs
.push_back("-export_dynamic");
226 // If we are using App Extension restrictions, pass a flag to the linker
227 // telling it that the compiled code has been audited.
228 if (Args
.hasFlag(options::OPT_fapplication_extension
,
229 options::OPT_fno_application_extension
, false))
230 CmdArgs
.push_back("-application_extension");
232 if (D
.isUsingLTO() && (Version
>= VersionTuple(116) || LinkerIsLLD
) &&
233 NeedsTempPath(Inputs
)) {
234 std::string TmpPathName
;
235 if (D
.getLTOMode() == LTOK_Full
) {
236 // If we are using full LTO, then automatically create a temporary file
237 // path for the linker to use, so that it's lifetime will extend past a
238 // possible dsymutil step.
240 D
.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object
));
241 } else if (D
.getLTOMode() == LTOK_Thin
)
242 // If we are using thin LTO, then create a directory instead.
243 TmpPathName
= D
.GetTemporaryDirectory("thinlto");
245 if (!TmpPathName
.empty()) {
246 auto *TmpPath
= C
.getArgs().MakeArgString(TmpPathName
);
247 C
.addTempFile(TmpPath
);
248 CmdArgs
.push_back("-object_path_lto");
249 CmdArgs
.push_back(TmpPath
);
253 // Use -lto_library option to specify the libLTO.dylib path. Try to find
254 // it in clang installed libraries. ld64 will only look at this argument
255 // when it actually uses LTO, so libLTO.dylib only needs to exist at link
256 // time if ld64 decides that it needs to use LTO.
257 // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
258 // next to it. That's ok since ld64 using a libLTO.dylib not matching the
259 // clang version won't work anyways.
260 // lld is built at the same revision as clang and statically links in
261 // LLVM libraries, so it doesn't need libLTO.dylib.
262 if (Version
>= VersionTuple(133) && !LinkerIsLLD
) {
263 // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
264 StringRef P
= llvm::sys::path::parent_path(D
.Dir
);
265 SmallString
<128> LibLTOPath(P
);
266 llvm::sys::path::append(LibLTOPath
, "lib");
267 llvm::sys::path::append(LibLTOPath
, "libLTO.dylib");
268 CmdArgs
.push_back("-lto_library");
269 CmdArgs
.push_back(C
.getArgs().MakeArgString(LibLTOPath
));
272 // ld64 version 262 and above runs the deduplicate pass by default.
273 // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe`
274 // if `!shouldLinkerNotDedup()` if LinkerIsLLD here?
275 if (Version
>= VersionTuple(262) &&
276 shouldLinkerNotDedup(C
.getJobs().empty(), Args
))
277 CmdArgs
.push_back("-no_deduplicate");
279 // Derived from the "link" spec.
280 Args
.AddAllArgs(CmdArgs
, options::OPT_static
);
281 if (!Args
.hasArg(options::OPT_static
))
282 CmdArgs
.push_back("-dynamic");
283 if (Args
.hasArg(options::OPT_fgnu_runtime
)) {
284 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
285 // here. How do we wish to handle such things?
288 if (!Args
.hasArg(options::OPT_dynamiclib
)) {
289 AddMachOArch(Args
, CmdArgs
);
290 // FIXME: Why do this only on this path?
291 Args
.AddLastArg(CmdArgs
, options::OPT_force__cpusubtype__ALL
);
293 Args
.AddLastArg(CmdArgs
, options::OPT_bundle
);
294 Args
.AddAllArgs(CmdArgs
, options::OPT_bundle__loader
);
295 Args
.AddAllArgs(CmdArgs
, options::OPT_client__name
);
298 if ((A
= Args
.getLastArg(options::OPT_compatibility__version
)) ||
299 (A
= Args
.getLastArg(options::OPT_current__version
)) ||
300 (A
= Args
.getLastArg(options::OPT_install__name
)))
301 D
.Diag(diag::err_drv_argument_only_allowed_with
) << A
->getAsString(Args
)
304 Args
.AddLastArg(CmdArgs
, options::OPT_force__flat__namespace
);
305 Args
.AddLastArg(CmdArgs
, options::OPT_keep__private__externs
);
306 Args
.AddLastArg(CmdArgs
, options::OPT_private__bundle
);
308 CmdArgs
.push_back("-dylib");
311 if ((A
= Args
.getLastArg(options::OPT_bundle
)) ||
312 (A
= Args
.getLastArg(options::OPT_bundle__loader
)) ||
313 (A
= Args
.getLastArg(options::OPT_client__name
)) ||
314 (A
= Args
.getLastArg(options::OPT_force__flat__namespace
)) ||
315 (A
= Args
.getLastArg(options::OPT_keep__private__externs
)) ||
316 (A
= Args
.getLastArg(options::OPT_private__bundle
)))
317 D
.Diag(diag::err_drv_argument_not_allowed_with
) << A
->getAsString(Args
)
320 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_compatibility__version
,
321 "-dylib_compatibility_version");
322 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_current__version
,
323 "-dylib_current_version");
325 AddMachOArch(Args
, CmdArgs
);
327 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_install__name
,
328 "-dylib_install_name");
331 Args
.AddLastArg(CmdArgs
, options::OPT_all__load
);
332 Args
.AddAllArgs(CmdArgs
, options::OPT_allowable__client
);
333 Args
.AddLastArg(CmdArgs
, options::OPT_bind__at__load
);
334 if (MachOTC
.isTargetIOSBased())
335 Args
.AddLastArg(CmdArgs
, options::OPT_arch__errors__fatal
);
336 Args
.AddLastArg(CmdArgs
, options::OPT_dead__strip
);
337 Args
.AddLastArg(CmdArgs
, options::OPT_no__dead__strip__inits__and__terms
);
338 Args
.AddAllArgs(CmdArgs
, options::OPT_dylib__file
);
339 Args
.AddLastArg(CmdArgs
, options::OPT_dynamic
);
340 Args
.AddAllArgs(CmdArgs
, options::OPT_exported__symbols__list
);
341 Args
.AddLastArg(CmdArgs
, options::OPT_flat__namespace
);
342 Args
.AddAllArgs(CmdArgs
, options::OPT_force__load
);
343 Args
.AddAllArgs(CmdArgs
, options::OPT_headerpad__max__install__names
);
344 Args
.AddAllArgs(CmdArgs
, options::OPT_image__base
);
345 Args
.AddAllArgs(CmdArgs
, options::OPT_init
);
347 // Add the deployment target.
348 if (Version
>= VersionTuple(520) || LinkerIsLLD
)
349 MachOTC
.addPlatformVersionArgs(Args
, CmdArgs
);
351 MachOTC
.addMinVersionArgs(Args
, CmdArgs
);
353 Args
.AddLastArg(CmdArgs
, options::OPT_nomultidefs
);
354 Args
.AddLastArg(CmdArgs
, options::OPT_multi__module
);
355 Args
.AddLastArg(CmdArgs
, options::OPT_single__module
);
356 Args
.AddAllArgs(CmdArgs
, options::OPT_multiply__defined
);
357 Args
.AddAllArgs(CmdArgs
, options::OPT_multiply__defined__unused
);
360 Args
.getLastArg(options::OPT_fpie
, options::OPT_fPIE
,
361 options::OPT_fno_pie
, options::OPT_fno_PIE
)) {
362 if (A
->getOption().matches(options::OPT_fpie
) ||
363 A
->getOption().matches(options::OPT_fPIE
))
364 CmdArgs
.push_back("-pie");
366 CmdArgs
.push_back("-no_pie");
369 // for embed-bitcode, use -bitcode_bundle in linker command
370 if (C
.getDriver().embedBitcodeEnabled()) {
371 // Check if the toolchain supports bitcode build flow.
372 if (MachOTC
.SupportsEmbeddedBitcode()) {
373 CmdArgs
.push_back("-bitcode_bundle");
374 // FIXME: Pass this if LinkerIsLLD too, once it implements this flag.
375 if (C
.getDriver().embedBitcodeMarkerOnly() &&
376 Version
>= VersionTuple(278)) {
377 CmdArgs
.push_back("-bitcode_process_mode");
378 CmdArgs
.push_back("marker");
381 D
.Diag(diag::err_drv_bitcode_unsupported_on_toolchain
);
384 // If GlobalISel is enabled, pass it through to LLVM.
385 if (Arg
*A
= Args
.getLastArg(options::OPT_fglobal_isel
,
386 options::OPT_fno_global_isel
)) {
387 if (A
->getOption().matches(options::OPT_fglobal_isel
)) {
388 CmdArgs
.push_back("-mllvm");
389 CmdArgs
.push_back("-global-isel");
390 // Disable abort and fall back to SDAG silently.
391 CmdArgs
.push_back("-mllvm");
392 CmdArgs
.push_back("-global-isel-abort=0");
396 Args
.AddLastArg(CmdArgs
, options::OPT_prebind
);
397 Args
.AddLastArg(CmdArgs
, options::OPT_noprebind
);
398 Args
.AddLastArg(CmdArgs
, options::OPT_nofixprebinding
);
399 Args
.AddLastArg(CmdArgs
, options::OPT_prebind__all__twolevel__modules
);
400 Args
.AddLastArg(CmdArgs
, options::OPT_read__only__relocs
);
401 Args
.AddAllArgs(CmdArgs
, options::OPT_sectcreate
);
402 Args
.AddAllArgs(CmdArgs
, options::OPT_sectorder
);
403 Args
.AddAllArgs(CmdArgs
, options::OPT_seg1addr
);
404 Args
.AddAllArgs(CmdArgs
, options::OPT_segprot
);
405 Args
.AddAllArgs(CmdArgs
, options::OPT_segaddr
);
406 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__only__addr
);
407 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__write__addr
);
408 Args
.AddAllArgs(CmdArgs
, options::OPT_seg__addr__table
);
409 Args
.AddAllArgs(CmdArgs
, options::OPT_seg__addr__table__filename
);
410 Args
.AddAllArgs(CmdArgs
, options::OPT_sub__library
);
411 Args
.AddAllArgs(CmdArgs
, options::OPT_sub__umbrella
);
413 // Give --sysroot= preference, over the Apple specific behavior to also use
414 // --isysroot as the syslibroot.
415 StringRef sysroot
= C
.getSysRoot();
417 CmdArgs
.push_back("-syslibroot");
418 CmdArgs
.push_back(C
.getArgs().MakeArgString(sysroot
));
419 } else if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
420 CmdArgs
.push_back("-syslibroot");
421 CmdArgs
.push_back(A
->getValue());
424 Args
.AddLastArg(CmdArgs
, options::OPT_twolevel__namespace
);
425 Args
.AddLastArg(CmdArgs
, options::OPT_twolevel__namespace__hints
);
426 Args
.AddAllArgs(CmdArgs
, options::OPT_umbrella
);
427 Args
.AddAllArgs(CmdArgs
, options::OPT_undefined
);
428 Args
.AddAllArgs(CmdArgs
, options::OPT_unexported__symbols__list
);
429 Args
.AddAllArgs(CmdArgs
, options::OPT_weak__reference__mismatches
);
430 Args
.AddLastArg(CmdArgs
, options::OPT_X_Flag
);
431 Args
.AddAllArgs(CmdArgs
, options::OPT_y
);
432 Args
.AddLastArg(CmdArgs
, options::OPT_w
);
433 Args
.AddAllArgs(CmdArgs
, options::OPT_pagezero__size
);
434 Args
.AddAllArgs(CmdArgs
, options::OPT_segs__read__
);
435 Args
.AddLastArg(CmdArgs
, options::OPT_seglinkedit
);
436 Args
.AddLastArg(CmdArgs
, options::OPT_noseglinkedit
);
437 Args
.AddAllArgs(CmdArgs
, options::OPT_sectalign
);
438 Args
.AddAllArgs(CmdArgs
, options::OPT_sectobjectsymbols
);
439 Args
.AddAllArgs(CmdArgs
, options::OPT_segcreate
);
440 Args
.AddLastArg(CmdArgs
, options::OPT_why_load
);
441 Args
.AddLastArg(CmdArgs
, options::OPT_whatsloaded
);
442 Args
.AddAllArgs(CmdArgs
, options::OPT_dylinker__install__name
);
443 Args
.AddLastArg(CmdArgs
, options::OPT_dylinker
);
444 Args
.AddLastArg(CmdArgs
, options::OPT_Mach
);
447 /// Determine whether we are linking the ObjC runtime.
448 static bool isObjCRuntimeLinked(const ArgList
&Args
) {
449 if (isObjCAutoRefCount(Args
)) {
450 Args
.ClaimAllArgs(options::OPT_fobjc_link_runtime
);
453 return Args
.hasArg(options::OPT_fobjc_link_runtime
);
456 static bool checkRemarksOptions(const Driver
&D
, const ArgList
&Args
,
457 const llvm::Triple
&Triple
) {
458 // When enabling remarks, we need to error if:
459 // * The remark file is specified but we're targeting multiple architectures,
460 // which means more than one remark file is being generated.
461 bool hasMultipleInvocations
=
462 Args
.getAllArgValues(options::OPT_arch
).size() > 1;
463 bool hasExplicitOutputFile
=
464 Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
465 if (hasMultipleInvocations
&& hasExplicitOutputFile
) {
466 D
.Diag(diag::err_drv_invalid_output_with_multiple_archs
)
467 << "-foptimization-record-file";
473 static void renderRemarksOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
474 const llvm::Triple
&Triple
,
475 const InputInfo
&Output
, const JobAction
&JA
) {
476 StringRef Format
= "yaml";
477 if (const Arg
*A
= Args
.getLastArg(options::OPT_fsave_optimization_record_EQ
))
478 Format
= A
->getValue();
480 CmdArgs
.push_back("-mllvm");
481 CmdArgs
.push_back("-lto-pass-remarks-output");
482 CmdArgs
.push_back("-mllvm");
484 const Arg
*A
= Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
486 CmdArgs
.push_back(A
->getValue());
488 assert(Output
.isFilename() && "Unexpected ld output.");
490 F
= Output
.getFilename();
494 CmdArgs
.push_back(Args
.MakeArgString(F
));
498 Args
.getLastArg(options::OPT_foptimization_record_passes_EQ
)) {
499 CmdArgs
.push_back("-mllvm");
501 std::string("-lto-pass-remarks-filter=") + A
->getValue();
502 CmdArgs
.push_back(Args
.MakeArgString(Passes
));
505 if (!Format
.empty()) {
506 CmdArgs
.push_back("-mllvm");
507 Twine FormatArg
= Twine("-lto-pass-remarks-format=") + Format
;
508 CmdArgs
.push_back(Args
.MakeArgString(FormatArg
));
511 if (getLastProfileUseArg(Args
)) {
512 CmdArgs
.push_back("-mllvm");
513 CmdArgs
.push_back("-lto-pass-remarks-with-hotness");
516 Args
.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ
)) {
517 CmdArgs
.push_back("-mllvm");
519 std::string("-lto-pass-remarks-hotness-threshold=") + A
->getValue();
520 CmdArgs
.push_back(Args
.MakeArgString(Opt
));
525 static void AppendPlatformPrefix(SmallString
<128> &Path
, const llvm::Triple
&T
);
527 void darwin::Linker::ConstructJob(Compilation
&C
, const JobAction
&JA
,
528 const InputInfo
&Output
,
529 const InputInfoList
&Inputs
,
531 const char *LinkingOutput
) const {
532 assert(Output
.getType() == types::TY_Image
&& "Invalid linker output type.");
534 // If the number of arguments surpasses the system limits, we will encode the
535 // input files in a separate file, shortening the command line. To this end,
536 // build a list of input file names that can be passed via a file with the
537 // -filelist linker option.
538 llvm::opt::ArgStringList InputFileList
;
540 // The logic here is derived from gcc's behavior; most of which
541 // comes from specs (starting with link_command). Consult gcc for
543 ArgStringList CmdArgs
;
545 /// Hack(tm) to ignore linking errors when we are doing ARC migration.
546 if (Args
.hasArg(options::OPT_ccc_arcmt_check
,
547 options::OPT_ccc_arcmt_migrate
)) {
548 for (const auto &Arg
: Args
)
551 Args
.MakeArgString(getToolChain().GetProgramPath("touch"));
552 CmdArgs
.push_back(Output
.getFilename());
553 C
.addCommand(std::make_unique
<Command
>(
554 JA
, *this, ResponseFileSupport::None(), Exec
, CmdArgs
, None
, Output
));
558 VersionTuple Version
= getMachOToolChain().getLinkerVersion(Args
);
562 Args
.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD
));
564 // I'm not sure why this particular decomposition exists in gcc, but
565 // we follow suite for ease of comparison.
566 AddLinkArgs(C
, Args
, CmdArgs
, Inputs
, Version
, LinkerIsLLD
);
568 if (willEmitRemarks(Args
) &&
569 checkRemarksOptions(getToolChain().getDriver(), Args
,
570 getToolChain().getTriple()))
571 renderRemarksOptions(Args
, CmdArgs
, getToolChain().getTriple(), Output
, JA
);
573 // Propagate the -moutline flag to the linker in LTO.
575 Args
.getLastArg(options::OPT_moutline
, options::OPT_mno_outline
)) {
576 if (A
->getOption().matches(options::OPT_moutline
)) {
577 if (getMachOToolChain().getMachOArchName(Args
) == "arm64") {
578 CmdArgs
.push_back("-mllvm");
579 CmdArgs
.push_back("-enable-machine-outliner");
581 // Outline from linkonceodr functions by default in LTO.
582 CmdArgs
.push_back("-mllvm");
583 CmdArgs
.push_back("-enable-linkonceodr-outlining");
586 // Disable all outlining behaviour if we have mno-outline. We need to do
587 // this explicitly, because targets which support default outlining will
588 // try to do work if we don't.
589 CmdArgs
.push_back("-mllvm");
590 CmdArgs
.push_back("-enable-machine-outliner=never");
594 // Setup statistics file output.
595 SmallString
<128> StatsFile
=
596 getStatsFileName(Args
, Output
, Inputs
[0], getToolChain().getDriver());
597 if (!StatsFile
.empty()) {
598 CmdArgs
.push_back("-mllvm");
599 CmdArgs
.push_back(Args
.MakeArgString("-lto-stats-file=" + StatsFile
.str()));
602 // It seems that the 'e' option is completely ignored for dynamic executables
603 // (the default), and with static executables, the last one wins, as expected.
604 Args
.AddAllArgs(CmdArgs
, {options::OPT_d_Flag
, options::OPT_s
, options::OPT_t
,
605 options::OPT_Z_Flag
, options::OPT_u_Group
,
606 options::OPT_e
, options::OPT_r
});
608 // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
609 // members of static archive libraries which implement Objective-C classes or
611 if (Args
.hasArg(options::OPT_ObjC
) || Args
.hasArg(options::OPT_ObjCXX
))
612 CmdArgs
.push_back("-ObjC");
614 CmdArgs
.push_back("-o");
615 CmdArgs
.push_back(Output
.getFilename());
617 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nostartfiles
))
618 getMachOToolChain().addStartObjectFileArgs(Args
, CmdArgs
);
620 Args
.AddAllArgs(CmdArgs
, options::OPT_L
);
622 AddLinkerInputs(getToolChain(), Inputs
, Args
, CmdArgs
, JA
);
623 // Build the input file for -filelist (list of linker input files) in case we
625 for (const auto &II
: Inputs
) {
626 if (!II
.isFilename()) {
627 // This is a linker input argument.
628 // We cannot mix input arguments and file names in a -filelist input, thus
629 // we prematurely stop our list (remaining files shall be passed as
631 if (InputFileList
.size() > 0)
637 InputFileList
.push_back(II
.getFilename());
640 // Additional linker set-up and flags for Fortran. This is required in order
641 // to generate executables.
642 if (getToolChain().getDriver().IsFlangMode()) {
643 addFortranRuntimeLibraryPath(getToolChain(), Args
, CmdArgs
);
644 addFortranRuntimeLibs(getToolChain(), CmdArgs
);
647 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
))
648 addOpenMPRuntime(CmdArgs
, getToolChain(), Args
);
650 if (isObjCRuntimeLinked(Args
) &&
651 !Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
652 // We use arclite library for both ARC and subscripting support.
653 getMachOToolChain().AddLinkARCArgs(Args
, CmdArgs
);
655 CmdArgs
.push_back("-framework");
656 CmdArgs
.push_back("Foundation");
658 CmdArgs
.push_back("-lobjc");
662 CmdArgs
.push_back("-arch_multiple");
663 CmdArgs
.push_back("-final_output");
664 CmdArgs
.push_back(LinkingOutput
);
667 if (Args
.hasArg(options::OPT_fnested_functions
))
668 CmdArgs
.push_back("-allow_stack_execute");
670 getMachOToolChain().addProfileRTLibs(Args
, CmdArgs
);
672 StringRef Parallelism
= getLTOParallelism(Args
, getToolChain().getDriver());
673 if (!Parallelism
.empty()) {
674 CmdArgs
.push_back("-mllvm");
675 unsigned NumThreads
=
676 llvm::get_threadpool_strategy(Parallelism
)->compute_thread_count();
677 CmdArgs
.push_back(Args
.MakeArgString("-threads=" + Twine(NumThreads
)));
680 if (getToolChain().ShouldLinkCXXStdlib(Args
))
681 getToolChain().AddCXXStdlibLibArgs(Args
, CmdArgs
);
683 bool NoStdOrDefaultLibs
=
684 Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
);
685 bool ForceLinkBuiltins
= Args
.hasArg(options::OPT_fapple_link_rtlib
);
686 if (!NoStdOrDefaultLibs
|| ForceLinkBuiltins
) {
687 // link_ssp spec is empty.
689 // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then
690 // we just want to link the builtins, not the other libs like libSystem.
691 if (NoStdOrDefaultLibs
&& ForceLinkBuiltins
) {
692 getMachOToolChain().AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
694 // Let the tool chain choose which runtime library to link.
695 getMachOToolChain().AddLinkRuntimeLibArgs(Args
, CmdArgs
,
698 // No need to do anything for pthreads. Claim argument to avoid warning.
699 Args
.ClaimAllArgs(options::OPT_pthread
);
700 Args
.ClaimAllArgs(options::OPT_pthreads
);
704 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nostartfiles
)) {
705 // endfile_spec is empty.
708 Args
.AddAllArgs(CmdArgs
, options::OPT_T_Group
);
709 Args
.AddAllArgs(CmdArgs
, options::OPT_F
);
711 // -iframework should be forwarded as -F.
712 for (const Arg
*A
: Args
.filtered(options::OPT_iframework
))
713 CmdArgs
.push_back(Args
.MakeArgString(std::string("-F") + A
->getValue()));
715 if (!Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
716 if (Arg
*A
= Args
.getLastArg(options::OPT_fveclib
)) {
717 if (A
->getValue() == StringRef("Accelerate")) {
718 CmdArgs
.push_back("-framework");
719 CmdArgs
.push_back("Accelerate");
724 // Add non-standard, platform-specific search paths, e.g., for DriverKit:
725 // -L<sysroot>/System/DriverKit/usr/lib
726 // -F<sysroot>/System/DriverKit/System/Library/Framework
728 bool NonStandardSearchPath
= false;
729 const auto &Triple
= getToolChain().getTriple();
730 if (Triple
.isDriverKit()) {
731 // ld64 fixed the implicit -F and -L paths in ld64-605.1+.
732 NonStandardSearchPath
=
733 Version
.getMajor() < 605 ||
734 (Version
.getMajor() == 605 && Version
.getMinor().value_or(0) < 1);
737 if (NonStandardSearchPath
) {
738 if (auto *Sysroot
= Args
.getLastArg(options::OPT_isysroot
)) {
739 auto AddSearchPath
= [&](StringRef Flag
, StringRef SearchPath
) {
740 SmallString
<128> P(Sysroot
->getValue());
741 AppendPlatformPrefix(P
, Triple
);
742 llvm::sys::path::append(P
, SearchPath
);
743 if (getToolChain().getVFS().exists(P
)) {
744 CmdArgs
.push_back(Args
.MakeArgString(Flag
+ P
));
747 AddSearchPath("-L", "/usr/lib");
748 AddSearchPath("-F", "/System/Library/Frameworks");
753 ResponseFileSupport ResponseSupport
;
754 if (Version
>= VersionTuple(705) || LinkerIsLLD
) {
755 ResponseSupport
= ResponseFileSupport::AtFileUTF8();
757 // For older versions of the linker, use the legacy filelist method instead.
758 ResponseSupport
= {ResponseFileSupport::RF_FileList
, llvm::sys::WEM_UTF8
,
762 std::unique_ptr
<Command
> Cmd
= std::make_unique
<Command
>(
763 JA
, *this, ResponseSupport
, Exec
, CmdArgs
, Inputs
, Output
);
764 Cmd
->setInputFileList(std::move(InputFileList
));
765 C
.addCommand(std::move(Cmd
));
768 void darwin::StaticLibTool::ConstructJob(Compilation
&C
, const JobAction
&JA
,
769 const InputInfo
&Output
,
770 const InputInfoList
&Inputs
,
772 const char *LinkingOutput
) const {
773 const Driver
&D
= getToolChain().getDriver();
775 // Silence warning for "clang -g foo.o -o foo"
776 Args
.ClaimAllArgs(options::OPT_g_Group
);
777 // and "clang -emit-llvm foo.o -o foo"
778 Args
.ClaimAllArgs(options::OPT_emit_llvm
);
779 // and for "clang -w foo.o -o foo". Other warning options are already
780 // handled somewhere else.
781 Args
.ClaimAllArgs(options::OPT_w
);
782 // Silence warnings when linking C code with a C++ '-stdlib' argument.
783 Args
.ClaimAllArgs(options::OPT_stdlib_EQ
);
785 // libtool <options> <output_file> <input_files>
786 ArgStringList CmdArgs
;
787 // Create and insert file members with a deterministic index.
788 CmdArgs
.push_back("-static");
789 CmdArgs
.push_back("-D");
790 CmdArgs
.push_back("-no_warning_for_no_symbols");
791 CmdArgs
.push_back("-o");
792 CmdArgs
.push_back(Output
.getFilename());
794 for (const auto &II
: Inputs
) {
795 if (II
.isFilename()) {
796 CmdArgs
.push_back(II
.getFilename());
800 // Delete old output archive file if it already exists before generating a new
802 const auto *OutputFileName
= Output
.getFilename();
803 if (Output
.isFilename() && llvm::sys::fs::exists(OutputFileName
)) {
804 if (std::error_code EC
= llvm::sys::fs::remove(OutputFileName
)) {
805 D
.Diag(diag::err_drv_unable_to_remove_file
) << EC
.message();
810 const char *Exec
= Args
.MakeArgString(getToolChain().GetStaticLibToolPath());
811 C
.addCommand(std::make_unique
<Command
>(JA
, *this,
812 ResponseFileSupport::AtFileUTF8(),
813 Exec
, CmdArgs
, Inputs
, Output
));
816 void darwin::Lipo::ConstructJob(Compilation
&C
, const JobAction
&JA
,
817 const InputInfo
&Output
,
818 const InputInfoList
&Inputs
,
820 const char *LinkingOutput
) const {
821 ArgStringList CmdArgs
;
823 CmdArgs
.push_back("-create");
824 assert(Output
.isFilename() && "Unexpected lipo output.");
826 CmdArgs
.push_back("-output");
827 CmdArgs
.push_back(Output
.getFilename());
829 for (const auto &II
: Inputs
) {
830 assert(II
.isFilename() && "Unexpected lipo input.");
831 CmdArgs
.push_back(II
.getFilename());
834 const char *Exec
= Args
.MakeArgString(getToolChain().GetProgramPath("lipo"));
835 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
836 Exec
, CmdArgs
, Inputs
, Output
));
839 void darwin::Dsymutil::ConstructJob(Compilation
&C
, const JobAction
&JA
,
840 const InputInfo
&Output
,
841 const InputInfoList
&Inputs
,
843 const char *LinkingOutput
) const {
844 ArgStringList CmdArgs
;
846 CmdArgs
.push_back("-o");
847 CmdArgs
.push_back(Output
.getFilename());
849 assert(Inputs
.size() == 1 && "Unable to handle multiple inputs.");
850 const InputInfo
&Input
= Inputs
[0];
851 assert(Input
.isFilename() && "Unexpected dsymutil input.");
852 CmdArgs
.push_back(Input
.getFilename());
855 Args
.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
856 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
857 Exec
, CmdArgs
, Inputs
, Output
));
860 void darwin::VerifyDebug::ConstructJob(Compilation
&C
, const JobAction
&JA
,
861 const InputInfo
&Output
,
862 const InputInfoList
&Inputs
,
864 const char *LinkingOutput
) const {
865 ArgStringList CmdArgs
;
866 CmdArgs
.push_back("--verify");
867 CmdArgs
.push_back("--debug-info");
868 CmdArgs
.push_back("--eh-frame");
869 CmdArgs
.push_back("--quiet");
871 assert(Inputs
.size() == 1 && "Unable to handle multiple inputs.");
872 const InputInfo
&Input
= Inputs
[0];
873 assert(Input
.isFilename() && "Unexpected verify input");
875 // Grabbing the output of the earlier dsymutil run.
876 CmdArgs
.push_back(Input
.getFilename());
879 Args
.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
880 C
.addCommand(std::make_unique
<Command
>(JA
, *this, ResponseFileSupport::None(),
881 Exec
, CmdArgs
, Inputs
, Output
));
884 MachO::MachO(const Driver
&D
, const llvm::Triple
&Triple
, const ArgList
&Args
)
885 : ToolChain(D
, Triple
, Args
) {
886 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
887 getProgramPaths().push_back(getDriver().getInstalledDir());
888 if (getDriver().getInstalledDir() != getDriver().Dir
)
889 getProgramPaths().push_back(getDriver().Dir
);
892 /// Darwin - Darwin tool chain for i386 and x86_64.
893 Darwin::Darwin(const Driver
&D
, const llvm::Triple
&Triple
, const ArgList
&Args
)
894 : MachO(D
, Triple
, Args
), TargetInitialized(false),
895 CudaInstallation(D
, Triple
, Args
), RocmInstallation(D
, Triple
, Args
) {}
897 types::ID
MachO::LookupTypeForExtension(StringRef Ext
) const {
898 types::ID Ty
= ToolChain::LookupTypeForExtension(Ext
);
900 // Darwin always preprocesses assembly files (unless -x is used explicitly).
901 if (Ty
== types::TY_PP_Asm
)
902 return types::TY_Asm
;
907 bool MachO::HasNativeLLVMSupport() const { return true; }
909 ToolChain::CXXStdlibType
Darwin::GetDefaultCXXStdlibType() const {
910 // Always use libc++ by default
911 return ToolChain::CST_Libcxx
;
914 /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
915 ObjCRuntime
Darwin::getDefaultObjCRuntime(bool isNonFragile
) const {
916 if (isTargetWatchOSBased())
917 return ObjCRuntime(ObjCRuntime::WatchOS
, TargetVersion
);
918 if (isTargetIOSBased())
919 return ObjCRuntime(ObjCRuntime::iOS
, TargetVersion
);
921 return ObjCRuntime(ObjCRuntime::MacOSX
, TargetVersion
);
922 return ObjCRuntime(ObjCRuntime::FragileMacOSX
, TargetVersion
);
925 /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
926 bool Darwin::hasBlocksRuntime() const {
927 if (isTargetWatchOSBased() || isTargetDriverKit())
929 else if (isTargetIOSBased())
930 return !isIPhoneOSVersionLT(3, 2);
932 assert(isTargetMacOSBased() && "unexpected darwin target");
933 return !isMacosxVersionLT(10, 6);
937 void Darwin::AddCudaIncludeArgs(const ArgList
&DriverArgs
,
938 ArgStringList
&CC1Args
) const {
939 CudaInstallation
.AddCudaIncludeArgs(DriverArgs
, CC1Args
);
942 void Darwin::AddHIPIncludeArgs(const ArgList
&DriverArgs
,
943 ArgStringList
&CC1Args
) const {
944 RocmInstallation
.AddHIPIncludeArgs(DriverArgs
, CC1Args
);
947 // This is just a MachO name translation routine and there's no
948 // way to join this into ARMTargetParser without breaking all
949 // other assumptions. Maybe MachO should consider standardising
950 // their nomenclature.
951 static const char *ArmMachOArchName(StringRef Arch
) {
952 return llvm::StringSwitch
<const char *>(Arch
)
953 .Case("armv6k", "armv6")
954 .Case("armv6m", "armv6m")
955 .Case("armv5tej", "armv5")
956 .Case("xscale", "xscale")
957 .Case("armv4t", "armv4t")
958 .Case("armv7", "armv7")
959 .Cases("armv7a", "armv7-a", "armv7")
960 .Cases("armv7r", "armv7-r", "armv7")
961 .Cases("armv7em", "armv7e-m", "armv7em")
962 .Cases("armv7k", "armv7-k", "armv7k")
963 .Cases("armv7m", "armv7-m", "armv7m")
964 .Cases("armv7s", "armv7-s", "armv7s")
968 static const char *ArmMachOArchNameCPU(StringRef CPU
) {
969 llvm::ARM::ArchKind ArchKind
= llvm::ARM::parseCPUArch(CPU
);
970 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
972 StringRef Arch
= llvm::ARM::getArchName(ArchKind
);
974 // FIXME: Make sure this MachO triple mangling is really necessary.
975 // ARMv5* normalises to ARMv5.
976 if (Arch
.startswith("armv5"))
977 Arch
= Arch
.substr(0, 5);
978 // ARMv6*, except ARMv6M, normalises to ARMv6.
979 else if (Arch
.startswith("armv6") && !Arch
.endswith("6m"))
980 Arch
= Arch
.substr(0, 5);
981 // ARMv7A normalises to ARMv7.
982 else if (Arch
.endswith("v7a"))
983 Arch
= Arch
.substr(0, 5);
987 StringRef
MachO::getMachOArchName(const ArgList
&Args
) const {
988 switch (getTriple().getArch()) {
990 return getDefaultUniversalArchName();
992 case llvm::Triple::aarch64_32
:
995 case llvm::Triple::aarch64
: {
996 if (getTriple().isArm64e())
1001 case llvm::Triple::thumb
:
1002 case llvm::Triple::arm
:
1003 if (const Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_march_EQ
))
1004 if (const char *Arch
= ArmMachOArchName(A
->getValue()))
1007 if (const Arg
*A
= Args
.getLastArg(options::OPT_mcpu_EQ
))
1008 if (const char *Arch
= ArmMachOArchNameCPU(A
->getValue()))
1015 VersionTuple
MachO::getLinkerVersion(const llvm::opt::ArgList
&Args
) const {
1016 if (LinkerVersion
) {
1018 VersionTuple NewLinkerVersion
;
1019 if (Arg
*A
= Args
.getLastArg(options::OPT_mlinker_version_EQ
))
1020 (void)NewLinkerVersion
.tryParse(A
->getValue());
1021 assert(NewLinkerVersion
== LinkerVersion
);
1023 return *LinkerVersion
;
1026 VersionTuple NewLinkerVersion
;
1027 if (Arg
*A
= Args
.getLastArg(options::OPT_mlinker_version_EQ
))
1028 if (NewLinkerVersion
.tryParse(A
->getValue()))
1029 getDriver().Diag(diag::err_drv_invalid_version_number
)
1030 << A
->getAsString(Args
);
1032 LinkerVersion
= NewLinkerVersion
;
1033 return *LinkerVersion
;
1036 Darwin::~Darwin() {}
1040 std::string
Darwin::ComputeEffectiveClangTriple(const ArgList
&Args
,
1041 types::ID InputType
) const {
1042 llvm::Triple
Triple(ComputeLLVMTriple(Args
, InputType
));
1044 // If the target isn't initialized (e.g., an unknown Darwin platform, return
1045 // the default triple).
1046 if (!isTargetInitialized())
1047 return Triple
.getTriple();
1049 SmallString
<16> Str
;
1050 if (isTargetWatchOSBased())
1052 else if (isTargetTvOSBased())
1054 else if (isTargetDriverKit())
1056 else if (isTargetIOSBased() || isTargetMacCatalyst())
1060 Str
+= getTripleTargetVersion().getAsString();
1061 Triple
.setOSName(Str
);
1063 return Triple
.getTriple();
1066 Tool
*MachO::getTool(Action::ActionClass AC
) const {
1068 case Action::LipoJobClass
:
1070 Lipo
.reset(new tools::darwin::Lipo(*this));
1072 case Action::DsymutilJobClass
:
1074 Dsymutil
.reset(new tools::darwin::Dsymutil(*this));
1075 return Dsymutil
.get();
1076 case Action::VerifyDebugInfoJobClass
:
1078 VerifyDebug
.reset(new tools::darwin::VerifyDebug(*this));
1079 return VerifyDebug
.get();
1081 return ToolChain::getTool(AC
);
1085 Tool
*MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
1087 Tool
*MachO::buildStaticLibTool() const {
1088 return new tools::darwin::StaticLibTool(*this);
1091 Tool
*MachO::buildAssembler() const {
1092 return new tools::darwin::Assembler(*this);
1095 DarwinClang::DarwinClang(const Driver
&D
, const llvm::Triple
&Triple
,
1096 const ArgList
&Args
)
1097 : Darwin(D
, Triple
, Args
) {}
1099 void DarwinClang::addClangWarningOptions(ArgStringList
&CC1Args
) const {
1100 // Always error about undefined 'TARGET_OS_*' macros.
1101 CC1Args
.push_back("-Wundef-prefix=TARGET_OS_");
1102 CC1Args
.push_back("-Werror=undef-prefix");
1104 // For modern targets, promote certain warnings to errors.
1105 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
1106 // Always enable -Wdeprecated-objc-isa-usage and promote it
1108 CC1Args
.push_back("-Wdeprecated-objc-isa-usage");
1109 CC1Args
.push_back("-Werror=deprecated-objc-isa-usage");
1111 // For iOS and watchOS, also error about implicit function declarations,
1112 // as that can impact calling conventions.
1113 if (!isTargetMacOS())
1114 CC1Args
.push_back("-Werror=implicit-function-declaration");
1118 /// Take a path that speculatively points into Xcode and return the
1119 /// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path
1121 static StringRef
getXcodeDeveloperPath(StringRef PathIntoXcode
) {
1122 static constexpr llvm::StringLiteral
XcodeAppSuffix(
1123 ".app/Contents/Developer");
1124 size_t Index
= PathIntoXcode
.find(XcodeAppSuffix
);
1125 if (Index
== StringRef::npos
)
1127 return PathIntoXcode
.take_front(Index
+ XcodeAppSuffix
.size());
1130 void DarwinClang::AddLinkARCArgs(const ArgList
&Args
,
1131 ArgStringList
&CmdArgs
) const {
1132 // Avoid linking compatibility stubs on i386 mac.
1133 if (isTargetMacOSBased() && getArch() == llvm::Triple::x86
)
1135 if (isTargetAppleSiliconMac())
1137 // ARC runtime is supported everywhere on arm64e.
1138 if (getTriple().isArm64e())
1141 ObjCRuntime runtime
= getDefaultObjCRuntime(/*nonfragile*/ true);
1143 if ((runtime
.hasNativeARC() || !isObjCAutoRefCount(Args
)) &&
1144 runtime
.hasSubscripting())
1147 SmallString
<128> P(getDriver().ClangExecutable
);
1148 llvm::sys::path::remove_filename(P
); // 'clang'
1149 llvm::sys::path::remove_filename(P
); // 'bin'
1150 llvm::sys::path::append(P
, "lib", "arc");
1152 // 'libarclite' usually lives in the same toolchain as 'clang'. However, the
1153 // Swift open source toolchains for macOS distribute Clang without libarclite.
1154 // In that case, to allow the linker to find 'libarclite', we point to the
1155 // 'libarclite' in the XcodeDefault toolchain instead.
1156 if (!getVFS().exists(P
)) {
1157 auto updatePath
= [&](const Arg
*A
) {
1158 // Try to infer the path to 'libarclite' in the toolchain from the
1159 // specified SDK path.
1160 StringRef XcodePathForSDK
= getXcodeDeveloperPath(A
->getValue());
1161 if (XcodePathForSDK
.empty())
1164 P
= XcodePathForSDK
;
1165 llvm::sys::path::append(P
, "Toolchains/XcodeDefault.xctoolchain/usr",
1167 return getVFS().exists(P
);
1170 bool updated
= false;
1171 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
))
1172 updated
= updatePath(A
);
1175 if (const Arg
*A
= Args
.getLastArg(options::OPT__sysroot_EQ
))
1180 CmdArgs
.push_back("-force_load");
1181 llvm::sys::path::append(P
, "libarclite_");
1182 // Mash in the platform.
1183 if (isTargetWatchOSSimulator())
1184 P
+= "watchsimulator";
1185 else if (isTargetWatchOS())
1187 else if (isTargetTvOSSimulator())
1188 P
+= "appletvsimulator";
1189 else if (isTargetTvOS())
1191 else if (isTargetIOSSimulator())
1192 P
+= "iphonesimulator";
1193 else if (isTargetIPhoneOS())
1199 CmdArgs
.push_back(Args
.MakeArgString(P
));
1202 unsigned DarwinClang::GetDefaultDwarfVersion() const {
1203 // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
1204 if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) ||
1205 (isTargetIOSBased() && isIPhoneOSVersionLT(9)))
1210 void MachO::AddLinkRuntimeLib(const ArgList
&Args
, ArgStringList
&CmdArgs
,
1211 StringRef Component
, RuntimeLinkOptions Opts
,
1212 bool IsShared
) const {
1213 SmallString
<64> DarwinLibName
= StringRef("libclang_rt.");
1214 // an Darwin the builtins compomnent is not in the library name
1215 if (Component
!= "builtins") {
1216 DarwinLibName
+= Component
;
1217 if (!(Opts
& RLO_IsEmbedded
))
1218 DarwinLibName
+= "_";
1221 DarwinLibName
+= getOSLibraryNameSuffix();
1222 DarwinLibName
+= IsShared
? "_dynamic.dylib" : ".a";
1223 SmallString
<128> Dir(getDriver().ResourceDir
);
1224 llvm::sys::path::append(Dir
, "lib", "darwin");
1225 if (Opts
& RLO_IsEmbedded
)
1226 llvm::sys::path::append(Dir
, "macho_embedded");
1228 SmallString
<128> P(Dir
);
1229 llvm::sys::path::append(P
, DarwinLibName
);
1231 // For now, allow missing resource libraries to support developers who may
1232 // not have compiler-rt checked out or integrated into their build (unless
1233 // we explicitly force linking with this library).
1234 if ((Opts
& RLO_AlwaysLink
) || getVFS().exists(P
)) {
1235 const char *LibArg
= Args
.MakeArgString(P
);
1236 CmdArgs
.push_back(LibArg
);
1239 // Adding the rpaths might negatively interact when other rpaths are involved,
1240 // so we should make sure we add the rpaths last, after all user-specified
1241 // rpaths. This is currently true from this place, but we need to be
1242 // careful if this function is ever called before user's rpaths are emitted.
1243 if (Opts
& RLO_AddRPath
) {
1244 assert(DarwinLibName
.endswith(".dylib") && "must be a dynamic library");
1246 // Add @executable_path to rpath to support having the dylib copied with
1248 CmdArgs
.push_back("-rpath");
1249 CmdArgs
.push_back("@executable_path");
1251 // Add the path to the resource dir to rpath to support using the dylib
1252 // from the default location without copying.
1253 CmdArgs
.push_back("-rpath");
1254 CmdArgs
.push_back(Args
.MakeArgString(Dir
));
1258 StringRef
Darwin::getPlatformFamily() const {
1259 switch (TargetPlatform
) {
1260 case DarwinPlatformKind::MacOS
:
1262 case DarwinPlatformKind::IPhoneOS
:
1263 if (TargetEnvironment
== MacCatalyst
)
1266 case DarwinPlatformKind::TvOS
:
1268 case DarwinPlatformKind::WatchOS
:
1270 case DarwinPlatformKind::DriverKit
:
1273 llvm_unreachable("Unsupported platform");
1276 StringRef
Darwin::getSDKName(StringRef isysroot
) {
1277 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
1278 auto BeginSDK
= llvm::sys::path::rbegin(isysroot
);
1279 auto EndSDK
= llvm::sys::path::rend(isysroot
);
1280 for (auto IT
= BeginSDK
; IT
!= EndSDK
; ++IT
) {
1281 StringRef SDK
= *IT
;
1282 if (SDK
.endswith(".sdk"))
1283 return SDK
.slice(0, SDK
.size() - 4);
1288 StringRef
Darwin::getOSLibraryNameSuffix(bool IgnoreSim
) const {
1289 switch (TargetPlatform
) {
1290 case DarwinPlatformKind::MacOS
:
1292 case DarwinPlatformKind::IPhoneOS
:
1293 if (TargetEnvironment
== MacCatalyst
)
1295 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "ios"
1297 case DarwinPlatformKind::TvOS
:
1298 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "tvos"
1300 case DarwinPlatformKind::WatchOS
:
1301 return TargetEnvironment
== NativeEnvironment
|| IgnoreSim
? "watchos"
1303 case DarwinPlatformKind::DriverKit
:
1306 llvm_unreachable("Unsupported platform");
1309 /// Check if the link command contains a symbol export directive.
1310 static bool hasExportSymbolDirective(const ArgList
&Args
) {
1311 for (Arg
*A
: Args
) {
1312 if (A
->getOption().matches(options::OPT_exported__symbols__list
))
1314 if (!A
->getOption().matches(options::OPT_Wl_COMMA
) &&
1315 !A
->getOption().matches(options::OPT_Xlinker
))
1317 if (A
->containsValue("-exported_symbols_list") ||
1318 A
->containsValue("-exported_symbol"))
1324 /// Add an export directive for \p Symbol to the link command.
1325 static void addExportedSymbol(ArgStringList
&CmdArgs
, const char *Symbol
) {
1326 CmdArgs
.push_back("-exported_symbol");
1327 CmdArgs
.push_back(Symbol
);
1330 /// Add a sectalign directive for \p Segment and \p Section to the maximum
1331 /// expected page size for Darwin.
1333 /// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K.
1334 /// Use a common alignment constant (16K) for now, and reduce the alignment on
1335 /// macOS if it proves important.
1336 static void addSectalignToPage(const ArgList
&Args
, ArgStringList
&CmdArgs
,
1337 StringRef Segment
, StringRef Section
) {
1338 for (const char *A
: {"-sectalign", Args
.MakeArgString(Segment
),
1339 Args
.MakeArgString(Section
), "0x4000"})
1340 CmdArgs
.push_back(A
);
1343 void Darwin::addProfileRTLibs(const ArgList
&Args
,
1344 ArgStringList
&CmdArgs
) const {
1345 if (!needsProfileRT(Args
) && !needsGCovInstrumentation(Args
))
1348 AddLinkRuntimeLib(Args
, CmdArgs
, "profile",
1349 RuntimeLinkOptions(RLO_AlwaysLink
));
1351 bool ForGCOV
= needsGCovInstrumentation(Args
);
1353 // If we have a symbol export directive and we're linking in the profile
1354 // runtime, automatically export symbols necessary to implement some of the
1355 // runtime's functionality.
1356 if (hasExportSymbolDirective(Args
)) {
1358 addExportedSymbol(CmdArgs
, "___gcov_dump");
1359 addExportedSymbol(CmdArgs
, "___gcov_reset");
1360 addExportedSymbol(CmdArgs
, "_writeout_fn_list");
1361 addExportedSymbol(CmdArgs
, "_reset_fn_list");
1363 addExportedSymbol(CmdArgs
, "___llvm_profile_filename");
1364 addExportedSymbol(CmdArgs
, "___llvm_profile_raw_version");
1368 // Align __llvm_prf_{cnts,data} sections to the maximum expected page
1369 // alignment. This allows profile counters to be mmap()'d to disk. Note that
1370 // it's not enough to just page-align __llvm_prf_cnts: the following section
1371 // must also be page-aligned so that its data is not clobbered by mmap().
1373 // The section alignment is only needed when continuous profile sync is
1374 // enabled, but this is expected to be the default in Xcode. Specifying the
1375 // extra alignment also allows the same binary to be used with/without sync
1378 for (auto IPSK
: {llvm::IPSK_cnts
, llvm::IPSK_data
}) {
1380 Args
, CmdArgs
, "__DATA",
1381 llvm::getInstrProfSectionName(IPSK
, llvm::Triple::MachO
,
1382 /*AddSegmentInfo=*/false));
1387 void DarwinClang::AddLinkSanitizerLibArgs(const ArgList
&Args
,
1388 ArgStringList
&CmdArgs
,
1389 StringRef Sanitizer
,
1390 bool Shared
) const {
1391 auto RLO
= RuntimeLinkOptions(RLO_AlwaysLink
| (Shared
? RLO_AddRPath
: 0U));
1392 AddLinkRuntimeLib(Args
, CmdArgs
, Sanitizer
, RLO
, Shared
);
1395 ToolChain::RuntimeLibType
DarwinClang::GetRuntimeLibType(
1396 const ArgList
&Args
) const {
1397 if (Arg
* A
= Args
.getLastArg(options::OPT_rtlib_EQ
)) {
1398 StringRef Value
= A
->getValue();
1399 if (Value
!= "compiler-rt" && Value
!= "platform")
1400 getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform
)
1401 << Value
<< "darwin";
1404 return ToolChain::RLT_CompilerRT
;
1407 void DarwinClang::AddLinkRuntimeLibArgs(const ArgList
&Args
,
1408 ArgStringList
&CmdArgs
,
1409 bool ForceLinkBuiltinRT
) const {
1410 // Call once to ensure diagnostic is printed if wrong value was specified
1411 GetRuntimeLibType(Args
);
1413 // Darwin doesn't support real static executables, don't link any runtime
1414 // libraries with -static.
1415 if (Args
.hasArg(options::OPT_static
) ||
1416 Args
.hasArg(options::OPT_fapple_kext
) ||
1417 Args
.hasArg(options::OPT_mkernel
)) {
1418 if (ForceLinkBuiltinRT
)
1419 AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
1423 // Reject -static-libgcc for now, we can deal with this when and if someone
1424 // cares. This is useful in situations where someone wants to statically link
1425 // something like libstdc++, and needs its runtime support routines.
1426 if (const Arg
*A
= Args
.getLastArg(options::OPT_static_libgcc
)) {
1427 getDriver().Diag(diag::err_drv_unsupported_opt
) << A
->getAsString(Args
);
1431 const SanitizerArgs
&Sanitize
= getSanitizerArgs(Args
);
1432 if (Sanitize
.needsAsanRt())
1433 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "asan");
1434 if (Sanitize
.needsLsanRt())
1435 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "lsan");
1436 if (Sanitize
.needsUbsanRt())
1437 AddLinkSanitizerLibArgs(Args
, CmdArgs
,
1438 Sanitize
.requiresMinimalRuntime() ? "ubsan_minimal"
1440 Sanitize
.needsSharedRt());
1441 if (Sanitize
.needsTsanRt())
1442 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "tsan");
1443 if (Sanitize
.needsFuzzer() && !Args
.hasArg(options::OPT_dynamiclib
)) {
1444 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "fuzzer", /*shared=*/false);
1446 // Libfuzzer is written in C++ and requires libcxx.
1447 AddCXXStdlibLibArgs(Args
, CmdArgs
);
1449 if (Sanitize
.needsStatsRt()) {
1450 AddLinkRuntimeLib(Args
, CmdArgs
, "stats_client", RLO_AlwaysLink
);
1451 AddLinkSanitizerLibArgs(Args
, CmdArgs
, "stats");
1454 const XRayArgs
&XRay
= getXRayArgs();
1455 if (XRay
.needsXRayRt()) {
1456 AddLinkRuntimeLib(Args
, CmdArgs
, "xray");
1457 AddLinkRuntimeLib(Args
, CmdArgs
, "xray-basic");
1458 AddLinkRuntimeLib(Args
, CmdArgs
, "xray-fdr");
1461 if (isTargetDriverKit() && !Args
.hasArg(options::OPT_nodriverkitlib
)) {
1462 CmdArgs
.push_back("-framework");
1463 CmdArgs
.push_back("DriverKit");
1466 // Otherwise link libSystem, then the dynamic runtime library, and finally any
1467 // target specific static runtime library.
1468 if (!isTargetDriverKit())
1469 CmdArgs
.push_back("-lSystem");
1471 // Select the dynamic runtime library and the target specific static library.
1472 if (isTargetIOSBased()) {
1473 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
1474 // it never went into the SDK.
1475 // Linking against libgcc_s.1 isn't needed for iOS 5.0+
1476 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
1477 getTriple().getArch() != llvm::Triple::aarch64
)
1478 CmdArgs
.push_back("-lgcc_s.1");
1480 AddLinkRuntimeLib(Args
, CmdArgs
, "builtins");
1483 /// Returns the most appropriate macOS target version for the current process.
1485 /// If the macOS SDK version is the same or earlier than the system version,
1486 /// then the SDK version is returned. Otherwise the system version is returned.
1487 static std::string
getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion
) {
1488 unsigned Major
, Minor
, Micro
;
1489 llvm::Triple
SystemTriple(llvm::sys::getProcessTriple());
1490 if (!SystemTriple
.isMacOSX())
1491 return std::string(MacOSSDKVersion
);
1492 VersionTuple SystemVersion
;
1493 SystemTriple
.getMacOSXVersion(SystemVersion
);
1495 if (!Driver::GetReleaseVersion(MacOSSDKVersion
, Major
, Minor
, Micro
,
1497 return std::string(MacOSSDKVersion
);
1498 VersionTuple
SDKVersion(Major
, Minor
, Micro
);
1499 if (SDKVersion
> SystemVersion
)
1500 return SystemVersion
.getAsString();
1501 return std::string(MacOSSDKVersion
);
1506 /// The Darwin OS that was selected or inferred from arguments / environment.
1507 struct DarwinPlatform
{
1509 /// The OS was specified using the -target argument.
1511 /// The OS was specified using the -mtargetos= argument.
1513 /// The OS was specified using the -m<os>-version-min argument.
1515 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
1516 DeploymentTargetEnv
,
1517 /// The OS was inferred from the SDK.
1519 /// The OS was inferred from the -arch.
1523 using DarwinPlatformKind
= Darwin::DarwinPlatformKind
;
1524 using DarwinEnvironmentKind
= Darwin::DarwinEnvironmentKind
;
1526 DarwinPlatformKind
getPlatform() const { return Platform
; }
1528 DarwinEnvironmentKind
getEnvironment() const { return Environment
; }
1530 void setEnvironment(DarwinEnvironmentKind Kind
) {
1532 InferSimulatorFromArch
= false;
1535 StringRef
getOSVersion() const {
1536 if (Kind
== OSVersionArg
)
1537 return Argument
->getValue();
1541 void setOSVersion(StringRef S
) {
1542 assert(Kind
== TargetArg
&& "Unexpected kind!");
1543 OSVersion
= std::string(S
);
1546 bool hasOSVersion() const { return HasOSVersion
; }
1548 VersionTuple
getNativeTargetVersion() const {
1549 assert(Environment
== DarwinEnvironmentKind::MacCatalyst
&&
1550 "native target version is specified only for Mac Catalyst");
1551 return NativeTargetVersion
;
1554 /// Returns true if the target OS was explicitly specified.
1555 bool isExplicitlySpecified() const { return Kind
<= DeploymentTargetEnv
; }
1557 /// Returns true if the simulator environment can be inferred from the arch.
1558 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch
; }
1560 const Optional
<llvm::Triple
> &getTargetVariantTriple() const {
1561 return TargetVariantTriple
;
1564 /// Adds the -m<os>-version-min argument to the compiler invocation.
1565 void addOSVersionMinArgument(DerivedArgList
&Args
, const OptTable
&Opts
) {
1568 assert(Kind
!= TargetArg
&& Kind
!= MTargetOSArg
&& Kind
!= OSVersionArg
&&
1572 case DarwinPlatformKind::MacOS
:
1573 Opt
= options::OPT_mmacos_version_min_EQ
;
1575 case DarwinPlatformKind::IPhoneOS
:
1576 Opt
= options::OPT_mios_version_min_EQ
;
1578 case DarwinPlatformKind::TvOS
:
1579 Opt
= options::OPT_mtvos_version_min_EQ
;
1581 case DarwinPlatformKind::WatchOS
:
1582 Opt
= options::OPT_mwatchos_version_min_EQ
;
1584 case DarwinPlatformKind::DriverKit
:
1585 // DriverKit always explicitly provides a version in the triple.
1588 Argument
= Args
.MakeJoinedArg(nullptr, Opts
.getOption(Opt
), OSVersion
);
1589 Args
.append(Argument
);
1592 /// Returns the OS version with the argument / environment variable that
1594 std::string
getAsString(DerivedArgList
&Args
, const OptTable
&Opts
) {
1599 case InferredFromSDK
:
1600 case InferredFromArch
:
1601 assert(Argument
&& "OS version argument not yet inferred");
1602 return Argument
->getAsString(Args
);
1603 case DeploymentTargetEnv
:
1604 return (llvm::Twine(EnvVarName
) + "=" + OSVersion
).str();
1606 llvm_unreachable("Unsupported Darwin Source Kind");
1609 void setEnvironment(llvm::Triple::EnvironmentType EnvType
,
1610 const VersionTuple
&OSVersion
,
1611 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
1613 case llvm::Triple::Simulator
:
1614 Environment
= DarwinEnvironmentKind::Simulator
;
1616 case llvm::Triple::MacABI
: {
1617 Environment
= DarwinEnvironmentKind::MacCatalyst
;
1618 // The minimum native macOS target for MacCatalyst is macOS 10.15.
1619 NativeTargetVersion
= VersionTuple(10, 15);
1620 if (HasOSVersion
&& SDKInfo
) {
1621 if (const auto *MacCatalystToMacOSMapping
= SDKInfo
->getVersionMapping(
1622 DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
1623 if (auto MacOSVersion
= MacCatalystToMacOSMapping
->map(
1624 OSVersion
, NativeTargetVersion
, None
)) {
1625 NativeTargetVersion
= *MacOSVersion
;
1629 // In a zippered build, we could be building for a macOS target that's
1630 // lower than the version that's implied by the OS version. In that case
1631 // we need to use the minimum version as the native target version.
1632 if (TargetVariantTriple
) {
1633 auto TargetVariantVersion
= TargetVariantTriple
->getOSVersion();
1634 if (TargetVariantVersion
.getMajor()) {
1635 if (TargetVariantVersion
< NativeTargetVersion
)
1636 NativeTargetVersion
= TargetVariantVersion
;
1646 static DarwinPlatform
1647 createFromTarget(const llvm::Triple
&TT
, StringRef OSVersion
, Arg
*A
,
1648 Optional
<llvm::Triple
> TargetVariantTriple
,
1649 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
1650 DarwinPlatform
Result(TargetArg
, getPlatformFromOS(TT
.getOS()), OSVersion
,
1652 VersionTuple OsVersion
= TT
.getOSVersion();
1653 if (OsVersion
.getMajor() == 0)
1654 Result
.HasOSVersion
= false;
1655 Result
.TargetVariantTriple
= TargetVariantTriple
;
1656 Result
.setEnvironment(TT
.getEnvironment(), OsVersion
, SDKInfo
);
1659 static DarwinPlatform
1660 createFromMTargetOS(llvm::Triple::OSType OS
, VersionTuple OSVersion
,
1661 llvm::Triple::EnvironmentType Environment
, Arg
*A
,
1662 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
1663 DarwinPlatform
Result(MTargetOSArg
, getPlatformFromOS(OS
),
1664 OSVersion
.getAsString(), A
);
1665 Result
.InferSimulatorFromArch
= false;
1666 Result
.setEnvironment(Environment
, OSVersion
, SDKInfo
);
1669 static DarwinPlatform
createOSVersionArg(DarwinPlatformKind Platform
, Arg
*A
,
1671 DarwinPlatform Result
{OSVersionArg
, Platform
, A
};
1673 Result
.Environment
= DarwinEnvironmentKind::Simulator
;
1676 static DarwinPlatform
createDeploymentTargetEnv(DarwinPlatformKind Platform
,
1677 StringRef EnvVarName
,
1679 DarwinPlatform
Result(DeploymentTargetEnv
, Platform
, Value
);
1680 Result
.EnvVarName
= EnvVarName
;
1683 static DarwinPlatform
createFromSDK(DarwinPlatformKind Platform
,
1685 bool IsSimulator
= false) {
1686 DarwinPlatform
Result(InferredFromSDK
, Platform
, Value
);
1688 Result
.Environment
= DarwinEnvironmentKind::Simulator
;
1689 Result
.InferSimulatorFromArch
= false;
1692 static DarwinPlatform
createFromArch(llvm::Triple::OSType OS
,
1694 return DarwinPlatform(InferredFromArch
, getPlatformFromOS(OS
), Value
);
1697 /// Constructs an inferred SDKInfo value based on the version inferred from
1698 /// the SDK path itself. Only works for values that were created by inferring
1699 /// the platform from the SDKPath.
1700 DarwinSDKInfo
inferSDKInfo() {
1701 assert(Kind
== InferredFromSDK
&& "can infer SDK info only");
1702 llvm::VersionTuple Version
;
1703 bool IsValid
= !Version
.tryParse(OSVersion
);
1705 assert(IsValid
&& "invalid SDK version");
1706 return DarwinSDKInfo(
1708 /*MaximumDeploymentTarget=*/VersionTuple(Version
.getMajor(), 0, 99));
1712 DarwinPlatform(SourceKind Kind
, DarwinPlatformKind Platform
, Arg
*Argument
)
1713 : Kind(Kind
), Platform(Platform
), Argument(Argument
) {}
1714 DarwinPlatform(SourceKind Kind
, DarwinPlatformKind Platform
, StringRef Value
,
1715 Arg
*Argument
= nullptr)
1716 : Kind(Kind
), Platform(Platform
), OSVersion(Value
), Argument(Argument
) {}
1718 static DarwinPlatformKind
getPlatformFromOS(llvm::Triple::OSType OS
) {
1720 case llvm::Triple::Darwin
:
1721 case llvm::Triple::MacOSX
:
1722 return DarwinPlatformKind::MacOS
;
1723 case llvm::Triple::IOS
:
1724 return DarwinPlatformKind::IPhoneOS
;
1725 case llvm::Triple::TvOS
:
1726 return DarwinPlatformKind::TvOS
;
1727 case llvm::Triple::WatchOS
:
1728 return DarwinPlatformKind::WatchOS
;
1729 case llvm::Triple::DriverKit
:
1730 return DarwinPlatformKind::DriverKit
;
1732 llvm_unreachable("Unable to infer Darwin variant");
1737 DarwinPlatformKind Platform
;
1738 DarwinEnvironmentKind Environment
= DarwinEnvironmentKind::NativeEnvironment
;
1739 VersionTuple NativeTargetVersion
;
1740 std::string OSVersion
;
1741 bool HasOSVersion
= true, InferSimulatorFromArch
= true;
1743 StringRef EnvVarName
;
1744 Optional
<llvm::Triple
> TargetVariantTriple
;
1747 /// Returns the deployment target that's specified using the -m<os>-version-min
1749 Optional
<DarwinPlatform
>
1750 getDeploymentTargetFromOSVersionArg(DerivedArgList
&Args
,
1751 const Driver
&TheDriver
) {
1752 Arg
*macOSVersion
= Args
.getLastArg(options::OPT_mmacos_version_min_EQ
);
1753 Arg
*iOSVersion
= Args
.getLastArg(options::OPT_mios_version_min_EQ
,
1754 options::OPT_mios_simulator_version_min_EQ
);
1756 Args
.getLastArg(options::OPT_mtvos_version_min_EQ
,
1757 options::OPT_mtvos_simulator_version_min_EQ
);
1758 Arg
*WatchOSVersion
=
1759 Args
.getLastArg(options::OPT_mwatchos_version_min_EQ
,
1760 options::OPT_mwatchos_simulator_version_min_EQ
);
1762 if (iOSVersion
|| TvOSVersion
|| WatchOSVersion
) {
1763 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1764 << macOSVersion
->getAsString(Args
)
1765 << (iOSVersion
? iOSVersion
1766 : TvOSVersion
? TvOSVersion
: WatchOSVersion
)
1767 ->getAsString(Args
);
1769 return DarwinPlatform::createOSVersionArg(Darwin::MacOS
, macOSVersion
,
1770 /*IsImulator=*/false);
1771 } else if (iOSVersion
) {
1772 if (TvOSVersion
|| WatchOSVersion
) {
1773 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1774 << iOSVersion
->getAsString(Args
)
1775 << (TvOSVersion
? TvOSVersion
: WatchOSVersion
)->getAsString(Args
);
1777 return DarwinPlatform::createOSVersionArg(
1778 Darwin::IPhoneOS
, iOSVersion
,
1779 iOSVersion
->getOption().getID() ==
1780 options::OPT_mios_simulator_version_min_EQ
);
1781 } else if (TvOSVersion
) {
1782 if (WatchOSVersion
) {
1783 TheDriver
.Diag(diag::err_drv_argument_not_allowed_with
)
1784 << TvOSVersion
->getAsString(Args
)
1785 << WatchOSVersion
->getAsString(Args
);
1787 return DarwinPlatform::createOSVersionArg(
1788 Darwin::TvOS
, TvOSVersion
,
1789 TvOSVersion
->getOption().getID() ==
1790 options::OPT_mtvos_simulator_version_min_EQ
);
1791 } else if (WatchOSVersion
)
1792 return DarwinPlatform::createOSVersionArg(
1793 Darwin::WatchOS
, WatchOSVersion
,
1794 WatchOSVersion
->getOption().getID() ==
1795 options::OPT_mwatchos_simulator_version_min_EQ
);
1799 /// Returns the deployment target that's specified using the
1800 /// OS_DEPLOYMENT_TARGET environment variable.
1801 Optional
<DarwinPlatform
>
1802 getDeploymentTargetFromEnvironmentVariables(const Driver
&TheDriver
,
1803 const llvm::Triple
&Triple
) {
1804 std::string Targets
[Darwin::LastDarwinPlatform
+ 1];
1805 const char *EnvVars
[] = {
1806 "MACOSX_DEPLOYMENT_TARGET",
1807 "IPHONEOS_DEPLOYMENT_TARGET",
1808 "TVOS_DEPLOYMENT_TARGET",
1809 "WATCHOS_DEPLOYMENT_TARGET",
1810 "DRIVERKIT_DEPLOYMENT_TARGET",
1812 static_assert(std::size(EnvVars
) == Darwin::LastDarwinPlatform
+ 1,
1813 "Missing platform");
1814 for (const auto &I
: llvm::enumerate(llvm::makeArrayRef(EnvVars
))) {
1815 if (char *Env
= ::getenv(I
.value()))
1816 Targets
[I
.index()] = Env
;
1819 // Allow conflicts among OSX and iOS for historical reasons, but choose the
1820 // default platform.
1821 if (!Targets
[Darwin::MacOS
].empty() &&
1822 (!Targets
[Darwin::IPhoneOS
].empty() ||
1823 !Targets
[Darwin::WatchOS
].empty() || !Targets
[Darwin::TvOS
].empty())) {
1824 if (Triple
.getArch() == llvm::Triple::arm
||
1825 Triple
.getArch() == llvm::Triple::aarch64
||
1826 Triple
.getArch() == llvm::Triple::thumb
)
1827 Targets
[Darwin::MacOS
] = "";
1829 Targets
[Darwin::IPhoneOS
] = Targets
[Darwin::WatchOS
] =
1830 Targets
[Darwin::TvOS
] = "";
1832 // Don't allow conflicts in any other platform.
1833 unsigned FirstTarget
= std::size(Targets
);
1834 for (unsigned I
= 0; I
!= std::size(Targets
); ++I
) {
1835 if (Targets
[I
].empty())
1837 if (FirstTarget
== std::size(Targets
))
1840 TheDriver
.Diag(diag::err_drv_conflicting_deployment_targets
)
1841 << Targets
[FirstTarget
] << Targets
[I
];
1845 for (const auto &Target
: llvm::enumerate(llvm::makeArrayRef(Targets
))) {
1846 if (!Target
.value().empty())
1847 return DarwinPlatform::createDeploymentTargetEnv(
1848 (Darwin::DarwinPlatformKind
)Target
.index(), EnvVars
[Target
.index()],
1854 /// Returns the SDK name without the optional prefix that ends with a '.' or an
1855 /// empty string otherwise.
1856 static StringRef
dropSDKNamePrefix(StringRef SDKName
) {
1857 size_t PrefixPos
= SDKName
.find('.');
1858 if (PrefixPos
== StringRef::npos
)
1860 return SDKName
.substr(PrefixPos
+ 1);
1863 /// Tries to infer the deployment target from the SDK specified by -isysroot
1864 /// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
1866 Optional
<DarwinPlatform
>
1867 inferDeploymentTargetFromSDK(DerivedArgList
&Args
,
1868 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
1869 const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
);
1872 StringRef isysroot
= A
->getValue();
1873 StringRef SDK
= Darwin::getSDKName(isysroot
);
1877 std::string Version
;
1879 // Get the version from the SDKSettings.json if it's available.
1880 Version
= SDKInfo
->getVersion().getAsString();
1882 // Slice the version number out.
1883 // Version number is between the first and the last number.
1884 size_t StartVer
= SDK
.find_first_of("0123456789");
1885 size_t EndVer
= SDK
.find_last_of("0123456789");
1886 if (StartVer
!= StringRef::npos
&& EndVer
> StartVer
)
1887 Version
= std::string(SDK
.slice(StartVer
, EndVer
+ 1));
1889 if (Version
.empty())
1892 auto CreatePlatformFromSDKName
=
1893 [&](StringRef SDK
) -> Optional
<DarwinPlatform
> {
1894 if (SDK
.startswith("iPhoneOS") || SDK
.startswith("iPhoneSimulator"))
1895 return DarwinPlatform::createFromSDK(
1896 Darwin::IPhoneOS
, Version
,
1897 /*IsSimulator=*/SDK
.startswith("iPhoneSimulator"));
1898 else if (SDK
.startswith("MacOSX"))
1899 return DarwinPlatform::createFromSDK(Darwin::MacOS
,
1900 getSystemOrSDKMacOSVersion(Version
));
1901 else if (SDK
.startswith("WatchOS") || SDK
.startswith("WatchSimulator"))
1902 return DarwinPlatform::createFromSDK(
1903 Darwin::WatchOS
, Version
,
1904 /*IsSimulator=*/SDK
.startswith("WatchSimulator"));
1905 else if (SDK
.startswith("AppleTVOS") || SDK
.startswith("AppleTVSimulator"))
1906 return DarwinPlatform::createFromSDK(
1907 Darwin::TvOS
, Version
,
1908 /*IsSimulator=*/SDK
.startswith("AppleTVSimulator"));
1909 else if (SDK
.startswith("DriverKit"))
1910 return DarwinPlatform::createFromSDK(Darwin::DriverKit
, Version
);
1913 if (auto Result
= CreatePlatformFromSDKName(SDK
))
1915 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
1916 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK
));
1919 std::string
getOSVersion(llvm::Triple::OSType OS
, const llvm::Triple
&Triple
,
1920 const Driver
&TheDriver
) {
1921 VersionTuple OsVersion
;
1922 llvm::Triple
SystemTriple(llvm::sys::getProcessTriple());
1924 case llvm::Triple::Darwin
:
1925 case llvm::Triple::MacOSX
:
1926 // If there is no version specified on triple, and both host and target are
1927 // macos, use the host triple to infer OS version.
1928 if (Triple
.isMacOSX() && SystemTriple
.isMacOSX() &&
1929 !Triple
.getOSMajorVersion())
1930 SystemTriple
.getMacOSXVersion(OsVersion
);
1931 else if (!Triple
.getMacOSXVersion(OsVersion
))
1932 TheDriver
.Diag(diag::err_drv_invalid_darwin_version
)
1933 << Triple
.getOSName();
1935 case llvm::Triple::IOS
:
1936 if (Triple
.isMacCatalystEnvironment() && !Triple
.getOSMajorVersion()) {
1937 OsVersion
= VersionTuple(13, 1);
1939 OsVersion
= Triple
.getiOSVersion();
1941 case llvm::Triple::TvOS
:
1942 OsVersion
= Triple
.getOSVersion();
1944 case llvm::Triple::WatchOS
:
1945 OsVersion
= Triple
.getWatchOSVersion();
1947 case llvm::Triple::DriverKit
:
1948 OsVersion
= Triple
.getDriverKitVersion();
1951 llvm_unreachable("Unexpected OS type");
1955 std::string OSVersion
;
1956 llvm::raw_string_ostream(OSVersion
)
1957 << OsVersion
.getMajor() << '.' << OsVersion
.getMinor().value_or(0) << '.'
1958 << OsVersion
.getSubminor().value_or(0);
1962 /// Tries to infer the target OS from the -arch.
1963 Optional
<DarwinPlatform
>
1964 inferDeploymentTargetFromArch(DerivedArgList
&Args
, const Darwin
&Toolchain
,
1965 const llvm::Triple
&Triple
,
1966 const Driver
&TheDriver
) {
1967 llvm::Triple::OSType OSTy
= llvm::Triple::UnknownOS
;
1969 StringRef MachOArchName
= Toolchain
.getMachOArchName(Args
);
1970 if (MachOArchName
== "arm64" || MachOArchName
== "arm64e")
1971 OSTy
= llvm::Triple::MacOSX
;
1972 else if (MachOArchName
== "armv7" || MachOArchName
== "armv7s")
1973 OSTy
= llvm::Triple::IOS
;
1974 else if (MachOArchName
== "armv7k" || MachOArchName
== "arm64_32")
1975 OSTy
= llvm::Triple::WatchOS
;
1976 else if (MachOArchName
!= "armv6m" && MachOArchName
!= "armv7m" &&
1977 MachOArchName
!= "armv7em")
1978 OSTy
= llvm::Triple::MacOSX
;
1979 if (OSTy
== llvm::Triple::UnknownOS
)
1981 return DarwinPlatform::createFromArch(OSTy
,
1982 getOSVersion(OSTy
, Triple
, TheDriver
));
1985 /// Returns the deployment target that's specified using the -target option.
1986 Optional
<DarwinPlatform
> getDeploymentTargetFromTargetArg(
1987 DerivedArgList
&Args
, const llvm::Triple
&Triple
, const Driver
&TheDriver
,
1988 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
1989 if (!Args
.hasArg(options::OPT_target
))
1991 if (Triple
.getOS() == llvm::Triple::Darwin
||
1992 Triple
.getOS() == llvm::Triple::UnknownOS
)
1994 std::string OSVersion
= getOSVersion(Triple
.getOS(), Triple
, TheDriver
);
1995 Optional
<llvm::Triple
> TargetVariantTriple
;
1996 for (const Arg
*A
: Args
.filtered(options::OPT_darwin_target_variant
)) {
1997 llvm::Triple
TVT(A
->getValue());
1998 // Find a matching <arch>-<vendor> target variant triple that can be used.
1999 if ((Triple
.getArch() == llvm::Triple::aarch64
||
2000 TVT
.getArchName() == Triple
.getArchName()) &&
2001 TVT
.getArch() == Triple
.getArch() &&
2002 TVT
.getSubArch() == Triple
.getSubArch() &&
2003 TVT
.getVendor() == Triple
.getVendor()) {
2004 if (TargetVariantTriple
)
2007 // Accept a -target-variant triple when compiling code that may run on
2008 // macOS or Mac Catalust.
2009 if ((Triple
.isMacOSX() && TVT
.getOS() == llvm::Triple::IOS
&&
2010 TVT
.isMacCatalystEnvironment()) ||
2011 (TVT
.isMacOSX() && Triple
.getOS() == llvm::Triple::IOS
&&
2012 Triple
.isMacCatalystEnvironment())) {
2013 TargetVariantTriple
= TVT
;
2016 TheDriver
.Diag(diag::err_drv_target_variant_invalid
)
2017 << A
->getSpelling() << A
->getValue();
2020 return DarwinPlatform::createFromTarget(Triple
, OSVersion
,
2021 Args
.getLastArg(options::OPT_target
),
2022 TargetVariantTriple
, SDKInfo
);
2025 /// Returns the deployment target that's specified using the -mtargetos option.
2026 Optional
<DarwinPlatform
>
2027 getDeploymentTargetFromMTargetOSArg(DerivedArgList
&Args
,
2028 const Driver
&TheDriver
,
2029 const Optional
<DarwinSDKInfo
> &SDKInfo
) {
2030 auto *A
= Args
.getLastArg(options::OPT_mtargetos_EQ
);
2033 llvm::Triple
TT(llvm::Twine("unknown-apple-") + A
->getValue());
2034 switch (TT
.getOS()) {
2035 case llvm::Triple::MacOSX
:
2036 case llvm::Triple::IOS
:
2037 case llvm::Triple::TvOS
:
2038 case llvm::Triple::WatchOS
:
2041 TheDriver
.Diag(diag::err_drv_invalid_os_in_arg
)
2042 << TT
.getOSName() << A
->getAsString(Args
);
2046 VersionTuple Version
= TT
.getOSVersion();
2047 if (!Version
.getMajor()) {
2048 TheDriver
.Diag(diag::err_drv_invalid_version_number
)
2049 << A
->getAsString(Args
);
2052 return DarwinPlatform::createFromMTargetOS(TT
.getOS(), Version
,
2053 TT
.getEnvironment(), A
, SDKInfo
);
2056 Optional
<DarwinSDKInfo
> parseSDKSettings(llvm::vfs::FileSystem
&VFS
,
2057 const ArgList
&Args
,
2058 const Driver
&TheDriver
) {
2059 const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
);
2062 StringRef isysroot
= A
->getValue();
2063 auto SDKInfoOrErr
= parseDarwinSDKInfo(VFS
, isysroot
);
2064 if (!SDKInfoOrErr
) {
2065 llvm::consumeError(SDKInfoOrErr
.takeError());
2066 TheDriver
.Diag(diag::warn_drv_darwin_sdk_invalid_settings
);
2069 return *SDKInfoOrErr
;
2074 void Darwin::AddDeploymentTarget(DerivedArgList
&Args
) const {
2075 const OptTable
&Opts
= getDriver().getOpts();
2077 // Support allowing the SDKROOT environment variable used by xcrun and other
2078 // Xcode tools to define the default sysroot, by making it the default for
2080 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2081 // Warn if the path does not exist.
2082 if (!getVFS().exists(A
->getValue()))
2083 getDriver().Diag(clang::diag::warn_missing_sysroot
) << A
->getValue();
2085 if (char *env
= ::getenv("SDKROOT")) {
2086 // We only use this value as the default if it is an absolute path,
2087 // exists, and it is not the root path.
2088 if (llvm::sys::path::is_absolute(env
) && getVFS().exists(env
) &&
2089 StringRef(env
) != "/") {
2090 Args
.append(Args
.MakeSeparateArg(
2091 nullptr, Opts
.getOption(options::OPT_isysroot
), env
));
2096 // Read the SDKSettings.json file for more information, like the SDK version
2097 // that we can pass down to the compiler.
2098 SDKInfo
= parseSDKSettings(getVFS(), Args
, getDriver());
2100 // The OS and the version can be specified using the -target argument.
2101 Optional
<DarwinPlatform
> OSTarget
=
2102 getDeploymentTargetFromTargetArg(Args
, getTriple(), getDriver(), SDKInfo
);
2104 // Disallow mixing -target and -mtargetos=.
2105 if (const auto *MTargetOSArg
= Args
.getLastArg(options::OPT_mtargetos_EQ
)) {
2106 std::string TargetArgStr
= OSTarget
->getAsString(Args
, Opts
);
2107 std::string MTargetOSArgStr
= MTargetOSArg
->getAsString(Args
);
2108 getDriver().Diag(diag::err_drv_cannot_mix_options
)
2109 << TargetArgStr
<< MTargetOSArgStr
;
2111 Optional
<DarwinPlatform
> OSVersionArgTarget
=
2112 getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2113 if (OSVersionArgTarget
) {
2114 unsigned TargetMajor
, TargetMinor
, TargetMicro
;
2116 unsigned ArgMajor
, ArgMinor
, ArgMicro
;
2118 if (OSTarget
->getPlatform() != OSVersionArgTarget
->getPlatform() ||
2119 (Driver::GetReleaseVersion(OSTarget
->getOSVersion(), TargetMajor
,
2120 TargetMinor
, TargetMicro
, TargetExtra
) &&
2121 Driver::GetReleaseVersion(OSVersionArgTarget
->getOSVersion(),
2122 ArgMajor
, ArgMinor
, ArgMicro
, ArgExtra
) &&
2123 (VersionTuple(TargetMajor
, TargetMinor
, TargetMicro
) !=
2124 VersionTuple(ArgMajor
, ArgMinor
, ArgMicro
) ||
2125 TargetExtra
!= ArgExtra
))) {
2126 // Select the OS version from the -m<os>-version-min argument when
2127 // the -target does not include an OS version.
2128 if (OSTarget
->getPlatform() == OSVersionArgTarget
->getPlatform() &&
2129 !OSTarget
->hasOSVersion()) {
2130 OSTarget
->setOSVersion(OSVersionArgTarget
->getOSVersion());
2132 // Warn about -m<os>-version-min that doesn't match the OS version
2133 // that's specified in the target.
2134 std::string OSVersionArg
=
2135 OSVersionArgTarget
->getAsString(Args
, Opts
);
2136 std::string TargetArg
= OSTarget
->getAsString(Args
, Opts
);
2137 getDriver().Diag(clang::diag::warn_drv_overriding_flag_option
)
2138 << OSVersionArg
<< TargetArg
;
2142 } else if ((OSTarget
= getDeploymentTargetFromMTargetOSArg(Args
, getDriver(),
2144 // The OS target can be specified using the -mtargetos= argument.
2145 // Disallow mixing -mtargetos= and -m<os>version-min=.
2146 Optional
<DarwinPlatform
> OSVersionArgTarget
=
2147 getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2148 if (OSVersionArgTarget
) {
2149 std::string MTargetOSArgStr
= OSTarget
->getAsString(Args
, Opts
);
2150 std::string OSVersionArgStr
= OSVersionArgTarget
->getAsString(Args
, Opts
);
2151 getDriver().Diag(diag::err_drv_cannot_mix_options
)
2152 << MTargetOSArgStr
<< OSVersionArgStr
;
2155 // The OS target can be specified using the -m<os>version-min argument.
2156 OSTarget
= getDeploymentTargetFromOSVersionArg(Args
, getDriver());
2157 // If no deployment target was specified on the command line, check for
2158 // environment defines.
2161 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
2163 // Don't infer simulator from the arch when the SDK is also specified.
2164 Optional
<DarwinPlatform
> SDKTarget
=
2165 inferDeploymentTargetFromSDK(Args
, SDKInfo
);
2167 OSTarget
->setEnvironment(SDKTarget
->getEnvironment());
2170 // If there is no command-line argument to specify the Target version and
2171 // no environment variable defined, see if we can set the default based
2172 // on -isysroot using SDKSettings.json if it exists.
2174 OSTarget
= inferDeploymentTargetFromSDK(Args
, SDKInfo
);
2175 /// If the target was successfully constructed from the SDK path, try to
2176 /// infer the SDK info if the SDK doesn't have it.
2177 if (OSTarget
&& !SDKInfo
)
2178 SDKInfo
= OSTarget
->inferSDKInfo();
2180 // If no OS targets have been specified, try to guess platform from -target
2181 // or arch name and compute the version from the triple.
2184 inferDeploymentTargetFromArch(Args
, *this, getTriple(), getDriver());
2187 assert(OSTarget
&& "Unable to infer Darwin variant");
2188 OSTarget
->addOSVersionMinArgument(Args
, Opts
);
2189 DarwinPlatformKind Platform
= OSTarget
->getPlatform();
2191 unsigned Major
, Minor
, Micro
;
2193 // Set the tool chain target information.
2194 if (Platform
== MacOS
) {
2195 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2197 HadExtra
|| Major
< 10 || Major
>= 100 || Minor
>= 100 || Micro
>= 100)
2198 getDriver().Diag(diag::err_drv_invalid_version_number
)
2199 << OSTarget
->getAsString(Args
, Opts
);
2200 } else if (Platform
== IPhoneOS
) {
2201 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2203 HadExtra
|| Major
>= 100 || Minor
>= 100 || Micro
>= 100)
2204 getDriver().Diag(diag::err_drv_invalid_version_number
)
2205 << OSTarget
->getAsString(Args
, Opts
);
2207 if (OSTarget
->getEnvironment() == MacCatalyst
&&
2208 (Major
< 13 || (Major
== 13 && Minor
< 1))) {
2209 getDriver().Diag(diag::err_drv_invalid_version_number
)
2210 << OSTarget
->getAsString(Args
, Opts
);
2215 // For 32-bit targets, the deployment target for iOS has to be earlier than
2217 if (getTriple().isArch32Bit() && Major
>= 11) {
2218 // If the deployment target is explicitly specified, print a diagnostic.
2219 if (OSTarget
->isExplicitlySpecified()) {
2220 if (OSTarget
->getEnvironment() == MacCatalyst
)
2221 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target
);
2223 getDriver().Diag(diag::warn_invalid_ios_deployment_target
)
2224 << OSTarget
->getAsString(Args
, Opts
);
2225 // Otherwise, set it to 10.99.99.
2232 } else if (Platform
== TvOS
) {
2233 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2235 HadExtra
|| Major
>= 100 || Minor
>= 100 || Micro
>= 100)
2236 getDriver().Diag(diag::err_drv_invalid_version_number
)
2237 << OSTarget
->getAsString(Args
, Opts
);
2238 } else if (Platform
== WatchOS
) {
2239 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2241 HadExtra
|| Major
>= 10 || Minor
>= 100 || Micro
>= 100)
2242 getDriver().Diag(diag::err_drv_invalid_version_number
)
2243 << OSTarget
->getAsString(Args
, Opts
);
2244 } else if (Platform
== DriverKit
) {
2245 if (!Driver::GetReleaseVersion(OSTarget
->getOSVersion(), Major
, Minor
,
2247 HadExtra
|| Major
< 19 || Major
>= 100 || Minor
>= 100 || Micro
>= 100)
2248 getDriver().Diag(diag::err_drv_invalid_version_number
)
2249 << OSTarget
->getAsString(Args
, Opts
);
2251 llvm_unreachable("unknown kind of Darwin platform");
2253 DarwinEnvironmentKind Environment
= OSTarget
->getEnvironment();
2254 // Recognize iOS targets with an x86 architecture as the iOS simulator.
2255 if (Environment
== NativeEnvironment
&& Platform
!= MacOS
&&
2256 Platform
!= DriverKit
&& OSTarget
->canInferSimulatorFromArch() &&
2257 getTriple().isX86())
2258 Environment
= Simulator
;
2260 VersionTuple NativeTargetVersion
;
2261 if (Environment
== MacCatalyst
)
2262 NativeTargetVersion
= OSTarget
->getNativeTargetVersion();
2263 setTarget(Platform
, Environment
, Major
, Minor
, Micro
, NativeTargetVersion
);
2264 TargetVariantTriple
= OSTarget
->getTargetVariantTriple();
2266 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2267 StringRef SDK
= getSDKName(A
->getValue());
2268 if (SDK
.size() > 0) {
2269 size_t StartVer
= SDK
.find_first_of("0123456789");
2270 StringRef SDKName
= SDK
.slice(0, StartVer
);
2271 if (!SDKName
.startswith(getPlatformFamily()) &&
2272 !dropSDKNamePrefix(SDKName
).startswith(getPlatformFamily()))
2273 getDriver().Diag(diag::warn_incompatible_sysroot
)
2274 << SDKName
<< getPlatformFamily();
2279 // For certain platforms/environments almost all resources (e.g., headers) are
2280 // located in sub-directories, e.g., for DriverKit they live in
2281 // <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).
2282 static void AppendPlatformPrefix(SmallString
<128> &Path
,
2283 const llvm::Triple
&T
) {
2284 if (T
.isDriverKit()) {
2285 llvm::sys::path::append(Path
, "System", "DriverKit");
2289 // Returns the effective sysroot from either -isysroot or --sysroot, plus the
2290 // platform prefix (if any).
2291 llvm::SmallString
<128>
2292 DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList
&DriverArgs
) const {
2293 llvm::SmallString
<128> Path("/");
2294 if (DriverArgs
.hasArg(options::OPT_isysroot
))
2295 Path
= DriverArgs
.getLastArgValue(options::OPT_isysroot
);
2296 else if (!getDriver().SysRoot
.empty())
2297 Path
= getDriver().SysRoot
;
2299 if (hasEffectiveTriple()) {
2300 AppendPlatformPrefix(Path
, getEffectiveTriple());
2305 void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList
&DriverArgs
,
2306 llvm::opt::ArgStringList
&CC1Args
) const {
2307 const Driver
&D
= getDriver();
2309 llvm::SmallString
<128> Sysroot
= GetEffectiveSysroot(DriverArgs
);
2311 bool NoStdInc
= DriverArgs
.hasArg(options::OPT_nostdinc
);
2312 bool NoStdlibInc
= DriverArgs
.hasArg(options::OPT_nostdlibinc
);
2313 bool NoBuiltinInc
= DriverArgs
.hasFlag(
2314 options::OPT_nobuiltininc
, options::OPT_ibuiltininc
, /*Default=*/false);
2315 bool ForceBuiltinInc
= DriverArgs
.hasFlag(
2316 options::OPT_ibuiltininc
, options::OPT_nobuiltininc
, /*Default=*/false);
2318 // Add <sysroot>/usr/local/include
2319 if (!NoStdInc
&& !NoStdlibInc
) {
2320 SmallString
<128> P(Sysroot
);
2321 llvm::sys::path::append(P
, "usr", "local", "include");
2322 addSystemInclude(DriverArgs
, CC1Args
, P
);
2325 // Add the Clang builtin headers (<resource>/include)
2326 if (!(NoStdInc
&& !ForceBuiltinInc
) && !NoBuiltinInc
) {
2327 SmallString
<128> P(D
.ResourceDir
);
2328 llvm::sys::path::append(P
, "include");
2329 addSystemInclude(DriverArgs
, CC1Args
, P
);
2332 if (NoStdInc
|| NoStdlibInc
)
2335 // Check for configure-time C include directories.
2336 llvm::StringRef
CIncludeDirs(C_INCLUDE_DIRS
);
2337 if (!CIncludeDirs
.empty()) {
2338 llvm::SmallVector
<llvm::StringRef
, 5> dirs
;
2339 CIncludeDirs
.split(dirs
, ":");
2340 for (llvm::StringRef dir
: dirs
) {
2341 llvm::StringRef Prefix
=
2342 llvm::sys::path::is_absolute(dir
) ? "" : llvm::StringRef(Sysroot
);
2343 addExternCSystemInclude(DriverArgs
, CC1Args
, Prefix
+ dir
);
2346 // Otherwise, add <sysroot>/usr/include.
2347 SmallString
<128> P(Sysroot
);
2348 llvm::sys::path::append(P
, "usr", "include");
2349 addExternCSystemInclude(DriverArgs
, CC1Args
, P
.str());
2353 bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList
&DriverArgs
,
2354 llvm::opt::ArgStringList
&CC1Args
,
2355 llvm::SmallString
<128> Base
,
2356 llvm::StringRef Version
,
2357 llvm::StringRef ArchDir
,
2358 llvm::StringRef BitDir
) const {
2359 llvm::sys::path::append(Base
, Version
);
2362 addSystemInclude(DriverArgs
, CC1Args
, Base
);
2364 // Add the multilib dirs
2366 llvm::SmallString
<128> P
= Base
;
2367 if (!ArchDir
.empty())
2368 llvm::sys::path::append(P
, ArchDir
);
2369 if (!BitDir
.empty())
2370 llvm::sys::path::append(P
, BitDir
);
2371 addSystemInclude(DriverArgs
, CC1Args
, P
);
2374 // Add the backward dir
2376 llvm::SmallString
<128> P
= Base
;
2377 llvm::sys::path::append(P
, "backward");
2378 addSystemInclude(DriverArgs
, CC1Args
, P
);
2381 return getVFS().exists(Base
);
2384 void DarwinClang::AddClangCXXStdlibIncludeArgs(
2385 const llvm::opt::ArgList
&DriverArgs
,
2386 llvm::opt::ArgStringList
&CC1Args
) const {
2387 // The implementation from a base class will pass through the -stdlib to
2389 // FIXME: this should not be necessary, remove usages in the frontend
2390 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
2391 // Also check whether this is used for setting library search paths.
2392 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs
, CC1Args
);
2394 if (DriverArgs
.hasArg(options::OPT_nostdlibinc
) ||
2395 DriverArgs
.hasArg(options::OPT_nostdincxx
))
2398 llvm::SmallString
<128> Sysroot
= GetEffectiveSysroot(DriverArgs
);
2400 switch (GetCXXStdlibType(DriverArgs
)) {
2401 case ToolChain::CST_Libcxx
: {
2402 // On Darwin, libc++ can be installed in one of the following two places:
2403 // 1. Alongside the compiler in <install>/include/c++/v1
2404 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
2406 // The precendence of paths is as listed above, i.e. we take the first path
2407 // that exists. Also note that we never include libc++ twice -- we take the
2408 // first path that exists and don't send the other paths to CC1 (otherwise
2409 // include_next could break).
2412 // Get from '<install>/bin' to '<install>/include/c++/v1'.
2413 // Note that InstallBin can be relative, so we use '..' instead of
2415 llvm::SmallString
<128> InstallBin
=
2416 llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin
2417 llvm::sys::path::append(InstallBin
, "..", "include", "c++", "v1");
2418 if (getVFS().exists(InstallBin
)) {
2419 addSystemInclude(DriverArgs
, CC1Args
, InstallBin
);
2421 } else if (DriverArgs
.hasArg(options::OPT_v
)) {
2422 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
2426 // Otherwise, check for (2)
2427 llvm::SmallString
<128> SysrootUsr
= Sysroot
;
2428 llvm::sys::path::append(SysrootUsr
, "usr", "include", "c++", "v1");
2429 if (getVFS().exists(SysrootUsr
)) {
2430 addSystemInclude(DriverArgs
, CC1Args
, SysrootUsr
);
2432 } else if (DriverArgs
.hasArg(options::OPT_v
)) {
2433 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
2437 // Otherwise, don't add any path.
2441 case ToolChain::CST_Libstdcxx
:
2442 llvm::SmallString
<128> UsrIncludeCxx
= Sysroot
;
2443 llvm::sys::path::append(UsrIncludeCxx
, "usr", "include", "c++");
2445 llvm::Triple::ArchType arch
= getTriple().getArch();
2446 bool IsBaseFound
= true;
2450 case llvm::Triple::ppc
:
2451 case llvm::Triple::ppc64
:
2452 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2454 "powerpc-apple-darwin10",
2455 arch
== llvm::Triple::ppc64
? "ppc64" : "");
2456 IsBaseFound
|= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2457 "4.0.0", "powerpc-apple-darwin10",
2458 arch
== llvm::Triple::ppc64
? "ppc64" : "");
2461 case llvm::Triple::x86
:
2462 case llvm::Triple::x86_64
:
2463 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2465 "i686-apple-darwin10",
2466 arch
== llvm::Triple::x86_64
? "x86_64" : "");
2467 IsBaseFound
|= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2468 "4.0.0", "i686-apple-darwin8",
2472 case llvm::Triple::arm
:
2473 case llvm::Triple::thumb
:
2474 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2476 "arm-apple-darwin10",
2478 IsBaseFound
|= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2480 "arm-apple-darwin10",
2484 case llvm::Triple::aarch64
:
2485 IsBaseFound
= AddGnuCPlusPlusIncludePaths(DriverArgs
, CC1Args
, UsrIncludeCxx
,
2487 "arm64-apple-darwin10",
2493 getDriver().Diag(diag::warn_drv_libstdcxx_not_found
);
2500 void DarwinClang::AddCXXStdlibLibArgs(const ArgList
&Args
,
2501 ArgStringList
&CmdArgs
) const {
2502 CXXStdlibType Type
= GetCXXStdlibType(Args
);
2505 case ToolChain::CST_Libcxx
:
2506 CmdArgs
.push_back("-lc++");
2507 if (Args
.hasArg(options::OPT_fexperimental_library
))
2508 CmdArgs
.push_back("-lc++experimental");
2511 case ToolChain::CST_Libstdcxx
:
2512 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
2513 // it was previously found in the gcc lib dir. However, for all the Darwin
2514 // platforms we care about it was -lstdc++.6, so we search for that
2515 // explicitly if we can't see an obvious -lstdc++ candidate.
2517 // Check in the sysroot first.
2518 if (const Arg
*A
= Args
.getLastArg(options::OPT_isysroot
)) {
2519 SmallString
<128> P(A
->getValue());
2520 llvm::sys::path::append(P
, "usr", "lib", "libstdc++.dylib");
2522 if (!getVFS().exists(P
)) {
2523 llvm::sys::path::remove_filename(P
);
2524 llvm::sys::path::append(P
, "libstdc++.6.dylib");
2525 if (getVFS().exists(P
)) {
2526 CmdArgs
.push_back(Args
.MakeArgString(P
));
2532 // Otherwise, look in the root.
2533 // FIXME: This should be removed someday when we don't have to care about
2534 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
2535 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
2536 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
2537 CmdArgs
.push_back("/usr/lib/libstdc++.6.dylib");
2541 // Otherwise, let the linker search.
2542 CmdArgs
.push_back("-lstdc++");
2547 void DarwinClang::AddCCKextLibArgs(const ArgList
&Args
,
2548 ArgStringList
&CmdArgs
) const {
2549 // For Darwin platforms, use the compiler-rt-based support library
2550 // instead of the gcc-provided one (which is also incidentally
2551 // only present in the gcc lib dir, which makes it hard to find).
2553 SmallString
<128> P(getDriver().ResourceDir
);
2554 llvm::sys::path::append(P
, "lib", "darwin");
2556 // Use the newer cc_kext for iOS ARM after 6.0.
2557 if (isTargetWatchOS()) {
2558 llvm::sys::path::append(P
, "libclang_rt.cc_kext_watchos.a");
2559 } else if (isTargetTvOS()) {
2560 llvm::sys::path::append(P
, "libclang_rt.cc_kext_tvos.a");
2561 } else if (isTargetIPhoneOS()) {
2562 llvm::sys::path::append(P
, "libclang_rt.cc_kext_ios.a");
2563 } else if (isTargetDriverKit()) {
2564 // DriverKit doesn't want extra runtime support.
2566 llvm::sys::path::append(P
, "libclang_rt.cc_kext.a");
2569 // For now, allow missing resource libraries to support developers who may
2570 // not have compiler-rt checked out or integrated into their build.
2571 if (getVFS().exists(P
))
2572 CmdArgs
.push_back(Args
.MakeArgString(P
));
2575 DerivedArgList
*MachO::TranslateArgs(const DerivedArgList
&Args
,
2576 StringRef BoundArch
,
2577 Action::OffloadKind
) const {
2578 DerivedArgList
*DAL
= new DerivedArgList(Args
.getBaseArgs());
2579 const OptTable
&Opts
= getDriver().getOpts();
2581 // FIXME: We really want to get out of the tool chain level argument
2582 // translation business, as it makes the driver functionality much
2583 // more opaque. For now, we follow gcc closely solely for the
2584 // purpose of easily achieving feature parity & testability. Once we
2585 // have something that works, we should reevaluate each translation
2586 // and try to push it down into tool specific logic.
2588 for (Arg
*A
: Args
) {
2589 if (A
->getOption().matches(options::OPT_Xarch__
)) {
2590 // Skip this argument unless the architecture matches either the toolchain
2591 // triple arch, or the arch being bound.
2592 StringRef XarchArch
= A
->getValue(0);
2593 if (!(XarchArch
== getArchName() ||
2594 (!BoundArch
.empty() && XarchArch
== BoundArch
)))
2597 Arg
*OriginalArg
= A
;
2598 TranslateXarchArgs(Args
, A
, DAL
);
2600 // Linker input arguments require custom handling. The problem is that we
2601 // have already constructed the phase actions, so we can not treat them as
2602 // "input arguments".
2603 if (A
->getOption().hasFlag(options::LinkerInput
)) {
2604 // Convert the argument into individual Zlinker_input_args.
2605 for (const char *Value
: A
->getValues()) {
2606 DAL
->AddSeparateArg(
2607 OriginalArg
, Opts
.getOption(options::OPT_Zlinker_input
), Value
);
2613 // Sob. These is strictly gcc compatible for the time being. Apple
2614 // gcc translates options twice, which means that self-expanding
2615 // options add duplicates.
2616 switch ((options::ID
)A
->getOption().getID()) {
2621 case options::OPT_mkernel
:
2622 case options::OPT_fapple_kext
:
2624 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_static
));
2627 case options::OPT_dependency_file
:
2628 DAL
->AddSeparateArg(A
, Opts
.getOption(options::OPT_MF
), A
->getValue());
2631 case options::OPT_gfull
:
2632 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
));
2634 A
, Opts
.getOption(options::OPT_fno_eliminate_unused_debug_symbols
));
2637 case options::OPT_gused
:
2638 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
));
2640 A
, Opts
.getOption(options::OPT_feliminate_unused_debug_symbols
));
2643 case options::OPT_shared
:
2644 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_dynamiclib
));
2647 case options::OPT_fconstant_cfstrings
:
2648 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_mconstant_cfstrings
));
2651 case options::OPT_fno_constant_cfstrings
:
2652 DAL
->AddFlagArg(A
, Opts
.getOption(options::OPT_mno_constant_cfstrings
));
2655 case options::OPT_Wnonportable_cfstrings
:
2657 Opts
.getOption(options::OPT_mwarn_nonportable_cfstrings
));
2660 case options::OPT_Wno_nonportable_cfstrings
:
2662 A
, Opts
.getOption(options::OPT_mno_warn_nonportable_cfstrings
));
2667 // Add the arch options based on the particular spelling of -arch, to match
2668 // how the driver driver works.
2669 if (!BoundArch
.empty()) {
2670 StringRef Name
= BoundArch
;
2671 const Option MCpu
= Opts
.getOption(options::OPT_mcpu_EQ
);
2672 const Option MArch
= Opts
.getOption(clang::driver::options::OPT_march_EQ
);
2674 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
2675 // which defines the list of which architectures we accept.
2678 else if (Name
== "ppc601")
2679 DAL
->AddJoinedArg(nullptr, MCpu
, "601");
2680 else if (Name
== "ppc603")
2681 DAL
->AddJoinedArg(nullptr, MCpu
, "603");
2682 else if (Name
== "ppc604")
2683 DAL
->AddJoinedArg(nullptr, MCpu
, "604");
2684 else if (Name
== "ppc604e")
2685 DAL
->AddJoinedArg(nullptr, MCpu
, "604e");
2686 else if (Name
== "ppc750")
2687 DAL
->AddJoinedArg(nullptr, MCpu
, "750");
2688 else if (Name
== "ppc7400")
2689 DAL
->AddJoinedArg(nullptr, MCpu
, "7400");
2690 else if (Name
== "ppc7450")
2691 DAL
->AddJoinedArg(nullptr, MCpu
, "7450");
2692 else if (Name
== "ppc970")
2693 DAL
->AddJoinedArg(nullptr, MCpu
, "970");
2695 else if (Name
== "ppc64" || Name
== "ppc64le")
2696 DAL
->AddFlagArg(nullptr, Opts
.getOption(options::OPT_m64
));
2698 else if (Name
== "i386")
2700 else if (Name
== "i486")
2701 DAL
->AddJoinedArg(nullptr, MArch
, "i486");
2702 else if (Name
== "i586")
2703 DAL
->AddJoinedArg(nullptr, MArch
, "i586");
2704 else if (Name
== "i686")
2705 DAL
->AddJoinedArg(nullptr, MArch
, "i686");
2706 else if (Name
== "pentium")
2707 DAL
->AddJoinedArg(nullptr, MArch
, "pentium");
2708 else if (Name
== "pentium2")
2709 DAL
->AddJoinedArg(nullptr, MArch
, "pentium2");
2710 else if (Name
== "pentpro")
2711 DAL
->AddJoinedArg(nullptr, MArch
, "pentiumpro");
2712 else if (Name
== "pentIIm3")
2713 DAL
->AddJoinedArg(nullptr, MArch
, "pentium2");
2715 else if (Name
== "x86_64" || Name
== "x86_64h")
2716 DAL
->AddFlagArg(nullptr, Opts
.getOption(options::OPT_m64
));
2718 else if (Name
== "arm")
2719 DAL
->AddJoinedArg(nullptr, MArch
, "armv4t");
2720 else if (Name
== "armv4t")
2721 DAL
->AddJoinedArg(nullptr, MArch
, "armv4t");
2722 else if (Name
== "armv5")
2723 DAL
->AddJoinedArg(nullptr, MArch
, "armv5tej");
2724 else if (Name
== "xscale")
2725 DAL
->AddJoinedArg(nullptr, MArch
, "xscale");
2726 else if (Name
== "armv6")
2727 DAL
->AddJoinedArg(nullptr, MArch
, "armv6k");
2728 else if (Name
== "armv6m")
2729 DAL
->AddJoinedArg(nullptr, MArch
, "armv6m");
2730 else if (Name
== "armv7")
2731 DAL
->AddJoinedArg(nullptr, MArch
, "armv7a");
2732 else if (Name
== "armv7em")
2733 DAL
->AddJoinedArg(nullptr, MArch
, "armv7em");
2734 else if (Name
== "armv7k")
2735 DAL
->AddJoinedArg(nullptr, MArch
, "armv7k");
2736 else if (Name
== "armv7m")
2737 DAL
->AddJoinedArg(nullptr, MArch
, "armv7m");
2738 else if (Name
== "armv7s")
2739 DAL
->AddJoinedArg(nullptr, MArch
, "armv7s");
2745 void MachO::AddLinkRuntimeLibArgs(const ArgList
&Args
,
2746 ArgStringList
&CmdArgs
,
2747 bool ForceLinkBuiltinRT
) const {
2748 // Embedded targets are simple at the moment, not supporting sanitizers and
2749 // with different libraries for each member of the product { static, PIC } x
2750 // { hard-float, soft-float }
2751 llvm::SmallString
<32> CompilerRT
= StringRef("");
2753 (tools::arm::getARMFloatABI(*this, Args
) == tools::arm::FloatABI::Hard
)
2756 CompilerRT
+= Args
.hasArg(options::OPT_fPIC
) ? "_pic" : "_static";
2758 AddLinkRuntimeLib(Args
, CmdArgs
, CompilerRT
, RLO_IsEmbedded
);
2761 bool Darwin::isAlignedAllocationUnavailable() const {
2762 llvm::Triple::OSType OS
;
2764 if (isTargetMacCatalyst())
2765 return TargetVersion
< alignedAllocMinVersion(llvm::Triple::MacOSX
);
2766 switch (TargetPlatform
) {
2767 case MacOS
: // Earlier than 10.13.
2768 OS
= llvm::Triple::MacOSX
;
2771 OS
= llvm::Triple::IOS
;
2773 case TvOS
: // Earlier than 11.0.
2774 OS
= llvm::Triple::TvOS
;
2776 case WatchOS
: // Earlier than 4.0.
2777 OS
= llvm::Triple::WatchOS
;
2779 case DriverKit
: // Always available.
2783 return TargetVersion
< alignedAllocMinVersion(OS
);
2786 void Darwin::addClangTargetOptions(const llvm::opt::ArgList
&DriverArgs
,
2787 llvm::opt::ArgStringList
&CC1Args
,
2788 Action::OffloadKind DeviceOffloadKind
) const {
2789 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
2790 // enabled or disabled aligned allocations.
2791 if (!DriverArgs
.hasArgNoClaim(options::OPT_faligned_allocation
,
2792 options::OPT_fno_aligned_allocation
) &&
2793 isAlignedAllocationUnavailable())
2794 CC1Args
.push_back("-faligned-alloc-unavailable");
2796 if (TargetVariantTriple
) {
2797 CC1Args
.push_back("-darwin-target-variant-triple");
2799 DriverArgs
.MakeArgString(TargetVariantTriple
->getTriple()));
2803 /// Pass the SDK version to the compiler when the SDK information is
2805 auto EmitTargetSDKVersionArg
= [&](const VersionTuple
&V
) {
2807 llvm::raw_string_ostream
OS(Arg
);
2808 OS
<< "-target-sdk-version=" << V
;
2809 CC1Args
.push_back(DriverArgs
.MakeArgString(OS
.str()));
2812 if (isTargetMacCatalyst()) {
2813 if (const auto *MacOStoMacCatalystMapping
= SDKInfo
->getVersionMapping(
2814 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2815 Optional
<VersionTuple
> SDKVersion
= MacOStoMacCatalystMapping
->map(
2816 SDKInfo
->getVersion(), minimumMacCatalystDeploymentTarget(), None
);
2817 EmitTargetSDKVersionArg(
2818 SDKVersion
? *SDKVersion
: minimumMacCatalystDeploymentTarget());
2821 EmitTargetSDKVersionArg(SDKInfo
->getVersion());
2824 /// Pass the target variant SDK version to the compiler when the SDK
2825 /// information is available and is required for target variant.
2826 if (TargetVariantTriple
) {
2827 if (isTargetMacCatalyst()) {
2829 llvm::raw_string_ostream
OS(Arg
);
2830 OS
<< "-darwin-target-variant-sdk-version=" << SDKInfo
->getVersion();
2831 CC1Args
.push_back(DriverArgs
.MakeArgString(OS
.str()));
2832 } else if (const auto *MacOStoMacCatalystMapping
=
2833 SDKInfo
->getVersionMapping(
2834 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2835 if (Optional
<VersionTuple
> SDKVersion
= MacOStoMacCatalystMapping
->map(
2836 SDKInfo
->getVersion(), minimumMacCatalystDeploymentTarget(),
2839 llvm::raw_string_ostream
OS(Arg
);
2840 OS
<< "-darwin-target-variant-sdk-version=" << *SDKVersion
;
2841 CC1Args
.push_back(DriverArgs
.MakeArgString(OS
.str()));
2847 // Enable compatibility mode for NSItemProviderCompletionHandler in
2848 // Foundation/NSItemProvider.h.
2849 CC1Args
.push_back("-fcompatibility-qualified-id-block-type-checking");
2851 // Give static local variables in inline functions hidden visibility when
2852 // -fvisibility-inlines-hidden is enabled.
2853 if (!DriverArgs
.getLastArgNoClaim(
2854 options::OPT_fvisibility_inlines_hidden_static_local_var
,
2855 options::OPT_fno_visibility_inlines_hidden_static_local_var
))
2856 CC1Args
.push_back("-fvisibility-inlines-hidden-static-local-var");
2860 Darwin::TranslateArgs(const DerivedArgList
&Args
, StringRef BoundArch
,
2861 Action::OffloadKind DeviceOffloadKind
) const {
2862 // First get the generic Apple args, before moving onto Darwin-specific ones.
2863 DerivedArgList
*DAL
=
2864 MachO::TranslateArgs(Args
, BoundArch
, DeviceOffloadKind
);
2865 const OptTable
&Opts
= getDriver().getOpts();
2867 // If no architecture is bound, none of the translations here are relevant.
2868 if (BoundArch
.empty())
2871 // Add an explicit version min argument for the deployment target. We do this
2872 // after argument translation because -Xarch_ arguments may add a version min
2874 AddDeploymentTarget(*DAL
);
2876 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
2877 // FIXME: It would be far better to avoid inserting those -static arguments,
2878 // but we can't check the deployment target in the translation code until
2880 if (isTargetWatchOSBased() || isTargetDriverKit() ||
2881 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
2882 for (ArgList::iterator it
= DAL
->begin(), ie
= DAL
->end(); it
!= ie
; ) {
2885 if (A
->getOption().getID() != options::OPT_mkernel
&&
2886 A
->getOption().getID() != options::OPT_fapple_kext
)
2888 assert(it
!= ie
&& "unexpected argument translation");
2890 assert(A
->getOption().getID() == options::OPT_static
&&
2891 "missing expected -static argument");
2897 if (!Args
.getLastArg(options::OPT_stdlib_EQ
) &&
2898 GetCXXStdlibType(Args
) == ToolChain::CST_Libcxx
)
2899 DAL
->AddJoinedArg(nullptr, Opts
.getOption(options::OPT_stdlib_EQ
),
2902 // Validate the C++ standard library choice.
2903 CXXStdlibType Type
= GetCXXStdlibType(*DAL
);
2904 if (Type
== ToolChain::CST_Libcxx
) {
2905 // Check whether the target provides libc++.
2908 // Complain about targeting iOS < 5.0 in any way.
2909 if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
2912 if (where
!= StringRef()) {
2913 getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment
) << where
;
2917 auto Arch
= tools::darwin::getArchTypeForMachOArchName(BoundArch
);
2918 if ((Arch
== llvm::Triple::arm
|| Arch
== llvm::Triple::thumb
)) {
2919 if (Args
.hasFlag(options::OPT_fomit_frame_pointer
,
2920 options::OPT_fno_omit_frame_pointer
, false))
2921 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target
)
2922 << "-fomit-frame-pointer" << BoundArch
;
2928 bool MachO::IsUnwindTablesDefault(const ArgList
&Args
) const {
2929 // Unwind tables are not emitted if -fno-exceptions is supplied (except when
2930 // targeting x86_64).
2931 return getArch() == llvm::Triple::x86_64
||
2932 (GetExceptionModel(Args
) != llvm::ExceptionHandling::SjLj
&&
2933 Args
.hasFlag(options::OPT_fexceptions
, options::OPT_fno_exceptions
,
2937 bool MachO::UseDwarfDebugFlags() const {
2938 if (const char *S
= ::getenv("RC_DEBUG_OPTIONS"))
2939 return S
[0] != '\0';
2943 std::string
MachO::GetGlobalDebugPathRemapping() const {
2944 if (const char *S
= ::getenv("RC_DEBUG_PREFIX_MAP"))
2949 llvm::ExceptionHandling
Darwin::GetExceptionModel(const ArgList
&Args
) const {
2950 // Darwin uses SjLj exceptions on ARM.
2951 if (getTriple().getArch() != llvm::Triple::arm
&&
2952 getTriple().getArch() != llvm::Triple::thumb
)
2953 return llvm::ExceptionHandling::None
;
2955 // Only watchOS uses the new DWARF/Compact unwinding method.
2956 llvm::Triple
Triple(ComputeLLVMTriple(Args
));
2957 if (Triple
.isWatchABI())
2958 return llvm::ExceptionHandling::DwarfCFI
;
2960 return llvm::ExceptionHandling::SjLj
;
2963 bool Darwin::SupportsEmbeddedBitcode() const {
2964 assert(TargetInitialized
&& "Target not initialized!");
2965 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
2970 bool MachO::isPICDefault() const { return true; }
2972 bool MachO::isPIEDefault(const llvm::opt::ArgList
&Args
) const { return false; }
2974 bool MachO::isPICDefaultForced() const {
2975 return (getArch() == llvm::Triple::x86_64
||
2976 getArch() == llvm::Triple::aarch64
);
2979 bool MachO::SupportsProfiling() const {
2980 // Profiling instrumentation is only supported on x86.
2981 return getTriple().isX86();
2984 void Darwin::addMinVersionArgs(const ArgList
&Args
,
2985 ArgStringList
&CmdArgs
) const {
2986 VersionTuple TargetVersion
= getTripleTargetVersion();
2988 if (isTargetWatchOS())
2989 CmdArgs
.push_back("-watchos_version_min");
2990 else if (isTargetWatchOSSimulator())
2991 CmdArgs
.push_back("-watchos_simulator_version_min");
2992 else if (isTargetTvOS())
2993 CmdArgs
.push_back("-tvos_version_min");
2994 else if (isTargetTvOSSimulator())
2995 CmdArgs
.push_back("-tvos_simulator_version_min");
2996 else if (isTargetDriverKit())
2997 CmdArgs
.push_back("-driverkit_version_min");
2998 else if (isTargetIOSSimulator())
2999 CmdArgs
.push_back("-ios_simulator_version_min");
3000 else if (isTargetIOSBased())
3001 CmdArgs
.push_back("-iphoneos_version_min");
3002 else if (isTargetMacCatalyst())
3003 CmdArgs
.push_back("-maccatalyst_version_min");
3005 assert(isTargetMacOS() && "unexpected target");
3006 CmdArgs
.push_back("-macosx_version_min");
3009 VersionTuple MinTgtVers
= getEffectiveTriple().getMinimumSupportedOSVersion();
3010 if (!MinTgtVers
.empty() && MinTgtVers
> TargetVersion
)
3011 TargetVersion
= MinTgtVers
;
3012 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3013 if (TargetVariantTriple
) {
3014 assert(isTargetMacOSBased() && "unexpected target");
3015 VersionTuple VariantTargetVersion
;
3016 if (TargetVariantTriple
->isMacOSX()) {
3017 CmdArgs
.push_back("-macosx_version_min");
3018 TargetVariantTriple
->getMacOSXVersion(VariantTargetVersion
);
3020 assert(TargetVariantTriple
->isiOS() &&
3021 TargetVariantTriple
->isMacCatalystEnvironment() &&
3022 "unexpected target variant triple");
3023 CmdArgs
.push_back("-maccatalyst_version_min");
3024 VariantTargetVersion
= TargetVariantTriple
->getiOSVersion();
3026 VersionTuple MinTgtVers
=
3027 TargetVariantTriple
->getMinimumSupportedOSVersion();
3028 if (MinTgtVers
.getMajor() && MinTgtVers
> VariantTargetVersion
)
3029 VariantTargetVersion
= MinTgtVers
;
3030 CmdArgs
.push_back(Args
.MakeArgString(VariantTargetVersion
.getAsString()));
3034 static const char *getPlatformName(Darwin::DarwinPlatformKind Platform
,
3035 Darwin::DarwinEnvironmentKind Environment
) {
3039 case Darwin::IPhoneOS
:
3040 if (Environment
== Darwin::MacCatalyst
)
3041 return "mac catalyst";
3045 case Darwin::WatchOS
:
3047 case Darwin::DriverKit
:
3050 llvm_unreachable("invalid platform");
3053 void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList
&Args
,
3054 llvm::opt::ArgStringList
&CmdArgs
) const {
3055 auto EmitPlatformVersionArg
=
3056 [&](const VersionTuple
&TV
, Darwin::DarwinPlatformKind TargetPlatform
,
3057 Darwin::DarwinEnvironmentKind TargetEnvironment
,
3058 const llvm::Triple
&TT
) {
3059 // -platform_version <platform> <target_version> <sdk_version>
3060 // Both the target and SDK version support only up to 3 components.
3061 CmdArgs
.push_back("-platform_version");
3062 std::string PlatformName
=
3063 getPlatformName(TargetPlatform
, TargetEnvironment
);
3064 if (TargetEnvironment
== Darwin::Simulator
)
3065 PlatformName
+= "-simulator";
3066 CmdArgs
.push_back(Args
.MakeArgString(PlatformName
));
3067 VersionTuple TargetVersion
= TV
.withoutBuild();
3068 if ((TargetPlatform
== Darwin::IPhoneOS
||
3069 TargetPlatform
== Darwin::TvOS
) &&
3070 getTriple().getArchName() == "arm64e" &&
3071 TargetVersion
.getMajor() < 14) {
3072 // arm64e slice is supported on iOS/tvOS 14+ only.
3073 TargetVersion
= VersionTuple(14, 0);
3075 VersionTuple MinTgtVers
= TT
.getMinimumSupportedOSVersion();
3076 if (!MinTgtVers
.empty() && MinTgtVers
> TargetVersion
)
3077 TargetVersion
= MinTgtVers
;
3078 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3080 if (TargetPlatform
== IPhoneOS
&& TargetEnvironment
== MacCatalyst
) {
3081 // Mac Catalyst programs must use the appropriate iOS SDK version
3082 // that corresponds to the macOS SDK version used for the compilation.
3083 Optional
<VersionTuple
> iOSSDKVersion
;
3085 if (const auto *MacOStoMacCatalystMapping
=
3086 SDKInfo
->getVersionMapping(
3087 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
3088 iOSSDKVersion
= MacOStoMacCatalystMapping
->map(
3089 SDKInfo
->getVersion().withoutBuild(),
3090 minimumMacCatalystDeploymentTarget(), None
);
3093 CmdArgs
.push_back(Args
.MakeArgString(
3094 (iOSSDKVersion
? *iOSSDKVersion
3095 : minimumMacCatalystDeploymentTarget())
3101 VersionTuple SDKVersion
= SDKInfo
->getVersion().withoutBuild();
3102 CmdArgs
.push_back(Args
.MakeArgString(SDKVersion
.getAsString()));
3104 // Use an SDK version that's matching the deployment target if the SDK
3105 // version is missing. This is preferred over an empty SDK version
3106 // (0.0.0) as the system's runtime might expect the linked binary to
3107 // contain a valid SDK version in order for the binary to work
3108 // correctly. It's reasonable to use the deployment target version as
3109 // a proxy for the SDK version because older SDKs don't guarantee
3110 // support for deployment targets newer than the SDK versions, so that
3111 // rules out using some predetermined older SDK version, which leaves
3112 // the deployment target version as the only reasonable choice.
3113 CmdArgs
.push_back(Args
.MakeArgString(TargetVersion
.getAsString()));
3116 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform
,
3117 TargetEnvironment
, getEffectiveTriple());
3118 if (!TargetVariantTriple
)
3120 Darwin::DarwinPlatformKind Platform
;
3121 Darwin::DarwinEnvironmentKind Environment
;
3122 VersionTuple TargetVariantVersion
;
3123 if (TargetVariantTriple
->isMacOSX()) {
3124 TargetVariantTriple
->getMacOSXVersion(TargetVariantVersion
);
3125 Platform
= Darwin::MacOS
;
3126 Environment
= Darwin::NativeEnvironment
;
3128 assert(TargetVariantTriple
->isiOS() &&
3129 TargetVariantTriple
->isMacCatalystEnvironment() &&
3130 "unexpected target variant triple");
3131 TargetVariantVersion
= TargetVariantTriple
->getiOSVersion();
3132 Platform
= Darwin::IPhoneOS
;
3133 Environment
= Darwin::MacCatalyst
;
3135 EmitPlatformVersionArg(TargetVariantVersion
, Platform
, Environment
,
3136 *TargetVariantTriple
);
3139 // Add additional link args for the -dynamiclib option.
3140 static void addDynamicLibLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3141 ArgStringList
&CmdArgs
) {
3142 // Derived from darwin_dylib1 spec.
3143 if (D
.isTargetIPhoneOS()) {
3144 if (D
.isIPhoneOSVersionLT(3, 1))
3145 CmdArgs
.push_back("-ldylib1.o");
3149 if (!D
.isTargetMacOS())
3151 if (D
.isMacosxVersionLT(10, 5))
3152 CmdArgs
.push_back("-ldylib1.o");
3153 else if (D
.isMacosxVersionLT(10, 6))
3154 CmdArgs
.push_back("-ldylib1.10.5.o");
3157 // Add additional link args for the -bundle option.
3158 static void addBundleLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3159 ArgStringList
&CmdArgs
) {
3160 if (Args
.hasArg(options::OPT_static
))
3162 // Derived from darwin_bundle1 spec.
3163 if ((D
.isTargetIPhoneOS() && D
.isIPhoneOSVersionLT(3, 1)) ||
3164 (D
.isTargetMacOS() && D
.isMacosxVersionLT(10, 6)))
3165 CmdArgs
.push_back("-lbundle1.o");
3168 // Add additional link args for the -pg option.
3169 static void addPgProfilingLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3170 ArgStringList
&CmdArgs
) {
3171 if (D
.isTargetMacOS() && D
.isMacosxVersionLT(10, 9)) {
3172 if (Args
.hasArg(options::OPT_static
) || Args
.hasArg(options::OPT_object
) ||
3173 Args
.hasArg(options::OPT_preload
)) {
3174 CmdArgs
.push_back("-lgcrt0.o");
3176 CmdArgs
.push_back("-lgcrt1.o");
3178 // darwin_crt2 spec is empty.
3180 // By default on OS X 10.8 and later, we don't link with a crt1.o
3181 // file and the linker knows to use _main as the entry point. But,
3182 // when compiling with -pg, we need to link with the gcrt1.o file,
3183 // so pass the -no_new_main option to tell the linker to use the
3184 // "start" symbol as the entry point.
3185 if (!D
.isMacosxVersionLT(10, 8))
3186 CmdArgs
.push_back("-no_new_main");
3188 D
.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin
)
3189 << D
.isTargetMacOSBased();
3193 static void addDefaultCRTLinkArgs(const Darwin
&D
, const ArgList
&Args
,
3194 ArgStringList
&CmdArgs
) {
3195 // Derived from darwin_crt1 spec.
3196 if (D
.isTargetIPhoneOS()) {
3197 if (D
.getArch() == llvm::Triple::aarch64
)
3198 ; // iOS does not need any crt1 files for arm64
3199 else if (D
.isIPhoneOSVersionLT(3, 1))
3200 CmdArgs
.push_back("-lcrt1.o");
3201 else if (D
.isIPhoneOSVersionLT(6, 0))
3202 CmdArgs
.push_back("-lcrt1.3.1.o");
3206 if (!D
.isTargetMacOS())
3208 if (D
.isMacosxVersionLT(10, 5))
3209 CmdArgs
.push_back("-lcrt1.o");
3210 else if (D
.isMacosxVersionLT(10, 6))
3211 CmdArgs
.push_back("-lcrt1.10.5.o");
3212 else if (D
.isMacosxVersionLT(10, 8))
3213 CmdArgs
.push_back("-lcrt1.10.6.o");
3214 // darwin_crt2 spec is empty.
3217 void Darwin::addStartObjectFileArgs(const ArgList
&Args
,
3218 ArgStringList
&CmdArgs
) const {
3219 // Derived from startfile spec.
3220 if (Args
.hasArg(options::OPT_dynamiclib
))
3221 addDynamicLibLinkArgs(*this, Args
, CmdArgs
);
3222 else if (Args
.hasArg(options::OPT_bundle
))
3223 addBundleLinkArgs(*this, Args
, CmdArgs
);
3224 else if (Args
.hasArg(options::OPT_pg
) && SupportsProfiling())
3225 addPgProfilingLinkArgs(*this, Args
, CmdArgs
);
3226 else if (Args
.hasArg(options::OPT_static
) ||
3227 Args
.hasArg(options::OPT_object
) ||
3228 Args
.hasArg(options::OPT_preload
))
3229 CmdArgs
.push_back("-lcrt0.o");
3231 addDefaultCRTLinkArgs(*this, Args
, CmdArgs
);
3233 if (isTargetMacOS() && Args
.hasArg(options::OPT_shared_libgcc
) &&
3234 isMacosxVersionLT(10, 5)) {
3235 const char *Str
= Args
.MakeArgString(GetFilePath("crt3.o"));
3236 CmdArgs
.push_back(Str
);
3240 void Darwin::CheckObjCARC() const {
3241 if (isTargetIOSBased() || isTargetWatchOSBased() ||
3242 (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)))
3244 getDriver().Diag(diag::err_arc_unsupported_on_toolchain
);
3247 SanitizerMask
Darwin::getSupportedSanitizers() const {
3248 const bool IsX86_64
= getTriple().getArch() == llvm::Triple::x86_64
;
3249 const bool IsAArch64
= getTriple().getArch() == llvm::Triple::aarch64
;
3250 SanitizerMask Res
= ToolChain::getSupportedSanitizers();
3251 Res
|= SanitizerKind::Address
;
3252 Res
|= SanitizerKind::PointerCompare
;
3253 Res
|= SanitizerKind::PointerSubtract
;
3254 Res
|= SanitizerKind::Leak
;
3255 Res
|= SanitizerKind::Fuzzer
;
3256 Res
|= SanitizerKind::FuzzerNoLink
;
3257 Res
|= SanitizerKind::Function
;
3258 Res
|= SanitizerKind::ObjCCast
;
3260 // Prior to 10.9, macOS shipped a version of the C++ standard library without
3261 // C++11 support. The same is true of iOS prior to version 5. These OS'es are
3262 // incompatible with -fsanitize=vptr.
3263 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
3264 !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
3265 Res
|= SanitizerKind::Vptr
;
3267 if ((IsX86_64
|| IsAArch64
) && isTargetMacOSBased()) {
3268 Res
|= SanitizerKind::Thread
;
3269 } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
3271 Res
|= SanitizerKind::Thread
;
3276 void Darwin::printVerboseInfo(raw_ostream
&OS
) const {
3277 CudaInstallation
.print(OS
);
3278 RocmInstallation
.print(OS
);