clang 23.0.0git
Darwin.cpp
Go to the documentation of this file.
1//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Darwin.h"
10#include "Arch/ARM.h"
13#include "clang/Config/config.h"
16#include "clang/Driver/Driver.h"
19#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Option/ArgList.h"
21#include "llvm/ProfileData/InstrProf.h"
22#include "llvm/ProfileData/MemProf.h"
23#include "llvm/Support/Path.h"
24#include "llvm/Support/Threading.h"
25#include "llvm/Support/VirtualFileSystem.h"
26#include "llvm/TargetParser/TargetParser.h"
27#include "llvm/TargetParser/Triple.h"
28#include <cstdlib> // ::getenv
29
30#ifdef CLANG_USE_XCSELECT
31#include <xcselect.h> // ::xcselect_host_sdk_path
32#endif
33
34using namespace clang::driver;
35using namespace clang::driver::tools;
36using namespace clang::driver::toolchains;
37using namespace clang;
38using namespace llvm::opt;
39
41 return VersionTuple(13, 1);
42}
43
44llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
45 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
46 // archs which Darwin doesn't use.
47
48 // The matching this routine does is fairly pointless, since it is neither the
49 // complete architecture list, nor a reasonable subset. The problem is that
50 // historically the driver accepts this and also ties its -march=
51 // handling to the architecture name, so we need to be careful before removing
52 // support for it.
53
54 // This code must be kept in sync with Clang's Darwin specific argument
55 // translation.
56
57 return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
58 .Cases({"i386", "i486", "i486SX", "i586", "i686"}, llvm::Triple::x86)
59 .Cases({"pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4"},
60 llvm::Triple::x86)
61 .Cases({"x86_64", "x86_64h"}, llvm::Triple::x86_64)
62 // This is derived from the 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({"armv8m.base", "armv8m.main", "armv8.1m.main"}, llvm::Triple::arm)
67 .Cases({"arm64", "arm64e"}, llvm::Triple::aarch64)
68 .Case("arm64_32", llvm::Triple::aarch64_32)
69 .Case("r600", llvm::Triple::r600)
70 .Case("amdgcn", llvm::Triple::amdgcn)
71 .Case("nvptx", llvm::Triple::nvptx)
72 .Case("nvptx64", llvm::Triple::nvptx64)
73 .Case("amdil", llvm::Triple::amdil)
74 .Case("spir", llvm::Triple::spir)
75 .Default(llvm::Triple::UnknownArch);
76}
77
78void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str,
79 const ArgList &Args) {
80 const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
81 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str);
82 T.setArch(Arch);
83 if (Arch != llvm::Triple::UnknownArch)
84 T.setArchName(Str);
85
86 // Standalone/bare metal compiles often unintentionally come out as
87 // armv6m-apple-ios (-target not specified, or set from Xcode). Change these
88 // cases to armv6m-apple-unknown-macho to better reflect intent.
89 if ((T.getOS() != llvm::Triple::Firmware) &&
90 (ArchKind == llvm::ARM::ArchKind::ARMV6M ||
91 ArchKind == llvm::ARM::ArchKind::ARMV7M ||
92 ArchKind == llvm::ARM::ArchKind::ARMV7EM ||
93 ArchKind == llvm::ARM::ArchKind::ARMV8MBaseline ||
94 ArchKind == llvm::ARM::ArchKind::ARMV8MMainline ||
95 ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline)) {
96 // Don't reject these -version-min= if we have the appropriate triple.
97 if (T.getOS() == llvm::Triple::IOS)
98 for (Arg *A : Args.filtered(options::OPT_mios_version_min_EQ))
99 A->ignoreTargetSpecific();
100 if (T.getOS() == llvm::Triple::WatchOS)
101 for (Arg *A : Args.filtered(options::OPT_mwatchos_version_min_EQ))
102 A->ignoreTargetSpecific();
103 if (T.getOS() == llvm::Triple::TvOS)
104 for (Arg *A : Args.filtered(options::OPT_mtvos_version_min_EQ))
105 A->ignoreTargetSpecific();
106
107 T.setOS(llvm::Triple::UnknownOS);
108 T.setObjectFormat(llvm::Triple::MachO);
109 }
110}
111
113 const InputInfo &Output,
114 const InputInfoList &Inputs,
115 const ArgList &Args,
116 const char *LinkingOutput) const {
117 const llvm::Triple &T(getToolChain().getTriple());
118
119 ArgStringList CmdArgs;
120
121 assert(Inputs.size() == 1 && "Unexpected number of inputs.");
122 const InputInfo &Input = Inputs[0];
123
124 // Determine the original source input.
125 const Action *SourceAction = &JA;
126 while (SourceAction->getKind() != Action::InputClass) {
127 assert(!SourceAction->getInputs().empty() && "unexpected root action!");
128 SourceAction = SourceAction->getInputs()[0];
129 }
130
131 // If -fno-integrated-as is used add -Q to the darwin assembler driver to make
132 // sure it runs its system assembler not clang's integrated assembler.
133 // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as.
134 // FIXME: at run-time detect assembler capabilities or rely on version
135 // information forwarded by -target-assembler-version.
136 if (Args.hasArg(options::OPT_fno_integrated_as)) {
137 if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
138 CmdArgs.push_back("-Q");
139 }
140
141 // Forward -g, assuming we are dealing with an actual assembly file.
142 if (SourceAction->getType() == types::TY_Asm ||
143 SourceAction->getType() == types::TY_PP_Asm) {
144 if (Args.hasArg(options::OPT_gstabs))
145 CmdArgs.push_back("--gstabs");
146 else if (Args.hasArg(options::OPT_g_Group))
147 CmdArgs.push_back("-g");
148 }
149
150 // Derived from asm spec.
151 AddMachOArch(Args, CmdArgs);
152
153 // Use -force_cpusubtype_ALL on x86 by default.
154 if (T.isX86() || Args.hasArg(options::OPT_force__cpusubtype__ALL))
155 CmdArgs.push_back("-force_cpusubtype_ALL");
156
157 if (getToolChain().getArch() != llvm::Triple::x86_64 &&
158 (((Args.hasArg(options::OPT_mkernel) ||
159 Args.hasArg(options::OPT_fapple_kext)) &&
160 getMachOToolChain().isKernelStatic()) ||
161 Args.hasArg(options::OPT_static)))
162 CmdArgs.push_back("-static");
163
164 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
165
166 assert(Output.isFilename() && "Unexpected lipo output.");
167 CmdArgs.push_back("-o");
168 CmdArgs.push_back(Output.getFilename());
169
170 assert(Input.isFilename() && "Invalid input.");
171 CmdArgs.push_back(Input.getFilename());
172
173 // asm_final spec is empty.
174
175 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
176 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
177 Exec, CmdArgs, Inputs, Output));
178}
179
180void darwin::MachOTool::anchor() {}
181
182void darwin::MachOTool::AddMachOArch(const ArgList &Args,
183 ArgStringList &CmdArgs) const {
184 StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
185
186 // Derived from darwin_arch spec.
187 CmdArgs.push_back("-arch");
188 CmdArgs.push_back(Args.MakeArgString(ArchName));
189
190 // FIXME: Is this needed anymore?
191 if (ArchName == "arm")
192 CmdArgs.push_back("-force_cpusubtype_ALL");
193}
194
195bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {
196 // We only need to generate a temp path for LTO if we aren't compiling object
197 // files. When compiling source files, we run 'dsymutil' after linking. We
198 // don't run 'dsymutil' when compiling object files.
199 for (const auto &Input : Inputs)
200 if (Input.getType() != types::TY_Object)
201 return true;
202
203 return false;
204}
205
206/// Pass -no_deduplicate to ld64 under certain conditions:
207///
208/// - Either -O0 or -O1 is explicitly specified
209/// - No -O option is specified *and* this is a compile+link (implicit -O0)
210///
211/// Also do *not* add -no_deduplicate when no -O option is specified and this
212/// is just a link (we can't imply -O0)
213static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
214 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
215 if (A->getOption().matches(options::OPT_O0))
216 return true;
217 if (A->getOption().matches(options::OPT_O))
218 return llvm::StringSwitch<bool>(A->getValue())
219 .Case("1", true)
220 .Default(false);
221 return false; // OPT_Ofast & OPT_O4
222 }
223
224 if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.
225 return true;
226 return false;
227}
228
229void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
230 ArgStringList &CmdArgs,
231 const InputInfoList &Inputs,
232 VersionTuple Version, bool LinkerIsLLD,
233 bool UsePlatformVersion) const {
234 const Driver &D = getToolChain().getDriver();
235 const toolchains::MachO &MachOTC = getMachOToolChain();
236
237 // Newer linkers support -demangle. Pass it if supported and not disabled by
238 // the user.
239 if ((Version >= VersionTuple(100) || LinkerIsLLD) &&
240 !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
241 CmdArgs.push_back("-demangle");
242
243 if (Args.hasArg(options::OPT_rdynamic) &&
244 (Version >= VersionTuple(137) || LinkerIsLLD))
245 CmdArgs.push_back("-export_dynamic");
246
247 // If we are using App Extension restrictions, pass a flag to the linker
248 // telling it that the compiled code has been audited.
249 if (Args.hasFlag(options::OPT_fapplication_extension,
250 options::OPT_fno_application_extension, false))
251 CmdArgs.push_back("-application_extension");
252
253 if (D.isUsingLTO() && (Version >= VersionTuple(116) || LinkerIsLLD) &&
254 NeedsTempPath(Inputs)) {
255 std::string TmpPathName;
256 if (D.getLTOMode() == LTOK_Full) {
257 // If we are using full LTO, then automatically create a temporary file
258 // path for the linker to use, so that it's lifetime will extend past a
259 // possible dsymutil step.
260 TmpPathName =
261 D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object));
262 } else if (D.getLTOMode() == LTOK_Thin)
263 // If we are using thin LTO, then create a directory instead.
264 TmpPathName = D.GetTemporaryDirectory("thinlto");
265
266 if (!TmpPathName.empty()) {
267 auto *TmpPath = C.getArgs().MakeArgString(TmpPathName);
268 C.addTempFile(TmpPath);
269 CmdArgs.push_back("-object_path_lto");
270 CmdArgs.push_back(TmpPath);
271 }
272 }
273
274 // Use -lto_library option to specify the libLTO.dylib path. Try to find
275 // it in clang installed libraries. ld64 will only look at this argument
276 // when it actually uses LTO, so libLTO.dylib only needs to exist at link
277 // time if ld64 decides that it needs to use LTO.
278 // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
279 // next to it. That's ok since ld64 using a libLTO.dylib not matching the
280 // clang version won't work anyways.
281 // lld is built at the same revision as clang and statically links in
282 // LLVM libraries, so it doesn't need libLTO.dylib.
283 if (Version >= VersionTuple(133) && !LinkerIsLLD) {
284 // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
285 StringRef P = llvm::sys::path::parent_path(D.Dir);
286 SmallString<128> LibLTOPath(P);
287 llvm::sys::path::append(LibLTOPath, "lib");
288 llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
289 CmdArgs.push_back("-lto_library");
290 CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
291 }
292
293 // ld64 version 262 and above runs the deduplicate pass by default.
294 // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe`
295 // if `!shouldLinkerNotDedup()` if LinkerIsLLD here?
296 if (Version >= VersionTuple(262) &&
297 shouldLinkerNotDedup(C.getJobs().empty(), Args))
298 CmdArgs.push_back("-no_deduplicate");
299
300 // Derived from the "link" spec.
301 Args.AddAllArgs(CmdArgs, options::OPT_static);
302 if (!Args.hasArg(options::OPT_static))
303 CmdArgs.push_back("-dynamic");
304 if (Args.hasArg(options::OPT_fgnu_runtime)) {
305 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
306 // here. How do we wish to handle such things?
307 }
308
309 if (!Args.hasArg(options::OPT_dynamiclib)) {
310 AddMachOArch(Args, CmdArgs);
311 // FIXME: Why do this only on this path?
312 Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
313
314 Args.AddLastArg(CmdArgs, options::OPT_bundle);
315 Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
316 Args.AddAllArgs(CmdArgs, options::OPT_client__name);
317
318 Arg *A;
319 if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
320 (A = Args.getLastArg(options::OPT_current__version)) ||
321 (A = Args.getLastArg(options::OPT_install__name)))
322 D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
323 << "-dynamiclib";
324
325 Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
326 Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
327 Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
328 } else {
329 CmdArgs.push_back("-dylib");
330
331 Arg *A;
332 if ((A = Args.getLastArg(options::OPT_bundle)) ||
333 (A = Args.getLastArg(options::OPT_bundle__loader)) ||
334 (A = Args.getLastArg(options::OPT_client__name)) ||
335 (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
336 (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
337 (A = Args.getLastArg(options::OPT_private__bundle)))
338 D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
339 << "-dynamiclib";
340
341 Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
342 "-dylib_compatibility_version");
343 Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
344 "-dylib_current_version");
345
346 AddMachOArch(Args, CmdArgs);
347
348 Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
349 "-dylib_install_name");
350 }
351
352 Args.AddLastArg(CmdArgs, options::OPT_all__load);
353 Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
354 Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
355 if (MachOTC.isTargetIOSBased())
356 Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
357 Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
358 Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
359 Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
360 Args.AddLastArg(CmdArgs, options::OPT_dynamic);
361 Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
362 Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
363 Args.AddAllArgs(CmdArgs, options::OPT_force__load);
364 Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
365 Args.AddAllArgs(CmdArgs, options::OPT_image__base);
366 Args.AddAllArgs(CmdArgs, options::OPT_init);
367
368 // Add the deployment target.
369 if (Version >= VersionTuple(520) || LinkerIsLLD || UsePlatformVersion)
370 MachOTC.addPlatformVersionArgs(Args, CmdArgs);
371 else
372 MachOTC.addMinVersionArgs(Args, CmdArgs);
373
374 Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
375 Args.AddLastArg(CmdArgs, options::OPT_multi__module);
376 Args.AddLastArg(CmdArgs, options::OPT_single__module);
377 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
378 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
379
380 if (const Arg *A =
381 Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
382 options::OPT_fno_pie, options::OPT_fno_PIE)) {
383 if (A->getOption().matches(options::OPT_fpie) ||
384 A->getOption().matches(options::OPT_fPIE))
385 CmdArgs.push_back("-pie");
386 else
387 CmdArgs.push_back("-no_pie");
388 }
389
390 // for embed-bitcode, use -bitcode_bundle in linker command
391 if (C.getDriver().embedBitcodeEnabled()) {
392 // Check if the toolchain supports bitcode build flow.
393 if (MachOTC.SupportsEmbeddedBitcode()) {
394 CmdArgs.push_back("-bitcode_bundle");
395 // FIXME: Pass this if LinkerIsLLD too, once it implements this flag.
396 if (C.getDriver().embedBitcodeMarkerOnly() &&
397 Version >= VersionTuple(278)) {
398 CmdArgs.push_back("-bitcode_process_mode");
399 CmdArgs.push_back("marker");
400 }
401 } else
402 D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
403 }
404
405 // If GlobalISel is enabled, pass it through to LLVM.
406 if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
407 options::OPT_fno_global_isel)) {
408 if (A->getOption().matches(options::OPT_fglobal_isel)) {
409 CmdArgs.push_back("-mllvm");
410 CmdArgs.push_back("-global-isel");
411 // Disable abort and fall back to SDAG silently.
412 CmdArgs.push_back("-mllvm");
413 CmdArgs.push_back("-global-isel-abort=0");
414 }
415 }
416
417 if (Args.hasArg(options::OPT_mkernel) ||
418 Args.hasArg(options::OPT_fapple_kext) ||
419 Args.hasArg(options::OPT_ffreestanding)) {
420 CmdArgs.push_back("-mllvm");
421 CmdArgs.push_back("-disable-atexit-based-global-dtor-lowering");
422 }
423
424 Args.AddLastArg(CmdArgs, options::OPT_prebind);
425 Args.AddLastArg(CmdArgs, options::OPT_noprebind);
426 Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
427 Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
428 Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
429 Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
430 Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
431 Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
432 Args.AddAllArgs(CmdArgs, options::OPT_segprot);
433 Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
434 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
435 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
436 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
437 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
438 Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
439 Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
440
441 // Give --sysroot= preference, over the Apple specific behavior to also use
442 // --isysroot as the syslibroot.
443 // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we
444 // prioritise command line arguments over configuration of `DEFAULT_SYSROOT`.
445 if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) {
446 CmdArgs.push_back("-syslibroot");
447 CmdArgs.push_back(A->getValue());
448 } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
449 CmdArgs.push_back("-syslibroot");
450 CmdArgs.push_back(A->getValue());
451 } else if (StringRef sysroot = C.getSysRoot(); sysroot != "") {
452 CmdArgs.push_back("-syslibroot");
453 CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
454 }
455
456 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
457 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
458 Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
459 Args.AddAllArgs(CmdArgs, options::OPT_undefined);
460 Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
461 Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
462 Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
463 Args.AddAllArgs(CmdArgs, options::OPT_y);
464 Args.AddLastArg(CmdArgs, options::OPT_w);
465 Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
466 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
467 Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
468 Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
469 Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
470 Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
471 Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
472 Args.AddLastArg(CmdArgs, options::OPT_why_load);
473 Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
474 Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
475 Args.AddLastArg(CmdArgs, options::OPT_dylinker);
476 Args.AddLastArg(CmdArgs, options::OPT_Mach);
477
478 if (LinkerIsLLD) {
479 if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {
480 SmallString<128> Path(CSPGOGenerateArg->getNumValues() == 0
481 ? ""
482 : CSPGOGenerateArg->getValue());
483 llvm::sys::path::append(Path, "default_%m.profraw");
484 CmdArgs.push_back("--cs-profile-generate");
485 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));
486 } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {
487 SmallString<128> Path(
488 ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
489 if (Path.empty() || llvm::sys::fs::is_directory(Path))
490 llvm::sys::path::append(Path, "default.profdata");
491 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));
492 }
493
494 auto *CodeGenDataGenArg =
495 Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
496 if (CodeGenDataGenArg)
497 CmdArgs.push_back(
498 Args.MakeArgString(Twine("--codegen-data-generate-path=") +
499 CodeGenDataGenArg->getValue()));
500 } else {
501 if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {
502 SmallString<128> Path(CSPGOGenerateArg->getNumValues() == 0
503 ? ""
504 : CSPGOGenerateArg->getValue());
505 llvm::sys::path::append(Path, "default_%m.profraw");
506 CmdArgs.push_back("-mllvm");
507 CmdArgs.push_back("-cs-profile-generate");
508 CmdArgs.push_back("-mllvm");
509 CmdArgs.push_back(Args.MakeArgString(Twine("-cs-profile-path=") + Path));
510 } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {
511 SmallString<128> Path(
512 ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
513 if (Path.empty() || llvm::sys::fs::is_directory(Path))
514 llvm::sys::path::append(Path, "default.profdata");
515 CmdArgs.push_back("-mllvm");
516 CmdArgs.push_back(Args.MakeArgString(Twine("-cs-profile-path=") + Path));
517 }
518 }
519}
520
521/// Determine whether we are linking the ObjC runtime.
522static bool isObjCRuntimeLinked(const ArgList &Args) {
523 if (isObjCAutoRefCount(Args)) {
524 Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
525 return true;
526 }
527 return Args.hasArg(options::OPT_fobjc_link_runtime);
528}
529
530static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
531 const llvm::Triple &Triple) {
532 // When enabling remarks, we need to error if:
533 // * The remark file is specified but we're targeting multiple architectures,
534 // which means more than one remark file is being generated.
536 Args.getAllArgValues(options::OPT_arch).size() > 1;
537 bool hasExplicitOutputFile =
538 Args.getLastArg(options::OPT_foptimization_record_file_EQ);
539 if (hasMultipleInvocations && hasExplicitOutputFile) {
540 D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
541 << "-foptimization-record-file";
542 return false;
543 }
544 return true;
545}
546
547static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
548 const llvm::Triple &Triple,
549 const InputInfo &Output, const JobAction &JA) {
550 StringRef Format = "yaml";
551 if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
552 Format = A->getValue();
553
554 CmdArgs.push_back("-mllvm");
555 CmdArgs.push_back("-lto-pass-remarks-output");
556 CmdArgs.push_back("-mllvm");
557
558 const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
559 if (A) {
560 CmdArgs.push_back(A->getValue());
561 } else {
562 assert(Output.isFilename() && "Unexpected ld output.");
564 F = Output.getFilename();
565 F += ".opt.";
566 F += Format;
567
568 CmdArgs.push_back(Args.MakeArgString(F));
569 }
570
571 if (const Arg *A =
572 Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
573 CmdArgs.push_back("-mllvm");
574 std::string Passes =
575 std::string("-lto-pass-remarks-filter=") + A->getValue();
576 CmdArgs.push_back(Args.MakeArgString(Passes));
577 }
578
579 if (!Format.empty()) {
580 CmdArgs.push_back("-mllvm");
581 Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format;
582 CmdArgs.push_back(Args.MakeArgString(FormatArg));
583 }
584
585 if (getLastProfileUseArg(Args)) {
586 CmdArgs.push_back("-mllvm");
587 CmdArgs.push_back("-lto-pass-remarks-with-hotness");
588
589 if (const Arg *A =
590 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
591 CmdArgs.push_back("-mllvm");
592 std::string Opt =
593 std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue();
594 CmdArgs.push_back(Args.MakeArgString(Opt));
595 }
596 }
597}
598
600 const InputInfo &Output,
601 const InputInfoList &Inputs,
602 const ArgList &Args,
603 const char *LinkingOutput) const {
604 assert((Output.getType() == types::TY_Image ||
605 Output.getType() == types::TY_Object) &&
606 "Invalid linker output type.");
607
608 // If the number of arguments surpasses the system limits, we will encode the
609 // input files in a separate file, shortening the command line. To this end,
610 // build a list of input file names that can be passed via a file with the
611 // -filelist linker option.
612 llvm::opt::ArgStringList InputFileList;
613
614 // The logic here is derived from gcc's behavior; most of which
615 // comes from specs (starting with link_command). Consult gcc for
616 // more information.
617 ArgStringList CmdArgs;
618
619 VersionTuple Version = getMachOToolChain().getLinkerVersion(Args);
620
621 bool LinkerIsLLD;
622 const char *Exec =
623 Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD));
624
625 // Newer triples always use -platform-version.
626 llvm::Triple Triple = getToolChain().getTriple();
627 bool UsePlatformVersion = Triple.isXROS() || Triple.isOSFirmware();
628
629 // I'm not sure why this particular decomposition exists in gcc, but
630 // we follow suite for ease of comparison.
631 AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD,
632 UsePlatformVersion);
633
634 if (willEmitRemarks(Args) &&
635 checkRemarksOptions(getToolChain().getDriver(), Args,
637 renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA);
638
639 // Propagate the -moutline flag to the linker in LTO.
640 if (Arg *A =
641 Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) {
642 if (A->getOption().matches(options::OPT_moutline)) {
643 if (getMachOToolChain().getMachOArchName(Args) == "arm64") {
644 CmdArgs.push_back("-mllvm");
645 CmdArgs.push_back("-enable-machine-outliner");
646 }
647 } else {
648 // Disable all outlining behaviour if we have mno-outline. We need to do
649 // this explicitly, because targets which support default outlining will
650 // try to do work if we don't.
651 CmdArgs.push_back("-mllvm");
652 CmdArgs.push_back("-enable-machine-outliner=never");
653 }
654 }
655
656 // Outline from linkonceodr functions by default in LTO, whenever the outliner
657 // is enabled. Note that the target may enable the machine outliner
658 // independently of -moutline.
659 CmdArgs.push_back("-mllvm");
660 CmdArgs.push_back("-enable-linkonceodr-outlining");
661
662 // Propagate codegen data flags to the linker for the LLVM backend.
663 auto *CodeGenDataGenArg =
664 Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
665 auto *CodeGenDataUseArg = Args.getLastArg(options::OPT_fcodegen_data_use_EQ);
666
667 // We only allow one of them to be specified.
668 const Driver &D = getToolChain().getDriver();
669 if (CodeGenDataGenArg && CodeGenDataUseArg)
670 D.Diag(diag::err_drv_argument_not_allowed_with)
671 << CodeGenDataGenArg->getAsString(Args)
672 << CodeGenDataUseArg->getAsString(Args);
673
674 // For codegen data gen, the output file is passed to the linker
675 // while a boolean flag is passed to the LLVM backend.
676 if (CodeGenDataGenArg) {
677 CmdArgs.push_back("-mllvm");
678 CmdArgs.push_back("-codegen-data-generate");
679 }
680
681 // For codegen data use, the input file is passed to the LLVM backend.
682 if (CodeGenDataUseArg) {
683 CmdArgs.push_back("-mllvm");
684 CmdArgs.push_back(Args.MakeArgString(Twine("-codegen-data-use-path=") +
685 CodeGenDataUseArg->getValue()));
686 }
687
688 // Setup statistics file output.
689 SmallString<128> StatsFile =
690 getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());
691 if (!StatsFile.empty()) {
692 CmdArgs.push_back("-mllvm");
693 CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str()));
694 }
695
696 // Set up stack usage file path.
697 if (Args.hasArg(options::OPT_fstack_usage)) {
698 SmallString<128> StackUsageFile(Output.getFilename());
699 llvm::sys::path::replace_extension(StackUsageFile, "su");
700 CmdArgs.push_back("-mllvm");
701 CmdArgs.push_back(
702 Args.MakeArgString("-stack-usage-file=" + StackUsageFile));
703 }
704
705 // It seems that the 'e' option is completely ignored for dynamic executables
706 // (the default), and with static executables, the last one wins, as expected.
707 Args.addAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
708 options::OPT_Z_Flag, options::OPT_u_Group});
709
710 // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
711 // members of static archive libraries which implement Objective-C classes or
712 // categories.
713 if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
714 CmdArgs.push_back("-ObjC");
715
716 CmdArgs.push_back("-o");
717 CmdArgs.push_back(Output.getFilename());
718
719 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
720 getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
721
722 Args.AddAllArgs(CmdArgs, options::OPT_L);
723
724 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
725 // Build the input file for -filelist (list of linker input files) in case we
726 // need it later
727 for (const auto &II : Inputs) {
728 if (!II.isFilename()) {
729 // This is a linker input argument.
730 // We cannot mix input arguments and file names in a -filelist input, thus
731 // we prematurely stop our list (remaining files shall be passed as
732 // arguments).
733 if (InputFileList.size() > 0)
734 break;
735
736 continue;
737 }
738
739 InputFileList.push_back(II.getFilename());
740 }
741
742 // Additional linker set-up and flags for Fortran. This is required in order
743 // to generate executables.
744 if (getToolChain().getDriver().IsFlangMode() &&
745 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
746 getToolChain().addFortranRuntimeLibraryPath(Args, CmdArgs);
747 getToolChain().addFortranRuntimeLibs(Args, CmdArgs);
748 }
749
750 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
751 addOpenMPRuntime(C, CmdArgs, getToolChain(), Args);
752
753 if (isObjCRuntimeLinked(Args) &&
754 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
755 // We use arclite library for both ARC and subscripting support.
756 getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
757
758 CmdArgs.push_back("-framework");
759 CmdArgs.push_back("Foundation");
760 // Link libobj.
761 CmdArgs.push_back("-lobjc");
762 }
763
764 if (LinkingOutput) {
765 CmdArgs.push_back("-arch_multiple");
766 CmdArgs.push_back("-final_output");
767 CmdArgs.push_back(LinkingOutput);
768 }
769
770 if (Args.hasArg(options::OPT_fnested_functions))
771 CmdArgs.push_back("-allow_stack_execute");
772
773 getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
774
775 StringRef Parallelism = getLTOParallelism(Args, getToolChain().getDriver());
776 if (!Parallelism.empty()) {
777 CmdArgs.push_back("-mllvm");
778 unsigned NumThreads =
779 llvm::get_threadpool_strategy(Parallelism)->compute_thread_count();
780 CmdArgs.push_back(Args.MakeArgString("-threads=" + Twine(NumThreads)));
781 }
782
783 if (getToolChain().ShouldLinkCXXStdlib(Args))
784 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
785
786 bool NoStdOrDefaultLibs =
787 Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
788 bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib);
789 if (!NoStdOrDefaultLibs || ForceLinkBuiltins) {
790 // link_ssp spec is empty.
791
792 // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then
793 // we just want to link the builtins, not the other libs like libSystem.
794 if (NoStdOrDefaultLibs && ForceLinkBuiltins) {
795 getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins");
796 } else {
797 // Let the tool chain choose which runtime library to link.
798 getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs,
799 ForceLinkBuiltins);
800
801 // No need to do anything for pthreads. Claim argument to avoid warning.
802 Args.ClaimAllArgs(options::OPT_pthread);
803 Args.ClaimAllArgs(options::OPT_pthreads);
804 }
805 }
806
807 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
808 // endfile_spec is empty.
809 }
810
811 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
812 Args.AddAllArgs(CmdArgs, options::OPT_F);
813
814 // -iframework should be forwarded as -F.
815 for (const Arg *A : Args.filtered(options::OPT_iframework))
816 CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
817
818 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
819 if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
820 if (A->getValue() == StringRef("Accelerate")) {
821 CmdArgs.push_back("-framework");
822 CmdArgs.push_back("Accelerate");
823 }
824 }
825 }
826
827 // Add non-standard, platform-specific search paths, e.g., for DriverKit:
828 // -L<sysroot>/System/DriverKit/usr/lib
829 // -F<sysroot>/System/DriverKit/System/Library/Framework
830 {
831 bool NonStandardSearchPath = false;
832 const auto &Triple = getToolChain().getTriple();
833 if (Triple.isDriverKit()) {
834 // ld64 fixed the implicit -F and -L paths in ld64-605.1+.
835 NonStandardSearchPath =
836 Version.getMajor() < 605 ||
837 (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1);
838 } else {
839 NonStandardSearchPath = getMachOToolChain().HasPlatformPrefix(Triple);
840 }
841
842 if (NonStandardSearchPath) {
843 if (auto *Sysroot = Args.getLastArg(options::OPT_isysroot)) {
844 auto AddSearchPath = [&](StringRef Flag, StringRef SearchPath) {
845 SmallString<128> P(Sysroot->getValue());
846 getMachOToolChain().AppendPlatformPrefix(P, Triple);
847 llvm::sys::path::append(P, SearchPath);
848 if (getToolChain().getVFS().exists(P)) {
849 CmdArgs.push_back(Args.MakeArgString(Flag + P));
850 }
851 };
852 AddSearchPath("-L", "/usr/lib");
853 AddSearchPath("-F", "/System/Library/Frameworks");
854 }
855 }
856 }
857
858 ResponseFileSupport ResponseSupport;
859 if (Version >= VersionTuple(705) || LinkerIsLLD) {
860 ResponseSupport = ResponseFileSupport::AtFileUTF8();
861 } else {
862 // For older versions of the linker, use the legacy filelist method instead.
863 ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8,
864 "-filelist"};
865 }
866
867 std::unique_ptr<Command> Cmd = std::make_unique<Command>(
868 JA, *this, ResponseSupport, Exec, CmdArgs, Inputs, Output);
869 Cmd->setInputFileList(std::move(InputFileList));
870 C.addCommand(std::move(Cmd));
871}
872
874 const InputInfo &Output,
875 const InputInfoList &Inputs,
876 const ArgList &Args,
877 const char *LinkingOutput) const {
878 const Driver &D = getToolChain().getDriver();
879
880 // Silence warning for "clang -g foo.o -o foo"
881 Args.ClaimAllArgs(options::OPT_g_Group);
882 // and "clang -emit-llvm foo.o -o foo"
883 Args.ClaimAllArgs(options::OPT_emit_llvm);
884 // and for "clang -w foo.o -o foo". Other warning options are already
885 // handled somewhere else.
886 Args.ClaimAllArgs(options::OPT_w);
887 // Silence warnings when linking C code with a C++ '-stdlib' argument.
888 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
889
890 // libtool <options> <output_file> <input_files>
891 ArgStringList CmdArgs;
892 // Create and insert file members with a deterministic index.
893 CmdArgs.push_back("-static");
894 CmdArgs.push_back("-D");
895 CmdArgs.push_back("-no_warning_for_no_symbols");
896 CmdArgs.push_back("-o");
897 CmdArgs.push_back(Output.getFilename());
898
899 for (const auto &II : Inputs) {
900 if (II.isFilename()) {
901 CmdArgs.push_back(II.getFilename());
902 }
903 }
904
905 // Delete old output archive file if it already exists before generating a new
906 // archive file.
907 const auto *OutputFileName = Output.getFilename();
908 if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {
909 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
910 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
911 return;
912 }
913 }
914
915 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
916 C.addCommand(std::make_unique<Command>(JA, *this,
918 Exec, CmdArgs, Inputs, Output));
919}
920
922 const InputInfo &Output,
923 const InputInfoList &Inputs,
924 const ArgList &Args,
925 const char *LinkingOutput) const {
926 ArgStringList CmdArgs;
927
928 CmdArgs.push_back("-create");
929 assert(Output.isFilename() && "Unexpected lipo output.");
930
931 CmdArgs.push_back("-output");
932 CmdArgs.push_back(Output.getFilename());
933
934 for (const auto &II : Inputs) {
935 assert(II.isFilename() && "Unexpected lipo input.");
936 CmdArgs.push_back(II.getFilename());
937 }
938
939 StringRef LipoName = Args.getLastArgValue(options::OPT_fuse_lipo_EQ, "lipo");
940 const char *Exec =
941 Args.MakeArgString(getToolChain().GetProgramPath(LipoName.data()));
942 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
943 Exec, CmdArgs, Inputs, Output));
944}
945
947 const InputInfo &Output,
948 const InputInfoList &Inputs,
949 const ArgList &Args,
950 const char *LinkingOutput) const {
951 ArgStringList CmdArgs;
952
953 CmdArgs.push_back("-o");
954 CmdArgs.push_back(Output.getFilename());
955
956 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
957 const InputInfo &Input = Inputs[0];
958 assert(Input.isFilename() && "Unexpected dsymutil input.");
959 CmdArgs.push_back(Input.getFilename());
960
961 const char *Exec =
962 Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
963 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
964 Exec, CmdArgs, Inputs, Output));
965}
966
968 const InputInfo &Output,
969 const InputInfoList &Inputs,
970 const ArgList &Args,
971 const char *LinkingOutput) const {
972 ArgStringList CmdArgs;
973 CmdArgs.push_back("--verify");
974 CmdArgs.push_back("--debug-info");
975 CmdArgs.push_back("--eh-frame");
976 CmdArgs.push_back("--quiet");
977
978 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
979 const InputInfo &Input = Inputs[0];
980 assert(Input.isFilename() && "Unexpected verify input");
981
982 // Grabbing the output of the earlier dsymutil run.
983 CmdArgs.push_back(Input.getFilename());
984
985 const char *Exec =
986 Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
987 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
988 Exec, CmdArgs, Inputs, Output));
989}
990
991MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
992 : ToolChain(D, Triple, Args) {
993 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
994 getProgramPaths().push_back(getDriver().Dir);
995}
996
997AppleMachO::AppleMachO(const Driver &D, const llvm::Triple &Triple,
998 const ArgList &Args)
999 : MachO(D, Triple, Args), CudaInstallation(D, Triple, Args),
1000 RocmInstallation(D, Triple, Args), SYCLInstallation(D, Triple, Args) {}
1001
1002/// Darwin - Darwin tool chain for i386 and x86_64.
1003Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
1004 : AppleMachO(D, Triple, Args), TargetInitialized(false) {}
1005
1008
1009 // Darwin always preprocesses assembly files (unless -x is used explicitly).
1010 if (Ty == types::TY_PP_Asm)
1011 return types::TY_Asm;
1012
1013 return Ty;
1014}
1015
1016bool MachO::HasNativeLLVMSupport() const { return true; }
1017
1019 // Always use libc++ by default
1020 return ToolChain::CST_Libcxx;
1021}
1022
1023/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
1027 if (isTargetIOSBased())
1029 if (isTargetXROS()) {
1030 // XROS uses the iOS runtime.
1031 auto T = llvm::Triple(Twine("arm64-apple-") +
1032 llvm::Triple::getOSTypeName(llvm::Triple::XROS) +
1033 TargetVersion.getAsString());
1034 return ObjCRuntime(ObjCRuntime::iOS, T.getiOSVersion());
1035 }
1036 if (isNonFragile)
1039}
1040
1041/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
1044 return true;
1045 else if (isTargetFirmware())
1046 return false;
1047 else if (isTargetIOSBased())
1048 return !isIPhoneOSVersionLT(3, 2);
1049 else {
1050 assert(isTargetMacOSBased() && "unexpected darwin target");
1051 return !isMacosxVersionLT(10, 6);
1052 }
1053}
1054
1055void AppleMachO::AddCudaIncludeArgs(const ArgList &DriverArgs,
1056 ArgStringList &CC1Args) const {
1057 CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
1058}
1059
1060void AppleMachO::AddHIPIncludeArgs(const ArgList &DriverArgs,
1061 ArgStringList &CC1Args) const {
1062 RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
1063}
1064
1065void AppleMachO::addSYCLIncludeArgs(const ArgList &DriverArgs,
1066 ArgStringList &CC1Args) const {
1067 SYCLInstallation->addSYCLIncludeArgs(DriverArgs, CC1Args);
1068}
1069
1070// This is just a MachO name translation routine and there's no
1071// way to join this into ARMTargetParser without breaking all
1072// other assumptions. Maybe MachO should consider standardising
1073// their nomenclature.
1074static const char *ArmMachOArchName(StringRef Arch) {
1075 return llvm::StringSwitch<const char *>(Arch)
1076 .Case("armv6k", "armv6")
1077 .Case("armv6m", "armv6m")
1078 .Case("armv5tej", "armv5")
1079 .Case("xscale", "xscale")
1080 .Case("armv4t", "armv4t")
1081 .Case("armv7", "armv7")
1082 .Cases({"armv7a", "armv7-a"}, "armv7")
1083 .Cases({"armv7r", "armv7-r"}, "armv7")
1084 .Cases({"armv7em", "armv7e-m"}, "armv7em")
1085 .Cases({"armv7k", "armv7-k"}, "armv7k")
1086 .Cases({"armv7m", "armv7-m"}, "armv7m")
1087 .Cases({"armv7s", "armv7-s"}, "armv7s")
1088 .Cases({"armv8-m.base", "armv8m.base"}, "armv8m.base")
1089 .Cases({"armv8-m.main", "armv8m.main"}, "armv8m.main")
1090 .Cases({"armv8.1-m.main", "armv8m.main"}, "armv8.1m.main")
1091 .Default(nullptr);
1092}
1093
1094static const char *ArmMachOArchNameCPU(StringRef CPU) {
1095 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
1096 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1097 return nullptr;
1098 StringRef Arch = llvm::ARM::getArchName(ArchKind);
1099
1100 // FIXME: Make sure this MachO triple mangling is really necessary.
1101 // ARMv5* normalises to ARMv5.
1102 if (Arch.starts_with("armv5"))
1103 Arch = Arch.substr(0, 5);
1104 // ARMv6*, except ARMv6M, normalises to ARMv6.
1105 else if (Arch.starts_with("armv6") && !Arch.ends_with("6m"))
1106 Arch = Arch.substr(0, 5);
1107 // ARMv7A normalises to ARMv7.
1108 else if (Arch.ends_with("v7a"))
1109 Arch = Arch.substr(0, 5);
1110 return Arch.data();
1111}
1112
1113StringRef MachO::getMachOArchName(const ArgList &Args) const {
1114 switch (getTriple().getArch()) {
1115 default:
1117
1118 case llvm::Triple::aarch64_32:
1119 return "arm64_32";
1120
1121 case llvm::Triple::aarch64: {
1122 if (getTriple().isArm64e())
1123 return "arm64e";
1124 return "arm64";
1125 }
1126
1127 case llvm::Triple::thumb:
1128 case llvm::Triple::arm:
1129 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1130 if (const char *Arch = ArmMachOArchName(A->getValue()))
1131 return Arch;
1132
1133 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1134 if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
1135 return Arch;
1136
1137 return "arm";
1138 }
1139}
1140
1141VersionTuple MachO::getLinkerVersion(const llvm::opt::ArgList &Args) const {
1142 if (LinkerVersion) {
1143#ifndef NDEBUG
1144 VersionTuple NewLinkerVersion;
1145 if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ))
1146 (void)NewLinkerVersion.tryParse(A->getValue());
1147 assert(NewLinkerVersion == LinkerVersion);
1148#endif
1149 return *LinkerVersion;
1150 }
1151
1152 VersionTuple NewLinkerVersion;
1153 if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
1154 // Rejecting subbuild version is probably not necessary, but some
1155 // existing tests depend on this.
1156 if (NewLinkerVersion.tryParse(A->getValue()) ||
1157 NewLinkerVersion.getSubbuild())
1158 getDriver().Diag(diag::err_drv_invalid_version_number)
1159 << A->getAsString(Args);
1160 }
1161
1162 LinkerVersion = NewLinkerVersion;
1163 return *LinkerVersion;
1164}
1165
1167
1170 return;
1171
1172 llvm::Triple::OSType OS = getTriple().getOS();
1173
1174 DarwinPlatformKind Platform;
1175 switch (OS) {
1176 case llvm::Triple::Darwin:
1177 case llvm::Triple::MacOSX:
1178 Platform = MacOS;
1179 break;
1180 case llvm::Triple::IOS:
1181 Platform = IPhoneOS;
1182 break;
1183 case llvm::Triple::TvOS:
1184 Platform = TvOS;
1185 break;
1186 case llvm::Triple::WatchOS:
1187 Platform = WatchOS;
1188 break;
1189 case llvm::Triple::XROS:
1190 Platform = XROS;
1191 break;
1192 case llvm::Triple::DriverKit:
1193 Platform = DriverKit;
1194 break;
1195 default:
1196 // Unknown platform; leave uninitialized.
1197 return;
1198 }
1199
1201 if (getTriple().isSimulatorEnvironment())
1202 Environment = Simulator;
1203 else if (getTriple().isMacCatalystEnvironment())
1204 Environment = MacCatalyst;
1205
1206 VersionTuple OsVer = getTriple().getOSVersion();
1207 setTarget(Platform, Environment, OsVer.getMajor(),
1208 OsVer.getMinor().value_or(0), OsVer.getSubminor().value_or(0),
1209 VersionTuple());
1210}
1211
1213
1215
1216void Darwin::VerifyTripleForSDK(const llvm::opt::ArgList &Args,
1217 const llvm::Triple Triple) const {
1218 if (SDKInfo) {
1219 if (!SDKInfo->supportsTriple(Triple))
1220 getDriver().Diag(diag::warn_incompatible_sysroot)
1221 << SDKInfo->getDisplayName() << Triple.getTriple();
1222 } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
1223 // If there is no SDK info, assume this is building against an SDK that
1224 // predates SDKSettings.json. Try to match the triple to the SDK path.
1225 const char *isysroot = A->getValue();
1226 StringRef SDKName = getSDKName(isysroot);
1227 if (!SDKName.empty()) {
1228 bool supported = true;
1229 if (Triple.isWatchOS())
1230 supported = SDKName.starts_with("Watch");
1231 else if (Triple.isTvOS())
1232 supported = SDKName.starts_with("AppleTV");
1233 else if (Triple.isDriverKit())
1234 supported = SDKName.starts_with("DriverKit");
1235 else if (Triple.isiOS())
1236 supported = SDKName.starts_with("iPhone");
1237 else if (Triple.isMacOSX())
1238 supported = SDKName.starts_with("MacOSX");
1239 // If it's not an older SDK, then it might be a damaged SDK or a
1240 // non-standard -isysroot path. Don't try to diagnose that here.
1241
1242 if (!supported)
1243 getDriver().Diag(diag::warn_incompatible_sysroot)
1244 << SDKName << Triple.getTriple();
1245 }
1246 }
1247}
1248
1249std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
1250 llvm::StringRef BoundArch,
1251 types::ID InputType) const {
1252 llvm::Triple Triple(ComputeLLVMTriple(Args, BoundArch, InputType));
1253
1254 // If the target isn't initialized (e.g., an unknown Darwin platform, return
1255 // the default triple). Note: we intentionally do NOT call
1256 // ensureTargetInitialized() here because this method is called before
1257 // AddDeploymentTarget() in some code paths (e.g. -print-libgcc-file-name),
1258 // and lazy init with version 0.0.0 would conflict with the real version
1259 // that AddDeploymentTarget() later sets via setTarget().
1260 if (!isTargetInitialized())
1261 return Triple.getTriple();
1262
1263 SmallString<16> Str;
1265 Str += "watchos";
1266 else if (isTargetTvOSBased())
1267 Str += "tvos";
1268 else if (isTargetDriverKit())
1269 Str += "driverkit";
1270 else if (isTargetIOSBased() || isTargetMacCatalyst())
1271 Str += "ios";
1272 else if (isTargetXROS())
1273 Str += llvm::Triple::getOSTypeName(llvm::Triple::XROS);
1274 else if (isTargetFirmware())
1275 Str += llvm::Triple::getOSTypeName(llvm::Triple::Firmware);
1276 else
1277 Str += "macosx";
1278 Str += getTripleTargetVersion().getAsString();
1279 Triple.setOSName(Str);
1280
1281 VerifyTripleForSDK(Args, Triple);
1282
1283 return Triple.getTriple();
1284}
1285
1287 switch (AC) {
1289 if (!Lipo)
1290 Lipo.reset(new tools::darwin::Lipo(*this));
1291 return Lipo.get();
1293 if (!Dsymutil)
1294 Dsymutil.reset(new tools::darwin::Dsymutil(*this));
1295 return Dsymutil.get();
1297 if (!VerifyDebug)
1298 VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
1299 return VerifyDebug.get();
1300 default:
1301 return ToolChain::getTool(AC);
1302 }
1303}
1304
1305Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
1306
1308 return new tools::darwin::StaticLibTool(*this);
1309}
1310
1312 return new tools::darwin::Assembler(*this);
1313}
1314
1315DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
1316 const ArgList &Args)
1317 : Darwin(D, Triple, Args) {}
1318
1319void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
1320 // Always error about undefined 'TARGET_OS_*' macros.
1321 CC1Args.push_back("-Wundef-prefix=TARGET_OS_");
1322 CC1Args.push_back("-Werror=undef-prefix");
1323
1324 // For modern targets, promote certain warnings to errors.
1325 // Lazily initialize the target if needed (e.g. when Darwin is used as
1326 // a host toolchain for device offloading).
1328 if (!isTargetInitialized())
1329 return;
1330 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
1331 // Always enable -Wdeprecated-objc-isa-usage and promote it
1332 // to an error.
1333 CC1Args.push_back("-Wdeprecated-objc-isa-usage");
1334 CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
1335
1336 // For iOS and watchOS, also error about implicit function declarations,
1337 // as that can impact calling conventions.
1338 if (!isTargetMacOS())
1339 CC1Args.push_back("-Werror=implicit-function-declaration");
1340 }
1341}
1342
1344 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
1345 Action::OffloadKind DeviceOffloadKind) const {
1346
1347 Darwin::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
1348}
1349
1350/// Take a path that speculatively points into Xcode and return the
1351/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path
1352/// otherwise.
1353static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) {
1354 static constexpr llvm::StringLiteral XcodeAppSuffix(
1355 ".app/Contents/Developer");
1356 size_t Index = PathIntoXcode.find(XcodeAppSuffix);
1357 if (Index == StringRef::npos)
1358 return "";
1359 return PathIntoXcode.take_front(Index + XcodeAppSuffix.size());
1360}
1361
1362void DarwinClang::AddLinkARCArgs(const ArgList &Args,
1363 ArgStringList &CmdArgs) const {
1364 // Avoid linking compatibility stubs on i386 mac.
1365 if (isTargetMacOSBased() && getArch() == llvm::Triple::x86)
1366 return;
1368 return;
1369 // ARC runtime is supported everywhere on arm64e.
1370 if (getTriple().isArm64e())
1371 return;
1372 if (isTargetXROS())
1373 return;
1374
1375 ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
1376
1377 if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
1378 runtime.hasSubscripting())
1379 return;
1380
1381 SmallString<128> P(getDriver().ClangExecutable);
1382 llvm::sys::path::remove_filename(P); // 'clang'
1383 llvm::sys::path::remove_filename(P); // 'bin'
1384 llvm::sys::path::append(P, "lib", "arc");
1385
1386 // 'libarclite' usually lives in the same toolchain as 'clang'. However, the
1387 // Swift open source toolchains for macOS distribute Clang without libarclite.
1388 // In that case, to allow the linker to find 'libarclite', we point to the
1389 // 'libarclite' in the XcodeDefault toolchain instead.
1390 if (!getVFS().exists(P)) {
1391 auto updatePath = [&](const Arg *A) {
1392 // Try to infer the path to 'libarclite' in the toolchain from the
1393 // specified SDK path.
1394 StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue());
1395 if (XcodePathForSDK.empty())
1396 return false;
1397
1398 P = XcodePathForSDK;
1399 llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr",
1400 "lib", "arc");
1401 return getVFS().exists(P);
1402 };
1403
1404 bool updated = false;
1405 if (const Arg *A = Args.getLastArg(options::OPT_isysroot))
1406 updated = updatePath(A);
1407
1408 if (!updated) {
1409 if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1410 updatePath(A);
1411 }
1412 }
1413
1414 CmdArgs.push_back("-force_load");
1415 llvm::sys::path::append(P, "libarclite_");
1416 // Mash in the platform.
1418 P += "watchsimulator";
1419 else if (isTargetWatchOS())
1420 P += "watchos";
1421 else if (isTargetTvOSSimulator())
1422 P += "appletvsimulator";
1423 else if (isTargetTvOS())
1424 P += "appletvos";
1425 else if (isTargetIOSSimulator())
1426 P += "iphonesimulator";
1427 else if (isTargetIPhoneOS())
1428 P += "iphoneos";
1429 else
1430 P += "macosx";
1431 P += ".a";
1432
1433 if (!getVFS().exists(P))
1434 getDriver().Diag(clang::diag::err_drv_darwin_sdk_missing_arclite) << P;
1435
1436 CmdArgs.push_back(Args.MakeArgString(P));
1437}
1438
1440 // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
1441 if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) ||
1443 return 2;
1444 // Default to use DWARF 4 on OS X 10.11 - macOS 14 / iOS 9 - iOS 17.
1445 if ((isTargetMacOSBased() && isMacosxVersionLT(15)) ||
1447 (isTargetWatchOSBased() && TargetVersion < llvm::VersionTuple(11)) ||
1448 (isTargetXROS() && TargetVersion < llvm::VersionTuple(2)) ||
1449 (isTargetDriverKit() && TargetVersion < llvm::VersionTuple(24)) ||
1450 (isTargetMacOSBased() &&
1451 TargetVersion.empty())) // apple-darwin, no version.
1452 return 4;
1453 return 5;
1454}
1455
1457 // Default to an OS version on which LLDB supports debugging
1458 // -gsimple-template-names programs.
1459 if ((isTargetMacOSBased() && isMacosxVersionLT(26)) ||
1461 (isTargetWatchOSBased() && TargetVersion < llvm::VersionTuple(26)) ||
1462 (isTargetXROS() && TargetVersion < llvm::VersionTuple(26)) ||
1463 (isTargetDriverKit() && TargetVersion < llvm::VersionTuple(25)) ||
1464 (isTargetMacOSBased() &&
1465 TargetVersion.empty())) // apple-darwin, no version.
1466 return false;
1467
1468 return true;
1469}
1470
1471void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
1472 StringRef Component, RuntimeLinkOptions Opts,
1473 bool IsShared) const {
1474 std::string P = getCompilerRT(
1475 Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static);
1476
1477 // For now, allow missing resource libraries to support developers who may
1478 // not have compiler-rt checked out or integrated into their build (unless
1479 // we explicitly force linking with this library).
1480 if ((Opts & RLO_AlwaysLink) || getVFS().exists(P)) {
1481 const char *LibArg = Args.MakeArgString(P);
1482 CmdArgs.push_back(LibArg);
1483 }
1484
1485 // Adding the rpaths might negatively interact when other rpaths are involved,
1486 // so we should make sure we add the rpaths last, after all user-specified
1487 // rpaths. This is currently true from this place, but we need to be
1488 // careful if this function is ever called before user's rpaths are emitted.
1489 if (Opts & RLO_AddRPath) {
1490 assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library");
1491
1492 // Add @executable_path to rpath to support having the dylib copied with
1493 // the executable.
1494 CmdArgs.push_back("-rpath");
1495 CmdArgs.push_back("@executable_path");
1496
1497 // Add the compiler-rt library's directory to rpath to support using the
1498 // dylib from the default location without copying.
1499 CmdArgs.push_back("-rpath");
1500 CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P)));
1501 }
1502}
1503
1504std::string MachO::getCompilerRT(const ArgList &Args, StringRef Component,
1505 FileType Type, bool IsFortran) const {
1506 assert(Type != ToolChain::FT_Object &&
1507 "it doesn't make sense to ask for the compiler-rt library name as an "
1508 "object file");
1509 SmallString<64> MachOLibName = StringRef("libclang_rt");
1510 // On MachO, the builtins component is not in the library name
1511 if (Component != "builtins") {
1512 MachOLibName += '.';
1513 MachOLibName += Component;
1514 }
1515 MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
1516
1517 SmallString<128> FullPath(getDriver().ResourceDir);
1518 llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded",
1519 MachOLibName);
1520 return std::string(FullPath);
1521}
1522
1523std::string Darwin::getCompilerRT(const ArgList &Args, StringRef Component,
1524 FileType Type, bool IsFortran) const {
1525 // Firmware uses the "bare metal" RT.
1527 return MachO::getCompilerRT(Args, Component, Type, IsFortran);
1528
1529 assert(Type != ToolChain::FT_Object &&
1530 "it doesn't make sense to ask for the compiler-rt library name as an "
1531 "object file");
1532 SmallString<64> DarwinLibName = StringRef("libclang_rt.");
1533 // On Darwin, the builtins component is not in the library name
1534 if (Component != "builtins") {
1535 DarwinLibName += Component;
1536 DarwinLibName += '_';
1537 }
1538 DarwinLibName += getOSLibraryNameSuffix();
1539 DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
1540
1541 SmallString<128> FullPath(getDriver().ResourceDir);
1542 llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName);
1543 return std::string(FullPath);
1544}
1545
1546StringRef Darwin::getSDKName(StringRef isysroot) {
1547 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
1548 auto BeginSDK = llvm::sys::path::rbegin(isysroot);
1549 auto EndSDK = llvm::sys::path::rend(isysroot);
1550 for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
1551 StringRef SDK = *IT;
1552 if (SDK.consume_back(".sdk"))
1553 return SDK;
1554 }
1555 return "";
1556}
1557
1558StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
1559 switch (TargetPlatform) {
1561 return "osx";
1564 return "osx";
1565 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "ios"
1566 : "iossim";
1568 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "tvos"
1569 : "tvossim";
1571 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos"
1572 : "watchossim";
1574 return TargetEnvironment == NativeEnvironment || IgnoreSim ? "xros"
1575 : "xrossim";
1577 return "driverkit";
1578
1580 break;
1581 }
1582 llvm_unreachable("Unsupported platform");
1583}
1584
1585/// Check if the link command contains a symbol export directive.
1586static bool hasExportSymbolDirective(const ArgList &Args) {
1587 for (Arg *A : Args) {
1588 if (A->getOption().matches(options::OPT_exported__symbols__list))
1589 return true;
1590 if (!A->getOption().matches(options::OPT_Wl_COMMA) &&
1591 !A->getOption().matches(options::OPT_Xlinker))
1592 continue;
1593 if (A->containsValue("-exported_symbols_list") ||
1594 A->containsValue("-exported_symbol"))
1595 return true;
1596 }
1597 return false;
1598}
1599
1600/// Add an export directive for \p Symbol to the link command.
1601static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) {
1602 CmdArgs.push_back("-exported_symbol");
1603 CmdArgs.push_back(Symbol);
1604}
1605
1606/// Add a sectalign directive for \p Segment and \p Section to the maximum
1607/// expected page size for Darwin.
1608///
1609/// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K.
1610/// Use a common alignment constant (16K) for now, and reduce the alignment on
1611/// macOS if it proves important.
1612static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs,
1613 StringRef Segment, StringRef Section) {
1614 for (const char *A : {"-sectalign", Args.MakeArgString(Segment),
1615 Args.MakeArgString(Section), "0x4000"})
1616 CmdArgs.push_back(A);
1617}
1618
1619void Darwin::addProfileRTLibs(const ArgList &Args,
1620 ArgStringList &CmdArgs) const {
1621 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args))
1622 return;
1623
1624 AddLinkRuntimeLib(Args, CmdArgs, "profile",
1626
1627 bool ForGCOV = needsGCovInstrumentation(Args);
1628
1629 // If we have a symbol export directive and we're linking in the profile
1630 // runtime, automatically export symbols necessary to implement some of the
1631 // runtime's functionality.
1632 if (hasExportSymbolDirective(Args) && ForGCOV) {
1633 addExportedSymbol(CmdArgs, "___gcov_dump");
1634 addExportedSymbol(CmdArgs, "___gcov_reset");
1635 addExportedSymbol(CmdArgs, "_writeout_fn_list");
1636 addExportedSymbol(CmdArgs, "_reset_fn_list");
1637 }
1638
1639 // Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page
1640 // alignment. This allows profile counters to be mmap()'d to disk. Note that
1641 // it's not enough to just page-align __llvm_prf_cnts: the following section
1642 // must also be page-aligned so that its data is not clobbered by mmap().
1643 //
1644 // The section alignment is only needed when continuous profile sync is
1645 // enabled, but this is expected to be the default in Xcode. Specifying the
1646 // extra alignment also allows the same binary to be used with/without sync
1647 // enabled.
1648 if (!ForGCOV) {
1649 for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_bitmap, llvm::IPSK_data}) {
1651 Args, CmdArgs, "__DATA",
1652 llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO,
1653 /*AddSegmentInfo=*/false));
1654 }
1655 }
1656}
1657
1658void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
1659 ArgStringList &CmdArgs,
1660 StringRef Sanitizer,
1661 bool Shared) const {
1662 auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U));
1663 AddLinkRuntimeLib(Args, CmdArgs, Sanitizer, RLO, Shared);
1664}
1665
1667 const ArgList &Args) const {
1668 if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {
1669 StringRef Value = A->getValue();
1670 if (Value != "compiler-rt" && Value != "platform")
1671 getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform)
1672 << Value << "darwin";
1673 }
1674
1675 return ToolChain::GetRuntimeLibType(Args);
1676}
1677
1678void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
1679 ArgStringList &CmdArgs,
1680 bool ForceLinkBuiltinRT) const {
1681 // Firmware uses the "bare metal" runtime lib.
1683 return MachO::AddLinkRuntimeLibArgs(Args, CmdArgs, ForceLinkBuiltinRT);
1684
1685 // Call once to ensure diagnostic is printed if wrong value was specified
1686 GetRuntimeLibType(Args);
1687
1688 // Darwin doesn't support real static executables, don't link any runtime
1689 // libraries with -static.
1690 if (Args.hasArg(options::OPT_static) ||
1691 Args.hasArg(options::OPT_fapple_kext) ||
1692 Args.hasArg(options::OPT_mkernel)) {
1693 if (ForceLinkBuiltinRT)
1694 AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1695 return;
1696 }
1697
1698 // Reject -static-libgcc for now, we can deal with this when and if someone
1699 // cares. This is useful in situations where someone wants to statically link
1700 // something like libstdc++, and needs its runtime support routines.
1701 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
1702 getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
1703 return;
1704 }
1705
1706 const SanitizerArgs &Sanitize = getSanitizerArgs(Args);
1707
1708 if (!Sanitize.needsSharedRt()) {
1709 const char *sanitizer = nullptr;
1710 if (Sanitize.needsUbsanRt()) {
1711 sanitizer = "UndefinedBehaviorSanitizer";
1712 } else if (Sanitize.needsRtsanRt()) {
1713 sanitizer = "RealtimeSanitizer";
1714 } else if (Sanitize.needsAsanRt()) {
1715 sanitizer = "AddressSanitizer";
1716 } else if (Sanitize.needsTsanRt()) {
1717 sanitizer = "ThreadSanitizer";
1718 }
1719 if (sanitizer) {
1720 getDriver().Diag(diag::err_drv_unsupported_static_sanitizer_darwin)
1721 << sanitizer;
1722 return;
1723 }
1724 }
1725
1726 if (Sanitize.linkRuntimes()) {
1727 if (Sanitize.needsAsanRt()) {
1728 if (Sanitize.needsStableAbi()) {
1729 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan_abi", /*shared=*/false);
1730 } else {
1731 assert(Sanitize.needsSharedRt() &&
1732 "Static sanitizer runtimes not supported");
1733 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
1734 }
1735 }
1736 if (Sanitize.needsRtsanRt()) {
1737 assert(Sanitize.needsSharedRt() &&
1738 "Static sanitizer runtimes not supported");
1739 AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan");
1740 }
1741 if (Sanitize.needsLsanRt())
1742 AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
1743 if (Sanitize.needsUbsanRt()) {
1744 assert(Sanitize.needsSharedRt() &&
1745 "Static sanitizer runtimes not supported");
1746 AddLinkSanitizerLibArgs(
1747 Args, CmdArgs,
1748 Sanitize.requiresMinimalRuntime() ? "ubsan_minimal" : "ubsan");
1749 }
1750 if (Sanitize.needsTsanRt()) {
1751 assert(Sanitize.needsSharedRt() &&
1752 "Static sanitizer runtimes not supported");
1753 AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
1754 }
1755 if (Sanitize.needsTysanRt())
1756 AddLinkSanitizerLibArgs(Args, CmdArgs, "tysan");
1757 if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) {
1758 AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false);
1759
1760 // Libfuzzer is written in C++ and requires libcxx.
1761 // Since darwin::Linker::ConstructJob already adds -lc++ for clang++
1762 // by default if ShouldLinkCXXStdlib(Args), we only add the option if
1763 // !ShouldLinkCXXStdlib(Args). This avoids duplicate library errors
1764 // on Darwin.
1765 if (!ShouldLinkCXXStdlib(Args))
1766 AddCXXStdlibLibArgs(Args, CmdArgs);
1767 }
1768 if (Sanitize.needsStatsRt()) {
1769 AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
1770 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
1771 }
1772 }
1773
1774 if (Sanitize.needsMemProfRt())
1775 if (hasExportSymbolDirective(Args))
1777 CmdArgs,
1778 llvm::memprof::getMemprofOptionsSymbolDarwinLinkageName().data());
1779
1780 const XRayArgs &XRay = getXRayArgs(Args);
1781 if (XRay.needsXRayRt()) {
1782 AddLinkRuntimeLib(Args, CmdArgs, "xray");
1783 AddLinkRuntimeLib(Args, CmdArgs, "xray-basic");
1784 AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr");
1785 }
1786
1787 if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) {
1788 CmdArgs.push_back("-framework");
1789 CmdArgs.push_back("DriverKit");
1790 }
1791
1792 // Otherwise link libSystem, then the dynamic runtime library, and finally any
1793 // target specific static runtime library.
1794 if (!isTargetDriverKit())
1795 CmdArgs.push_back("-lSystem");
1796
1797 // Select the dynamic runtime library and the target specific static library.
1798 // Some old Darwin versions put builtins, libunwind, and some other stuff in
1799 // libgcc_s.1.dylib. MacOS X 10.6 and iOS 5 moved those functions to
1800 // libSystem, and made libgcc_s.1.dylib a stub. We never link libgcc_s when
1801 // building for aarch64 or iOS simulator, since libgcc_s was made obsolete
1802 // before either existed.
1803 if (getTriple().getArch() != llvm::Triple::aarch64 &&
1807 CmdArgs.push_back("-lgcc_s.1");
1808 AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1809}
1810
1811/// Returns the most appropriate macOS target version for the current process.
1812///
1813/// If the macOS SDK version is the same or earlier than the system version,
1814/// then the SDK version is returned. Otherwise the system version is returned.
1815static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
1816 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
1817 if (!SystemTriple.isMacOSX())
1818 return std::string(MacOSSDKVersion);
1819 VersionTuple SystemVersion;
1820 SystemTriple.getMacOSXVersion(SystemVersion);
1821
1822 unsigned Major, Minor, Micro;
1823 bool HadExtra;
1824 if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
1825 HadExtra))
1826 return std::string(MacOSSDKVersion);
1827 VersionTuple SDKVersion(Major, Minor, Micro);
1828
1829 if (SDKVersion > SystemVersion)
1830 return SystemVersion.getAsString();
1831 return std::string(MacOSSDKVersion);
1832}
1833
1834namespace {
1835
1836/// The Darwin OS and version that was selected or inferred from arguments or
1837/// environment.
1838struct DarwinPlatform {
1839 enum SourceKind {
1840 /// The OS was specified using the -target argument.
1841 TargetArg,
1842 /// The OS was specified using the -mtargetos= argument.
1843 MTargetOSArg,
1844 /// The OS was specified using the -m<os>-version-min argument.
1845 OSVersionArg,
1846 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
1847 DeploymentTargetEnv,
1848 /// The OS was inferred from the SDK.
1849 InferredFromSDK,
1850 /// The OS was inferred from the -arch.
1851 InferredFromArch
1852 };
1853
1854 using DarwinPlatformKind = Darwin::DarwinPlatformKind;
1855 using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind;
1856
1857 DarwinPlatformKind getPlatform() const { return Platform; }
1858
1859 DarwinEnvironmentKind getEnvironment() const { return Environment; }
1860
1861 void setEnvironment(DarwinEnvironmentKind Kind) {
1862 Environment = Kind;
1863 InferSimulatorFromArch = false;
1864 }
1865
1866 const VersionTuple getOSVersion() const {
1867 return UnderlyingOSVersion.value_or(VersionTuple());
1868 }
1869
1870 VersionTuple takeOSVersion() {
1871 assert(UnderlyingOSVersion.has_value() &&
1872 "attempting to get an unset OS version");
1873 VersionTuple Result = *UnderlyingOSVersion;
1874 UnderlyingOSVersion.reset();
1875 return Result;
1876 }
1877 bool isValidOSVersion() const {
1878 return llvm::Triple::isValidVersionForOS(getOSFromPlatform(Platform),
1879 getOSVersion());
1880 }
1881
1882 VersionTuple getCanonicalOSVersion() const {
1883 return llvm::Triple::getCanonicalVersionForOS(
1884 getOSFromPlatform(Platform), getOSVersion(), /*IsInValidRange=*/true);
1885 }
1886
1887 void setOSVersion(const VersionTuple &Version) {
1888 UnderlyingOSVersion = Version;
1889 }
1890
1891 bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); }
1892
1893 VersionTuple getZipperedOSVersion() const {
1894 assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
1895 "zippered target version is specified only for Mac Catalyst");
1896 return ZipperedOSVersion;
1897 }
1898
1899 /// Returns true if the target OS was explicitly specified.
1900 bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
1901
1902 /// Returns true if the simulator environment can be inferred from the arch.
1903 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }
1904
1905 const std::optional<llvm::Triple> &getTargetVariantTriple() const {
1906 return TargetVariantTriple;
1907 }
1908
1909 /// Adds the -m<os>-version-min argument to the compiler invocation.
1910 void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
1911 auto &[Arg, OSVersionStr] = Arguments;
1912 if (Arg)
1913 return;
1914 assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1915 "Invalid kind");
1916 options::ID Opt;
1917 switch (Platform) {
1918 case DarwinPlatformKind::MacOS:
1919 Opt = options::OPT_mmacos_version_min_EQ;
1920 break;
1921 case DarwinPlatformKind::IPhoneOS:
1922 Opt = options::OPT_mios_version_min_EQ;
1923 break;
1924 case DarwinPlatformKind::TvOS:
1925 Opt = options::OPT_mtvos_version_min_EQ;
1926 break;
1927 case DarwinPlatformKind::WatchOS:
1928 Opt = options::OPT_mwatchos_version_min_EQ;
1929 break;
1930 default:
1931 // New platforms always explicitly provide a version in the triple.
1932 return;
1933 }
1934 Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);
1935 Args.append(Arg);
1936 }
1937
1938 /// Returns the OS version with the argument / environment variable that
1939 /// specified it.
1940 std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
1941 auto &[Arg, OSVersionStr] = Arguments;
1942 switch (Kind) {
1943 case TargetArg:
1944 case MTargetOSArg:
1945 case OSVersionArg:
1946 assert(Arg && "OS version argument not yet inferred");
1947 return Arg->getAsString(Args);
1948 case DeploymentTargetEnv:
1949 return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
1950 case InferredFromSDK:
1951 case InferredFromArch:
1952 llvm_unreachable("Cannot print arguments for inferred OS version");
1953 }
1954 llvm_unreachable("Unsupported Darwin Source Kind");
1955 }
1956
1957 // Returns the inferred source of how the OS version was resolved.
1958 std::string getInferredSource() {
1959 assert(!isExplicitlySpecified() && "OS version was not inferred");
1960 return InferredSource.str();
1961 }
1962
1963 void setEnvironment(llvm::Triple::EnvironmentType EnvType,
1964 const VersionTuple &OSVersion,
1965 const std::optional<DarwinSDKInfo> &SDKInfo) {
1966 switch (EnvType) {
1967 case llvm::Triple::Simulator:
1968 Environment = DarwinEnvironmentKind::Simulator;
1969 break;
1970 case llvm::Triple::MacABI: {
1971 Environment = DarwinEnvironmentKind::MacCatalyst;
1972 // The minimum native macOS target for MacCatalyst is macOS 10.15.
1973 ZipperedOSVersion = VersionTuple(10, 15);
1974 if (hasOSVersion() && SDKInfo) {
1975 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
1977 if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
1978 OSVersion, ZipperedOSVersion, std::nullopt)) {
1979 ZipperedOSVersion = *MacOSVersion;
1980 }
1981 }
1982 }
1983 // In a zippered build, we could be building for a macOS target that's
1984 // lower than the version that's implied by the OS version. In that case
1985 // we need to use the minimum version as the native target version.
1986 if (TargetVariantTriple) {
1987 auto TargetVariantVersion = TargetVariantTriple->getOSVersion();
1988 if (TargetVariantVersion.getMajor()) {
1989 if (TargetVariantVersion < ZipperedOSVersion)
1990 ZipperedOSVersion = std::move(TargetVariantVersion);
1991 }
1992 }
1993 break;
1994 }
1995 default:
1996 break;
1997 }
1998 }
1999
2000 static DarwinPlatform
2001 createFromTarget(const llvm::Triple &TT, Arg *A,
2002 std::optional<llvm::Triple> TargetVariantTriple,
2003 const std::optional<DarwinSDKInfo> &SDKInfo) {
2004 DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()),
2005 TT.getOSVersion(), A);
2006 VersionTuple OsVersion = TT.getOSVersion();
2007 Result.TargetVariantTriple = std::move(TargetVariantTriple);
2008 Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);
2009 return Result;
2010 }
2011 static DarwinPlatform
2012 createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
2013 llvm::Triple::EnvironmentType Environment, Arg *A,
2014 const std::optional<DarwinSDKInfo> &SDKInfo) {
2015 DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), OSVersion, A);
2016 Result.InferSimulatorFromArch = false;
2017 Result.setEnvironment(Environment, OSVersion, SDKInfo);
2018 return Result;
2019 }
2020 static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A,
2021 bool IsSimulator) {
2022 DarwinPlatform Result{OSVersionArg, Platform,
2023 getVersionFromString(A->getValue()), A};
2024 if (IsSimulator)
2025 Result.Environment = DarwinEnvironmentKind::Simulator;
2026 return Result;
2027 }
2028 static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,
2029 StringRef EnvVarName,
2030 StringRef OSVersion) {
2031 DarwinPlatform Result(DeploymentTargetEnv, Platform,
2032 getVersionFromString(OSVersion));
2033 Result.EnvVarName = EnvVarName;
2034 return Result;
2035 }
2036 static DarwinPlatform createFromSDKInfo(StringRef SDKRoot,
2037 const DarwinSDKInfo &SDKInfo) {
2038 const DarwinSDKInfo::SDKPlatformInfo PlatformInfo =
2039 SDKInfo.getCanonicalPlatformInfo();
2040 const llvm::Triple::OSType OS = PlatformInfo.getOS();
2041 VersionTuple Version = SDKInfo.getVersion();
2042 if (OS == llvm::Triple::MacOSX)
2043 Version = getVersionFromString(
2044 getSystemOrSDKMacOSVersion(Version.getAsString()));
2045 DarwinPlatform Result(InferredFromSDK, getPlatformFromOS(OS), Version);
2046 Result.Environment = getEnvKindFromEnvType(PlatformInfo.getEnvironment());
2047 Result.InferSimulatorFromArch = false;
2048 Result.InferredSource = SDKRoot;
2049 return Result;
2050 }
2051 static DarwinPlatform createFromSDK(StringRef SDKRoot,
2052 DarwinPlatformKind Platform,
2053 StringRef Value,
2054 bool IsSimulator = false) {
2055 DarwinPlatform Result(InferredFromSDK, Platform,
2056 getVersionFromString(Value));
2057 if (IsSimulator)
2058 Result.Environment = DarwinEnvironmentKind::Simulator;
2059 Result.InferSimulatorFromArch = false;
2060 Result.InferredSource = SDKRoot;
2061 return Result;
2062 }
2063 static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,
2064 VersionTuple Version) {
2065 auto Result =
2066 DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
2067 Result.InferredSource = Arch;
2068 return Result;
2069 }
2070
2071 /// Constructs an inferred SDKInfo value based on the version inferred from
2072 /// the SDK path itself. Only works for values that were created by inferring
2073 /// the platform from the SDKPath.
2074 DarwinSDKInfo inferSDKInfo() {
2075 assert(Kind == InferredFromSDK && "can infer SDK info only");
2076 llvm::Triple::OSType OS = getOSFromPlatform(Platform);
2077 llvm::Triple::EnvironmentType EnvironmentType =
2078 getEnvTypeFromEnvKind(Environment);
2079 StringRef PlatformPrefix =
2080 (Platform == DarwinPlatformKind::DriverKit) ? "/System/DriverKit" : "";
2081 return DarwinSDKInfo("", OS, EnvironmentType, getOSVersion(),
2082 getDisplayName(Platform, Environment, getOSVersion()),
2083 /*MaximumDeploymentTarget=*/
2084 VersionTuple(getOSVersion().getMajor(), 0, 99),
2085 {DarwinSDKInfo::SDKPlatformInfo(
2086 llvm::Triple::Apple, OS, EnvironmentType,
2087 llvm::Triple::MachO, PlatformPrefix)});
2088 }
2089
2090private:
2091 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
2092 : Kind(Kind), Platform(Platform),
2093 Arguments({Argument, VersionTuple().getAsString()}) {}
2094 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,
2095 VersionTuple Value, Arg *Argument = nullptr)
2096 : Kind(Kind), Platform(Platform),
2097 Arguments({Argument, Value.getAsString()}) {
2098 if (!Value.empty())
2099 UnderlyingOSVersion = Value;
2100 }
2101
2102 static VersionTuple getVersionFromString(const StringRef Input) {
2103 llvm::VersionTuple Version;
2104 bool IsValid = !Version.tryParse(Input);
2105 assert(IsValid && "unable to convert input version to version tuple");
2106 (void)IsValid;
2107 return Version;
2108 }
2109
2110 static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {
2111 switch (OS) {
2112 case llvm::Triple::Darwin:
2113 case llvm::Triple::MacOSX:
2114 return DarwinPlatformKind::MacOS;
2115 case llvm::Triple::IOS:
2116 return DarwinPlatformKind::IPhoneOS;
2117 case llvm::Triple::TvOS:
2118 return DarwinPlatformKind::TvOS;
2119 case llvm::Triple::WatchOS:
2120 return DarwinPlatformKind::WatchOS;
2121 case llvm::Triple::XROS:
2122 return DarwinPlatformKind::XROS;
2123 case llvm::Triple::DriverKit:
2124 return DarwinPlatformKind::DriverKit;
2125 case llvm::Triple::Firmware:
2126 return DarwinPlatformKind::Firmware;
2127 default:
2128 llvm_unreachable("Unable to infer Darwin variant");
2129 }
2130 }
2131
2132 static llvm::Triple::OSType getOSFromPlatform(DarwinPlatformKind Platform) {
2133 switch (Platform) {
2134 case DarwinPlatformKind::MacOS:
2135 return llvm::Triple::MacOSX;
2136 case DarwinPlatformKind::IPhoneOS:
2137 return llvm::Triple::IOS;
2138 case DarwinPlatformKind::TvOS:
2139 return llvm::Triple::TvOS;
2140 case DarwinPlatformKind::WatchOS:
2141 return llvm::Triple::WatchOS;
2142 case DarwinPlatformKind::DriverKit:
2143 return llvm::Triple::DriverKit;
2144 case DarwinPlatformKind::XROS:
2145 return llvm::Triple::XROS;
2146 case DarwinPlatformKind::Firmware:
2147 return llvm::Triple::Firmware;
2148 }
2149 llvm_unreachable("Unknown DarwinPlatformKind enum");
2150 }
2151
2152 static DarwinEnvironmentKind
2153 getEnvKindFromEnvType(llvm::Triple::EnvironmentType EnvironmentType) {
2154 switch (EnvironmentType) {
2155 case llvm::Triple::UnknownEnvironment:
2156 return DarwinEnvironmentKind::NativeEnvironment;
2157 case llvm::Triple::Simulator:
2158 return DarwinEnvironmentKind::Simulator;
2159 case llvm::Triple::MacABI:
2160 return DarwinEnvironmentKind::MacCatalyst;
2161 default:
2162 llvm_unreachable("Unable to infer Darwin environment");
2163 }
2164 }
2165
2166 static llvm::Triple::EnvironmentType
2167 getEnvTypeFromEnvKind(DarwinEnvironmentKind EnvironmentKind) {
2168 switch (EnvironmentKind) {
2169 case DarwinEnvironmentKind::NativeEnvironment:
2170 return llvm::Triple::UnknownEnvironment;
2171 case DarwinEnvironmentKind::Simulator:
2172 return llvm::Triple::Simulator;
2173 case DarwinEnvironmentKind::MacCatalyst:
2174 return llvm::Triple::MacABI;
2175 }
2176 llvm_unreachable("Unknown DarwinEnvironmentKind enum");
2177 }
2178
2179 static std::string getDisplayName(DarwinPlatformKind TargetPlatform,
2180 DarwinEnvironmentKind TargetEnvironment,
2181 VersionTuple Version) {
2182 SmallVector<std::string, 3> Components;
2183 switch (TargetPlatform) {
2184 case DarwinPlatformKind::MacOS:
2185 Components.push_back("macOS");
2186 break;
2187 case DarwinPlatformKind::IPhoneOS:
2188 Components.push_back("iOS");
2189 break;
2190 case DarwinPlatformKind::TvOS:
2191 Components.push_back("tvOS");
2192 break;
2193 case DarwinPlatformKind::WatchOS:
2194 Components.push_back("watchOS");
2195 break;
2196 case DarwinPlatformKind::DriverKit:
2197 Components.push_back("DriverKit");
2198 break;
2199 default:
2200 llvm::reportFatalUsageError(Twine("Platform: '") +
2201 std::to_string(TargetPlatform) +
2202 "' is unsupported when inferring SDK Info.");
2203 }
2204 switch (TargetEnvironment) {
2205 case DarwinEnvironmentKind::NativeEnvironment:
2206 break;
2207 case DarwinEnvironmentKind::Simulator:
2208 Components.push_back("Simulator");
2209 break;
2210 default:
2211 llvm::reportFatalUsageError(Twine("Environment: '") +
2212 std::to_string(TargetEnvironment) +
2213 "' is unsupported when inferring SDK Info.");
2214 }
2215 Components.push_back(Version.getAsString());
2216 return join(Components, " ");
2217 }
2218
2219 SourceKind Kind;
2220 DarwinPlatformKind Platform;
2221 DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
2222 // When compiling for a zippered target, this means both target &
2223 // target variant is set on the command line, ZipperedOSVersion holds the
2224 // OSVersion tied to the main target value.
2225 VersionTuple ZipperedOSVersion;
2226 // We allow multiple ways to set or default the OS
2227 // version used for compilation. When set, UnderlyingOSVersion represents
2228 // the intended version to match the platform information computed from
2229 // arguments.
2230 std::optional<VersionTuple> UnderlyingOSVersion;
2231 bool InferSimulatorFromArch = true;
2232 std::pair<Arg *, std::string> Arguments;
2233 StringRef EnvVarName;
2234 // If the DarwinPlatform information is derived from an inferred source, this
2235 // captures what that source input was for error reporting.
2236 StringRef InferredSource;
2237 // When compiling for a zippered target, this value represents the target
2238 // triple encoded in the target variant.
2239 std::optional<llvm::Triple> TargetVariantTriple;
2240};
2241
2242/// Returns the deployment target that's specified using the -m<os>-version-min
2243/// argument.
2244std::optional<DarwinPlatform>
2245getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
2246 const Driver &TheDriver) {
2247 Arg *macOSVersion = Args.getLastArg(options::OPT_mmacos_version_min_EQ);
2248 Arg *iOSVersion = Args.getLastArg(options::OPT_mios_version_min_EQ,
2249 options::OPT_mios_simulator_version_min_EQ);
2250 Arg *TvOSVersion =
2251 Args.getLastArg(options::OPT_mtvos_version_min_EQ,
2252 options::OPT_mtvos_simulator_version_min_EQ);
2253 Arg *WatchOSVersion =
2254 Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
2255 options::OPT_mwatchos_simulator_version_min_EQ);
2256
2257 auto GetDarwinPlatform =
2258 [&](DarwinPlatform::DarwinPlatformKind Platform, Arg *VersionArg,
2259 bool IsSimulator) -> std::optional<DarwinPlatform> {
2260 if (StringRef(VersionArg->getValue()).empty()) {
2261 TheDriver.Diag(diag::err_drv_missing_version_number)
2262 << VersionArg->getAsString(Args);
2263 return std::nullopt;
2264 }
2265 return DarwinPlatform::createOSVersionArg(Platform, VersionArg,
2266 /*IsSimulator=*/IsSimulator);
2267 };
2268
2269 if (macOSVersion) {
2270 if (iOSVersion || TvOSVersion || WatchOSVersion) {
2271 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2272 << macOSVersion->getAsString(Args)
2273 << (iOSVersion ? iOSVersion
2274 : TvOSVersion ? TvOSVersion : WatchOSVersion)
2275 ->getAsString(Args);
2276 }
2277 return GetDarwinPlatform(Darwin::MacOS, macOSVersion,
2278 /*IsSimulator=*/false);
2279
2280 } else if (iOSVersion) {
2281 if (TvOSVersion || WatchOSVersion) {
2282 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2283 << iOSVersion->getAsString(Args)
2284 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
2285 }
2286 return GetDarwinPlatform(Darwin::IPhoneOS, iOSVersion,
2287 iOSVersion->getOption().getID() ==
2288 options::OPT_mios_simulator_version_min_EQ);
2289 } else if (TvOSVersion) {
2290 if (WatchOSVersion) {
2291 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2292 << TvOSVersion->getAsString(Args)
2293 << WatchOSVersion->getAsString(Args);
2294 }
2295 return GetDarwinPlatform(Darwin::TvOS, TvOSVersion,
2296 TvOSVersion->getOption().getID() ==
2297 options::OPT_mtvos_simulator_version_min_EQ);
2298 } else if (WatchOSVersion)
2299 return GetDarwinPlatform(
2300 Darwin::WatchOS, WatchOSVersion,
2301 WatchOSVersion->getOption().getID() ==
2302 options::OPT_mwatchos_simulator_version_min_EQ);
2303 return std::nullopt;
2304}
2305
2306/// Returns the deployment target that's specified using the
2307/// OS_DEPLOYMENT_TARGET environment variable.
2308std::optional<DarwinPlatform>
2309getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
2310 const llvm::Triple &Triple) {
2311 const char *EnvVars[] = {
2312 "MACOSX_DEPLOYMENT_TARGET",
2313 "IPHONEOS_DEPLOYMENT_TARGET",
2314 "TVOS_DEPLOYMENT_TARGET",
2315 "WATCHOS_DEPLOYMENT_TARGET",
2316 "DRIVERKIT_DEPLOYMENT_TARGET",
2317 "XROS_DEPLOYMENT_TARGET"
2318 };
2319 std::string Targets[std::size(EnvVars)];
2320 for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) {
2321 if (char *Env = ::getenv(I.value()))
2322 Targets[I.index()] = Env;
2323 }
2324
2325 // Allow conflicts among OSX and iOS for historical reasons, but choose the
2326 // default platform.
2327 if (!Targets[Darwin::MacOS].empty() &&
2328 (!Targets[Darwin::IPhoneOS].empty() ||
2329 !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty() ||
2330 !Targets[Darwin::XROS].empty())) {
2331 if (Triple.getArch() == llvm::Triple::arm ||
2332 Triple.getArch() == llvm::Triple::aarch64 ||
2333 Triple.getArch() == llvm::Triple::thumb)
2334 Targets[Darwin::MacOS] = "";
2335 else
2336 Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] =
2337 Targets[Darwin::TvOS] = Targets[Darwin::XROS] = "";
2338 } else {
2339 // Don't allow conflicts in any other platform.
2340 unsigned FirstTarget = std::size(Targets);
2341 for (unsigned I = 0; I != std::size(Targets); ++I) {
2342 if (Targets[I].empty())
2343 continue;
2344 if (FirstTarget == std::size(Targets))
2345 FirstTarget = I;
2346 else
2347 TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
2348 << Targets[FirstTarget] << Targets[I];
2349 }
2350 }
2351
2352 for (const auto &Target : llvm::enumerate(llvm::ArrayRef(Targets))) {
2353 if (!Target.value().empty())
2354 return DarwinPlatform::createDeploymentTargetEnv(
2355 (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],
2356 Target.value());
2357 }
2358 return std::nullopt;
2359}
2360
2361/// Tries to infer the deployment target from the SDK specified by -isysroot
2362/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
2363/// it's available.
2364std::optional<DarwinPlatform>
2365inferDeploymentTargetFromSDK(DerivedArgList &Args,
2366 const std::optional<DarwinSDKInfo> &SDKInfo) {
2367 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2368 if (!A)
2369 return std::nullopt;
2370 StringRef isysroot = A->getValue();
2371 if (SDKInfo)
2372 return DarwinPlatform::createFromSDKInfo(isysroot, *SDKInfo);
2373
2374 StringRef SDK = Darwin::getSDKName(isysroot);
2375 if (!SDK.size())
2376 return std::nullopt;
2377
2378 std::string Version;
2379 // Slice the version number out.
2380 // Version number is between the first and the last number.
2381 size_t StartVer = SDK.find_first_of("0123456789");
2382 size_t EndVer = SDK.find_last_of("0123456789");
2383 if (StartVer != StringRef::npos && EndVer > StartVer)
2384 Version = std::string(SDK.slice(StartVer, EndVer + 1));
2385 if (Version.empty())
2386 return std::nullopt;
2387
2388 if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
2389 return DarwinPlatform::createFromSDK(
2390 isysroot, Darwin::IPhoneOS, Version,
2391 /*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
2392 else if (SDK.starts_with("MacOSX"))
2393 return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,
2395 else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
2396 return DarwinPlatform::createFromSDK(
2397 isysroot, Darwin::WatchOS, Version,
2398 /*IsSimulator=*/SDK.starts_with("WatchSimulator"));
2399 else if (SDK.starts_with("AppleTVOS") || SDK.starts_with("AppleTVSimulator"))
2400 return DarwinPlatform::createFromSDK(
2401 isysroot, Darwin::TvOS, Version,
2402 /*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
2403 else if (SDK.starts_with("DriverKit"))
2404 return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit, Version);
2405 return std::nullopt;
2406}
2407
2408// Compute & get the OS Version when the target triple omitted one.
2409VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,
2410 const llvm::Triple &Triple,
2411 const Driver &TheDriver) {
2412 VersionTuple OsVersion;
2413 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
2414 switch (OS) {
2415 case llvm::Triple::Darwin:
2416 case llvm::Triple::MacOSX:
2417 // If there is no version specified on triple, and both host and target are
2418 // macos, use the host triple to infer OS version.
2419 if (Triple.isMacOSX() && SystemTriple.isMacOSX() &&
2420 !Triple.getOSMajorVersion())
2421 SystemTriple.getMacOSXVersion(OsVersion);
2422 else if (!Triple.getMacOSXVersion(OsVersion))
2423 TheDriver.Diag(diag::err_drv_invalid_darwin_version)
2424 << Triple.getOSName();
2425 break;
2426 case llvm::Triple::IOS:
2427 if (Triple.isMacCatalystEnvironment() && !Triple.getOSMajorVersion()) {
2428 OsVersion = VersionTuple(13, 1);
2429 } else
2430 OsVersion = Triple.getiOSVersion();
2431 break;
2432 case llvm::Triple::TvOS:
2433 OsVersion = Triple.getOSVersion();
2434 break;
2435 case llvm::Triple::WatchOS:
2436 OsVersion = Triple.getWatchOSVersion();
2437 break;
2438 case llvm::Triple::DriverKit:
2439 OsVersion = Triple.getDriverKitVersion();
2440 break;
2441 default:
2442 OsVersion = Triple.getOSVersion();
2443 if (!OsVersion.getMajor())
2444 OsVersion = OsVersion.withMajorReplaced(1);
2445 break;
2446 }
2447 return OsVersion;
2448}
2449
2450/// Tries to infer the target OS from the -arch.
2451std::optional<DarwinPlatform>
2452inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
2453 const llvm::Triple &Triple,
2454 const Driver &TheDriver) {
2455 llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
2456
2457 StringRef MachOArchName = Toolchain.getMachOArchName(Args);
2458 if (MachOArchName == "arm64" || MachOArchName == "arm64e")
2459 OSTy = llvm::Triple::MacOSX;
2460 else if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
2461 MachOArchName == "armv6")
2462 OSTy = llvm::Triple::IOS;
2463 else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32")
2464 OSTy = llvm::Triple::WatchOS;
2465 else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
2466 MachOArchName != "armv7em" && MachOArchName != "armv8m.base" &&
2467 MachOArchName != "armv8m.main" && MachOArchName != "armv8.1m.main")
2468 OSTy = llvm::Triple::MacOSX;
2469 if (OSTy == llvm::Triple::UnknownOS)
2470 return std::nullopt;
2471 return DarwinPlatform::createFromArch(
2472 MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
2473}
2474
2475/// Returns the deployment target that's specified using the -target option.
2476std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2477 DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver,
2478 const std::optional<DarwinSDKInfo> &SDKInfo) {
2479 if (!Args.hasArg(options::OPT_target))
2480 return std::nullopt;
2481 if (Triple.getOS() == llvm::Triple::Darwin ||
2482 Triple.getOS() == llvm::Triple::UnknownOS)
2483 return std::nullopt;
2484 std::optional<llvm::Triple> TargetVariantTriple;
2485 for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
2486 llvm::Triple TVT(A->getValue());
2487 // Find a matching <arch>-<vendor> target variant triple that can be used.
2488 if ((Triple.getArch() == llvm::Triple::aarch64 ||
2489 TVT.getArchName() == Triple.getArchName()) &&
2490 TVT.getArch() == Triple.getArch() &&
2491 TVT.getSubArch() == Triple.getSubArch() &&
2492 TVT.getVendor() == Triple.getVendor()) {
2493 if (TargetVariantTriple)
2494 continue;
2495 A->claim();
2496 // Accept a -target-variant triple when compiling code that may run on
2497 // macOS or Mac Catalyst.
2498 if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS &&
2499 TVT.isMacCatalystEnvironment()) ||
2500 (TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS &&
2501 Triple.isMacCatalystEnvironment())) {
2502 TargetVariantTriple = TVT;
2503 continue;
2504 }
2505 TheDriver.Diag(diag::err_drv_target_variant_invalid)
2506 << A->getSpelling() << A->getValue();
2507 }
2508 }
2509 DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget(
2510 Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
2511 SDKInfo);
2512
2513 return PlatformAndVersion;
2514}
2515
2516/// Returns the deployment target that's specified using the -mtargetos option.
2517std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg(
2518 DerivedArgList &Args, const Driver &TheDriver,
2519 const std::optional<DarwinSDKInfo> &SDKInfo) {
2520 auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
2521 if (!A)
2522 return std::nullopt;
2523 llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
2524 switch (TT.getOS()) {
2525 case llvm::Triple::MacOSX:
2526 case llvm::Triple::IOS:
2527 case llvm::Triple::TvOS:
2528 case llvm::Triple::WatchOS:
2529 case llvm::Triple::XROS:
2530 break;
2531 default:
2532 TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
2533 << TT.getOSName() << A->getAsString(Args);
2534 return std::nullopt;
2535 }
2536
2537 VersionTuple Version = TT.getOSVersion();
2538 if (!Version.getMajor()) {
2539 TheDriver.Diag(diag::err_drv_invalid_version_number)
2540 << A->getAsString(Args);
2541 return std::nullopt;
2542 }
2543 return DarwinPlatform::createFromMTargetOS(TT.getOS(), Version,
2544 TT.getEnvironment(), A, SDKInfo);
2545}
2546
2547std::optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
2548 const ArgList &Args,
2549 const Driver &TheDriver) {
2550 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2551 if (!A)
2552 return std::nullopt;
2553 StringRef isysroot = A->getValue();
2554 auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot);
2555 if (!SDKInfoOrErr) {
2556 llvm::consumeError(SDKInfoOrErr.takeError());
2557 TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);
2558 return std::nullopt;
2559 }
2560 return *SDKInfoOrErr;
2561}
2562
2563} // namespace
2564
2565void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2566 const OptTable &Opts = getDriver().getOpts();
2567 // TryXcselect keeps track of whether we use xcselect to find the SDK
2568 // when CLANG_USE_XCSELECT is enabled. Currently, we do this when we
2569 // do not have a sysroot from -isysroot, --sysroot, or SDKROOT, and
2570 // we do not have --no-xcselect.
2571 bool TryXcselect = false;
2572 (void)TryXcselect;
2573
2574 // Support allowing the SDKROOT environment variable used by xcrun and other
2575 // Xcode tools to define the default sysroot, by making it the default for
2576 // isysroot.
2577 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2578 // Warn if the path does not exist.
2579 if (!getVFS().exists(A->getValue()))
2580 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
2581 } else if (const char *env = ::getenv("SDKROOT")) {
2582 // We only use this value as the default if it is an absolute path,
2583 // exists, and it is not the root path.
2584 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
2585 StringRef(env) != "/") {
2586 Args.append(Args.MakeSeparateArg(
2587 nullptr, Opts.getOption(options::OPT_isysroot), env));
2588 }
2589 } else {
2590 TryXcselect = !Args.hasArg(options::OPT__sysroot_EQ) &&
2591 !Args.hasArg(options::OPT_no_xcselect);
2592 }
2593
2594 // Read the SDKSettings.json file for more information, like the SDK version
2595 // that we can pass down to the compiler.
2596 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
2597 // FIXME: If SDKInfo is std::nullopt, diagnose a bad isysroot value (e.g.
2598 // doesn't end in .sdk).
2599
2600 // The OS and the version can be specified using the -target argument.
2601 std::optional<DarwinPlatform> PlatformAndVersion =
2602 getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
2603 if (PlatformAndVersion) {
2604 // Disallow mixing -target and -mtargetos=.
2605 if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
2606 std::string TargetArgStr = PlatformAndVersion->getAsString(Args, Opts);
2607 std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
2608 getDriver().Diag(diag::err_drv_cannot_mix_options)
2609 << TargetArgStr << MTargetOSArgStr;
2610 }
2611 // Implicitly allow resolving the OS version when it wasn't explicitly set.
2612 bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion();
2613 if (!TripleProvidedOSVersion)
2614 PlatformAndVersion->setOSVersion(
2615 getInferredOSVersion(getTriple().getOS(), getTriple(), getDriver()));
2616
2617 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2618 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2619 if (PlatformAndVersionFromOSVersionArg) {
2620 unsigned TargetMajor, TargetMinor, TargetMicro;
2621 bool TargetExtra;
2622 unsigned ArgMajor, ArgMinor, ArgMicro;
2623 bool ArgExtra;
2624 if (PlatformAndVersion->getPlatform() !=
2625 PlatformAndVersionFromOSVersionArg->getPlatform() ||
2627 PlatformAndVersion->getOSVersion().getAsString(), TargetMajor,
2628 TargetMinor, TargetMicro, TargetExtra) &&
2630 PlatformAndVersionFromOSVersionArg->getOSVersion().getAsString(),
2631 ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
2632 (VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
2633 VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
2634 TargetExtra != ArgExtra))) {
2635 // Select the OS version from the -m<os>-version-min argument when
2636 // the -target does not include an OS version.
2637 if (PlatformAndVersion->getPlatform() ==
2638 PlatformAndVersionFromOSVersionArg->getPlatform() &&
2639 !TripleProvidedOSVersion) {
2640 PlatformAndVersion->setOSVersion(
2641 PlatformAndVersionFromOSVersionArg->getOSVersion());
2642 } else {
2643 // Warn about -m<os>-version-min that doesn't match the OS version
2644 // that's specified in the target.
2645 std::string OSVersionArg =
2646 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2647 std::string TargetArg = PlatformAndVersion->getAsString(Args, Opts);
2648 getDriver().Diag(clang::diag::warn_drv_overriding_option)
2649 << OSVersionArg << TargetArg;
2650 }
2651 }
2652 }
2653 } else if ((PlatformAndVersion = getDeploymentTargetFromMTargetOSArg(
2654 Args, getDriver(), SDKInfo))) {
2655 // The OS target can be specified using the -mtargetos= argument.
2656 // Disallow mixing -mtargetos= and -m<os>version-min=.
2657 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2658 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2659 if (PlatformAndVersionFromOSVersionArg) {
2660 std::string MTargetOSArgStr = PlatformAndVersion->getAsString(Args, Opts);
2661 std::string OSVersionArgStr =
2662 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2663 getDriver().Diag(diag::err_drv_cannot_mix_options)
2664 << MTargetOSArgStr << OSVersionArgStr;
2665 }
2666 } else {
2667 // The OS target can be specified using the -m<os>version-min argument.
2668 PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver());
2669 // If no deployment target was specified on the command line, check for
2670 // environment defines.
2671 if (!PlatformAndVersion) {
2672 PlatformAndVersion =
2673 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
2674 if (PlatformAndVersion) {
2675 // Don't infer simulator from the arch when the SDK is also specified.
2676 std::optional<DarwinPlatform> SDKTarget =
2677 inferDeploymentTargetFromSDK(Args, SDKInfo);
2678 if (SDKTarget)
2679 PlatformAndVersion->setEnvironment(SDKTarget->getEnvironment());
2680 }
2681 }
2682 // If there is no command-line argument to specify the Target version and
2683 // no environment variable defined, see if we can set the default based
2684 // on -isysroot using SDKSettings.json if it exists.
2685 if (!PlatformAndVersion) {
2686 PlatformAndVersion = inferDeploymentTargetFromSDK(Args, SDKInfo);
2687 /// If the target was successfully constructed from the SDK path, try to
2688 /// infer the SDK info if the SDK doesn't have it.
2689 if (PlatformAndVersion && !SDKInfo)
2690 SDKInfo = PlatformAndVersion->inferSDKInfo();
2691 }
2692 // If no OS targets have been specified, try to guess platform from -target
2693 // or arch name and compute the version from the triple.
2694 if (!PlatformAndVersion)
2695 PlatformAndVersion =
2696 inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
2697 }
2698
2699 assert(PlatformAndVersion && "Unable to infer Darwin variant");
2700 if (!PlatformAndVersion->isValidOSVersion()) {
2701 if (PlatformAndVersion->isExplicitlySpecified())
2702 getDriver().Diag(diag::err_drv_invalid_version_number)
2703 << PlatformAndVersion->getAsString(Args, Opts);
2704 else
2705 getDriver().Diag(diag::err_drv_invalid_version_number_inferred)
2706 << PlatformAndVersion->getOSVersion().getAsString()
2707 << PlatformAndVersion->getInferredSource();
2708 }
2709 // After the deployment OS version has been resolved, set it to the canonical
2710 // version before further error detection and converting to a proper target
2711 // triple.
2712 VersionTuple CanonicalVersion = PlatformAndVersion->getCanonicalOSVersion();
2713 if (CanonicalVersion != PlatformAndVersion->getOSVersion()) {
2714 getDriver().Diag(diag::warn_drv_overriding_deployment_version)
2715 << PlatformAndVersion->getOSVersion().getAsString()
2716 << CanonicalVersion.getAsString();
2717 PlatformAndVersion->setOSVersion(CanonicalVersion);
2718 }
2719
2720 PlatformAndVersion->addOSVersionMinArgument(Args, Opts);
2721 DarwinPlatformKind Platform = PlatformAndVersion->getPlatform();
2722
2723 unsigned Major, Minor, Micro;
2724 bool HadExtra;
2725 // The major version should not be over this number.
2726 const unsigned MajorVersionLimit = 1000;
2727 const VersionTuple OSVersion = PlatformAndVersion->takeOSVersion();
2728 const std::string OSVersionStr = OSVersion.getAsString();
2729 // Set the tool chain target information.
2730 if (Platform == MacOS) {
2731#ifdef CLANG_USE_XCSELECT
2732 if (TryXcselect) {
2733 char *p;
2734 if (!::xcselect_host_sdk_path(CLANG_XCSELECT_HOST_SDK_POLICY, &p)) {
2735 Args.append(Args.MakeSeparateArg(
2736 nullptr, Opts.getOption(options::OPT_isysroot), p));
2737 ::free(p);
2738 if (!SDKInfo)
2739 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
2740 }
2741 }
2742#endif
2743 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2744 HadExtra) ||
2745 HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||
2746 Micro >= 100)
2747 getDriver().Diag(diag::err_drv_invalid_version_number)
2748 << PlatformAndVersion->getAsString(Args, Opts);
2749 } else if (Platform == IPhoneOS) {
2750 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2751 HadExtra) ||
2752 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2753 getDriver().Diag(diag::err_drv_invalid_version_number)
2754 << PlatformAndVersion->getAsString(Args, Opts);
2755 ;
2756 if (PlatformAndVersion->getEnvironment() == MacCatalyst &&
2757 (Major < 13 || (Major == 13 && Minor < 1))) {
2758 getDriver().Diag(diag::err_drv_invalid_version_number)
2759 << PlatformAndVersion->getAsString(Args, Opts);
2760 Major = 13;
2761 Minor = 1;
2762 Micro = 0;
2763 }
2764 // For 32-bit targets, the deployment target for iOS has to be earlier than
2765 // iOS 11.
2766 if (getTriple().isArch32Bit() && Major >= 11) {
2767 // If the deployment target is explicitly specified, print a diagnostic.
2768 if (PlatformAndVersion->isExplicitlySpecified()) {
2769 if (PlatformAndVersion->getEnvironment() == MacCatalyst)
2770 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
2771 else
2772 getDriver().Diag(diag::warn_invalid_ios_deployment_target)
2773 << PlatformAndVersion->getAsString(Args, Opts);
2774 // Otherwise, set it to 10.99.99.
2775 } else {
2776 Major = 10;
2777 Minor = 99;
2778 Micro = 99;
2779 }
2780 }
2781 } else if (Platform == TvOS) {
2782 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2783 HadExtra) ||
2784 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2785 getDriver().Diag(diag::err_drv_invalid_version_number)
2786 << PlatformAndVersion->getAsString(Args, Opts);
2787 } else if (Platform == WatchOS) {
2788 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2789 HadExtra) ||
2790 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2791 getDriver().Diag(diag::err_drv_invalid_version_number)
2792 << PlatformAndVersion->getAsString(Args, Opts);
2793 } else if (Platform == DriverKit) {
2794 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2795 HadExtra) ||
2796 HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||
2797 Micro >= 100)
2798 getDriver().Diag(diag::err_drv_invalid_version_number)
2799 << PlatformAndVersion->getAsString(Args, Opts);
2800 } else {
2801 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2802 HadExtra) ||
2803 HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||
2804 Micro >= 100)
2805 getDriver().Diag(diag::err_drv_invalid_version_number)
2806 << PlatformAndVersion->getAsString(Args, Opts);
2807 }
2808
2809 DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();
2810 // Recognize iOS targets with an x86 architecture as the iOS simulator.
2811 if (Environment == NativeEnvironment && Platform != MacOS &&
2812 Platform != DriverKit &&
2813 PlatformAndVersion->canInferSimulatorFromArch() && getTriple().isX86())
2814 Environment = Simulator;
2815
2816 VersionTuple ZipperedOSVersion;
2817 if (Environment == MacCatalyst)
2818 ZipperedOSVersion = PlatformAndVersion->getZipperedOSVersion();
2819 setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);
2820 TargetVariantTriple = PlatformAndVersion->getTargetVariantTriple();
2821 if (TargetVariantTriple &&
2822 !llvm::Triple::isValidVersionForOS(TargetVariantTriple->getOS(),
2823 TargetVariantTriple->getOSVersion())) {
2824 getDriver().Diag(diag::err_drv_invalid_version_number)
2825 << TargetVariantTriple->str();
2826 }
2827}
2828
2829bool DarwinClang::HasPlatformPrefix(const llvm::Triple &T) const {
2830 if (SDKInfo)
2831 return !SDKInfo->getPlatformPrefix(T).empty();
2832 else
2833 return Darwin::HasPlatformPrefix(T);
2834}
2835
2836// For certain platforms/environments almost all resources (e.g., headers) are
2837// located in sub-directories, e.g., for DriverKit they live in
2838// <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).
2840 const llvm::Triple &T) const {
2841 if (SDKInfo) {
2842 const StringRef PlatformPrefix = SDKInfo->getPlatformPrefix(T);
2843 if (!PlatformPrefix.empty())
2844 llvm::sys::path::append(Path, PlatformPrefix);
2845 } else if (T.isDriverKit()) {
2846 // The first version of DriverKit didn't have SDKSettings.json, manually add
2847 // its prefix.
2848 llvm::sys::path::append(Path, "System", "DriverKit");
2849 }
2850}
2851
2852// Returns the effective sysroot from either -isysroot or --sysroot, plus the
2853// platform prefix (if any).
2855AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
2856 llvm::SmallString<128> Path("/");
2857 if (DriverArgs.hasArg(options::OPT_isysroot))
2858 Path = DriverArgs.getLastArgValue(options::OPT_isysroot);
2859 else if (!getDriver().SysRoot.empty())
2860 Path = getDriver().SysRoot;
2861
2862 if (hasEffectiveTriple()) {
2864 }
2865 return Path;
2866}
2867
2869 const llvm::opt::ArgList &DriverArgs,
2870 llvm::opt::ArgStringList &CC1Args) const {
2871 const Driver &D = getDriver();
2872
2873 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2874
2875 bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);
2876 bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);
2877 bool NoBuiltinInc = DriverArgs.hasFlag(
2878 options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false);
2879 bool ForceBuiltinInc = DriverArgs.hasFlag(
2880 options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false);
2881
2882 // Add <sysroot>/usr/local/include
2883 if (!NoStdInc && !NoStdlibInc) {
2884 SmallString<128> P(Sysroot);
2885 llvm::sys::path::append(P, "usr", "local", "include");
2886 addSystemInclude(DriverArgs, CC1Args, P);
2887 }
2888
2889 // Add the Clang builtin headers (<resource>/include)
2890 if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) {
2891 SmallString<128> P(D.ResourceDir);
2892 llvm::sys::path::append(P, "include");
2893 addSystemInclude(DriverArgs, CC1Args, P);
2894 }
2895
2896 if (NoStdInc || NoStdlibInc)
2897 return;
2898
2899 // Check for configure-time C include directories.
2900 llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
2901 if (!CIncludeDirs.empty()) {
2903 CIncludeDirs.split(dirs, ":");
2904 for (llvm::StringRef dir : dirs) {
2905 llvm::StringRef Prefix =
2906 llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot);
2907 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
2908 }
2909 } else {
2910 // Otherwise, add <sysroot>/usr/include.
2911 SmallString<128> P(Sysroot);
2912 llvm::sys::path::append(P, "usr", "include");
2913 addExternCSystemInclude(DriverArgs, CC1Args, P.str());
2914 }
2915}
2916
2918 const llvm::opt::ArgList &DriverArgs,
2919 llvm::opt::ArgStringList &CC1Args) const {
2920 AppleMachO::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
2921
2922 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc))
2923 return;
2924
2925 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2926
2927 // Add <sysroot>/System/Library/Frameworks
2928 // Add <sysroot>/System/Library/SubFrameworks
2929 // Add <sysroot>/Library/Frameworks
2930 SmallString<128> P1(Sysroot), P2(Sysroot), P3(Sysroot);
2931 llvm::sys::path::append(P1, "System", "Library", "Frameworks");
2932 llvm::sys::path::append(P2, "System", "Library", "SubFrameworks");
2933 llvm::sys::path::append(P3, "Library", "Frameworks");
2934 addSystemFrameworkIncludes(DriverArgs, CC1Args, {P1, P2, P3});
2935}
2936
2937bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
2938 llvm::opt::ArgStringList &CC1Args,
2940 llvm::StringRef Version,
2941 llvm::StringRef ArchDir,
2942 llvm::StringRef BitDir) const {
2943 llvm::sys::path::append(Base, Version);
2944
2945 // Add the base dir
2946 addSystemInclude(DriverArgs, CC1Args, Base);
2947
2948 // Add the multilib dirs
2949 {
2951 if (!ArchDir.empty())
2952 llvm::sys::path::append(P, ArchDir);
2953 if (!BitDir.empty())
2954 llvm::sys::path::append(P, BitDir);
2955 addSystemInclude(DriverArgs, CC1Args, P);
2956 }
2957
2958 // Add the backward dir
2959 {
2961 llvm::sys::path::append(P, "backward");
2962 addSystemInclude(DriverArgs, CC1Args, P);
2963 }
2964
2965 return getVFS().exists(Base);
2966}
2967
2969 const llvm::opt::ArgList &DriverArgs,
2970 llvm::opt::ArgStringList &CC1Args) const {
2971 // The implementation from a base class will pass through the -stdlib to
2972 // CC1Args.
2973 // FIXME: this should not be necessary, remove usages in the frontend
2974 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
2975 // Also check whether this is used for setting library search paths.
2976 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
2977
2978 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
2979 options::OPT_nostdincxx))
2980 return;
2981
2982 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2983
2984 switch (GetCXXStdlibType(DriverArgs)) {
2985 case ToolChain::CST_Libcxx: {
2986 // On Darwin, libc++ can be installed in one of the following places:
2987 // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
2988 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
2989 //
2990 // The precedence of paths is as listed above, i.e. we take the first path
2991 // that exists. Note that we never include libc++ twice -- we take the first
2992 // path that exists and don't send the other paths to CC1 (otherwise
2993 // include_next could break).
2994
2995 // Check for (1)
2996 // Get from '<install>/bin' to '<install>/include/c++/v1'.
2997 // Note that InstallBin can be relative, so we use '..' instead of
2998 // parent_path.
2999 llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin
3000 llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
3001 if (getVFS().exists(InstallBin)) {
3002 addSystemInclude(DriverArgs, CC1Args, InstallBin);
3003 return;
3004 } else if (DriverArgs.hasArg(options::OPT_v)) {
3005 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
3006 << "\"\n";
3007 }
3008
3009 // Otherwise, check for (2)
3010 llvm::SmallString<128> SysrootUsr = Sysroot;
3011 llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
3012 if (getVFS().exists(SysrootUsr)) {
3013 addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
3014 return;
3015 } else if (DriverArgs.hasArg(options::OPT_v)) {
3016 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
3017 << "\"\n";
3018 }
3019
3020 // Otherwise, don't add any path.
3021 break;
3022 }
3023
3025 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
3026 break;
3027 }
3028}
3029
3030void AppleMachO::AddGnuCPlusPlusIncludePaths(
3031 const llvm::opt::ArgList &DriverArgs,
3032 llvm::opt::ArgStringList &CC1Args) const {}
3033
3034void DarwinClang::AddGnuCPlusPlusIncludePaths(
3035 const llvm::opt::ArgList &DriverArgs,
3036 llvm::opt::ArgStringList &CC1Args) const {
3037 llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);
3038 llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
3039
3040 llvm::Triple::ArchType arch = getTriple().getArch();
3041 bool IsBaseFound = true;
3042 switch (arch) {
3043 default:
3044 break;
3045
3046 case llvm::Triple::x86:
3047 case llvm::Triple::x86_64:
3048 IsBaseFound = AddGnuCPlusPlusIncludePaths(
3049 DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",
3050 arch == llvm::Triple::x86_64 ? "x86_64" : "");
3051 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
3052 DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");
3053 break;
3054
3055 case llvm::Triple::arm:
3056 case llvm::Triple::thumb:
3057 IsBaseFound =
3058 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
3059 "arm-apple-darwin10", "v7");
3060 IsBaseFound |=
3061 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
3062 "arm-apple-darwin10", "v6");
3063 break;
3064
3065 case llvm::Triple::aarch64:
3066 IsBaseFound =
3067 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
3068 "arm64-apple-darwin10", "");
3069 break;
3070 }
3071
3072 if (!IsBaseFound) {
3073 getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
3074 }
3075}
3076
3077void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
3078 ArgStringList &CmdArgs) const {
3080
3081 switch (Type) {
3083 CmdArgs.push_back("-lc++");
3084 if (Args.hasArg(options::OPT_fexperimental_library))
3085 CmdArgs.push_back("-lc++experimental");
3086 break;
3087
3089 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
3090 // it was previously found in the gcc lib dir. However, for all the Darwin
3091 // platforms we care about it was -lstdc++.6, so we search for that
3092 // explicitly if we can't see an obvious -lstdc++ candidate.
3093
3094 // Check in the sysroot first.
3095 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
3096 SmallString<128> P(A->getValue());
3097 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
3098
3099 if (!getVFS().exists(P)) {
3100 llvm::sys::path::remove_filename(P);
3101 llvm::sys::path::append(P, "libstdc++.6.dylib");
3102 if (getVFS().exists(P)) {
3103 CmdArgs.push_back(Args.MakeArgString(P));
3104 return;
3105 }
3106 }
3107 }
3108
3109 // Otherwise, look in the root.
3110 // FIXME: This should be removed someday when we don't have to care about
3111 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
3112 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
3113 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
3114 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
3115 return;
3116 }
3117
3118 // Otherwise, let the linker search.
3119 CmdArgs.push_back("-lstdc++");
3120 break;
3121 }
3122}
3123
3124void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
3125 ArgStringList &CmdArgs) const {
3126 // For Darwin platforms, use the compiler-rt-based support library
3127 // instead of the gcc-provided one (which is also incidentally
3128 // only present in the gcc lib dir, which makes it hard to find).
3129
3130 SmallString<128> P(getDriver().ResourceDir);
3131 llvm::sys::path::append(P, "lib", "darwin");
3132
3133 // Use the newer cc_kext for iOS ARM after 6.0.
3134 if (isTargetWatchOS()) {
3135 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
3136 } else if (isTargetTvOS()) {
3137 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
3138 } else if (isTargetIPhoneOS()) {
3139 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
3140 } else if (isTargetDriverKit()) {
3141 // DriverKit doesn't want extra runtime support.
3142 } else if (isTargetXROSDevice()) {
3143 llvm::sys::path::append(
3144 P, llvm::Twine("libclang_rt.cc_kext_") +
3145 llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a");
3146 } else {
3147 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
3148 }
3149
3150 // For now, allow missing resource libraries to support developers who may
3151 // not have compiler-rt checked out or integrated into their build.
3152 if (getVFS().exists(P))
3153 CmdArgs.push_back(Args.MakeArgString(P));
3154}
3155
3156DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
3157 StringRef BoundArch,
3158 Action::OffloadKind) const {
3159 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
3160 const OptTable &Opts = getDriver().getOpts();
3161
3162 // FIXME: We really want to get out of the tool chain level argument
3163 // translation business, as it makes the driver functionality much
3164 // more opaque. For now, we follow gcc closely solely for the
3165 // purpose of easily achieving feature parity & testability. Once we
3166 // have something that works, we should reevaluate each translation
3167 // and try to push it down into tool specific logic.
3168
3169 for (Arg *A : Args) {
3170 // Sob. These is strictly gcc compatible for the time being. Apple
3171 // gcc translates options twice, which means that self-expanding
3172 // options add duplicates.
3173 switch ((options::ID)A->getOption().getID()) {
3174 default:
3175 DAL->append(A);
3176 break;
3177
3178 case options::OPT_mkernel:
3179 case options::OPT_fapple_kext:
3180 DAL->append(A);
3181 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
3182 break;
3183
3184 case options::OPT_dependency_file:
3185 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
3186 break;
3187
3188 case options::OPT_gfull:
3189 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
3190 DAL->AddFlagArg(
3191 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
3192 break;
3193
3194 case options::OPT_gused:
3195 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
3196 DAL->AddFlagArg(
3197 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
3198 break;
3199
3200 case options::OPT_shared:
3201 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
3202 break;
3203
3204 case options::OPT_fconstant_cfstrings:
3205 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
3206 break;
3207
3208 case options::OPT_fno_constant_cfstrings:
3209 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
3210 break;
3211
3212 case options::OPT_Wnonportable_cfstrings:
3213 DAL->AddFlagArg(A,
3214 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
3215 break;
3216
3217 case options::OPT_Wno_nonportable_cfstrings:
3218 DAL->AddFlagArg(
3219 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
3220 break;
3221 }
3222 }
3223
3224 // Add the arch options based on the particular spelling of -arch, to match
3225 // how the driver works.
3226 if (!BoundArch.empty()) {
3227 StringRef Name = BoundArch;
3228 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
3229 const Option MArch = Opts.getOption(options::OPT_march_EQ);
3230
3231 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
3232 // which defines the list of which architectures we accept.
3233 if (Name == "ppc")
3234 ;
3235 else if (Name == "ppc601")
3236 DAL->AddJoinedArg(nullptr, MCpu, "601");
3237 else if (Name == "ppc603")
3238 DAL->AddJoinedArg(nullptr, MCpu, "603");
3239 else if (Name == "ppc604")
3240 DAL->AddJoinedArg(nullptr, MCpu, "604");
3241 else if (Name == "ppc604e")
3242 DAL->AddJoinedArg(nullptr, MCpu, "604e");
3243 else if (Name == "ppc750")
3244 DAL->AddJoinedArg(nullptr, MCpu, "750");
3245 else if (Name == "ppc7400")
3246 DAL->AddJoinedArg(nullptr, MCpu, "7400");
3247 else if (Name == "ppc7450")
3248 DAL->AddJoinedArg(nullptr, MCpu, "7450");
3249 else if (Name == "ppc970")
3250 DAL->AddJoinedArg(nullptr, MCpu, "970");
3251
3252 else if (Name == "ppc64" || Name == "ppc64le")
3253 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3254
3255 else if (Name == "i386")
3256 ;
3257 else if (Name == "i486")
3258 DAL->AddJoinedArg(nullptr, MArch, "i486");
3259 else if (Name == "i586")
3260 DAL->AddJoinedArg(nullptr, MArch, "i586");
3261 else if (Name == "i686")
3262 DAL->AddJoinedArg(nullptr, MArch, "i686");
3263 else if (Name == "pentium")
3264 DAL->AddJoinedArg(nullptr, MArch, "pentium");
3265 else if (Name == "pentium2")
3266 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3267 else if (Name == "pentpro")
3268 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
3269 else if (Name == "pentIIm3")
3270 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3271
3272 else if (Name == "x86_64" || Name == "x86_64h")
3273 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3274
3275 else if (Name == "arm")
3276 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3277 else if (Name == "armv4t")
3278 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3279 else if (Name == "armv5")
3280 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
3281 else if (Name == "xscale")
3282 DAL->AddJoinedArg(nullptr, MArch, "xscale");
3283 else if (Name == "armv6")
3284 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
3285 else if (Name == "armv6m")
3286 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
3287 else if (Name == "armv7")
3288 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
3289 else if (Name == "armv7em")
3290 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
3291 else if (Name == "armv7k")
3292 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
3293 else if (Name == "armv7m")
3294 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
3295 else if (Name == "armv7s")
3296 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
3297 else if (Name == "armv8-m.base" || Name == "armv8m.base")
3298 DAL->AddJoinedArg(nullptr, MArch, "armv8m.base");
3299 else if (Name == "armv8-m.main" || Name == "armv8m.main")
3300 DAL->AddJoinedArg(nullptr, MArch, "armv8m.main");
3301 else if (Name == "armv8.1-m.main" || Name == "armv8.1m.main")
3302 DAL->AddJoinedArg(nullptr, MArch, "armv8.1m.main");
3303 }
3304
3305 return DAL;
3306}
3307
3308void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
3309 ArgStringList &CmdArgs,
3310 bool ForceLinkBuiltinRT) const {
3311 // Embedded targets are simple at the moment, not supporting sanitizers and
3312 // with different libraries for each member of the product { static, PIC } x
3313 // { hard-float, soft-float }
3314 llvm::SmallString<32> CompilerRT = StringRef("");
3315 CompilerRT +=
3317 ? "hard"
3318 : "soft";
3319 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static";
3320
3321 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);
3322}
3323
3325 llvm::Triple::OSType OS;
3326
3327 if (isTargetMacCatalyst())
3328 return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX);
3329 switch (TargetPlatform) {
3330 case MacOS: // Earlier than 10.13.
3331 OS = llvm::Triple::MacOSX;
3332 break;
3333 case IPhoneOS:
3334 OS = llvm::Triple::IOS;
3335 break;
3336 case TvOS: // Earlier than 11.0.
3337 OS = llvm::Triple::TvOS;
3338 break;
3339 case WatchOS: // Earlier than 4.0.
3340 OS = llvm::Triple::WatchOS;
3341 break;
3342 default: // Always available on newer platforms.
3343 return false;
3344 }
3345
3347}
3348
3349static bool
3350sdkSupportsBuiltinModules(const std::optional<DarwinSDKInfo> &SDKInfo) {
3351 if (!SDKInfo)
3352 // If there is no SDK info, assume this is building against an SDK that
3353 // predates SDKSettings.json. None of those support builtin modules.
3354 return false;
3355
3356 switch (SDKInfo->getEnvironment()) {
3357 case llvm::Triple::UnknownEnvironment:
3358 case llvm::Triple::Simulator:
3359 case llvm::Triple::MacABI:
3360 // Standard xnu/Mach/Darwin based environments depend on the SDK version.
3361 break;
3362
3363 default:
3364 // All other environments support builtin modules from the start.
3365 return true;
3366 }
3367
3368 VersionTuple SDKVersion = SDKInfo->getVersion();
3369 switch (SDKInfo->getOS()) {
3370 // Existing SDKs added support for builtin modules in the fall
3371 // 2024 major releases.
3372 case llvm::Triple::MacOSX:
3373 return SDKVersion >= VersionTuple(15U);
3374 case llvm::Triple::IOS:
3375 return SDKVersion >= VersionTuple(18U);
3376 case llvm::Triple::TvOS:
3377 return SDKVersion >= VersionTuple(18U);
3378 case llvm::Triple::WatchOS:
3379 return SDKVersion >= VersionTuple(11U);
3380 case llvm::Triple::XROS:
3381 return SDKVersion >= VersionTuple(2U);
3382
3383 // New SDKs support builtin modules from the start.
3384 default:
3385 return true;
3386 }
3387}
3388
3389static inline llvm::VersionTuple
3390sizedDeallocMinVersion(llvm::Triple::OSType OS) {
3391 switch (OS) {
3392 default:
3393 break;
3394 case llvm::Triple::Darwin:
3395 case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.
3396 return llvm::VersionTuple(10U, 12U);
3397 case llvm::Triple::IOS:
3398 case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0.
3399 return llvm::VersionTuple(10U);
3400 case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0.
3401 return llvm::VersionTuple(3U);
3402 }
3403
3404 llvm_unreachable("Unexpected OS");
3405}
3406
3408 llvm::Triple::OSType OS;
3409
3410 if (isTargetMacCatalyst())
3411 return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX);
3412 switch (TargetPlatform) {
3413 case MacOS: // Earlier than 10.12.
3414 OS = llvm::Triple::MacOSX;
3415 break;
3416 case IPhoneOS:
3417 OS = llvm::Triple::IOS;
3418 break;
3419 case TvOS: // Earlier than 10.0.
3420 OS = llvm::Triple::TvOS;
3421 break;
3422 case WatchOS: // Earlier than 3.0.
3423 OS = llvm::Triple::WatchOS;
3424 break;
3425 default:
3426 // Always available on newer platforms.
3427 return false;
3428 }
3429
3431}
3432
3433void MachO::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
3434 llvm::opt::ArgStringList &CC1Args,
3435 Action::OffloadKind DeviceOffloadKind) const {
3436
3437 ToolChain::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3438
3439 // On arm64e, we enable all the features required for the Darwin userspace
3440 // ABI
3441 if (getTriple().isArm64e()) {
3442 // Core platform ABI
3443 if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
3444 options::OPT_fno_ptrauth_calls))
3445 CC1Args.push_back("-fptrauth-calls");
3446 if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
3447 options::OPT_fno_ptrauth_returns))
3448 CC1Args.push_back("-fptrauth-returns");
3449 if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
3450 options::OPT_fno_ptrauth_intrinsics))
3451 CC1Args.push_back("-fptrauth-intrinsics");
3452 if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos,
3453 options::OPT_fno_ptrauth_indirect_gotos))
3454 CC1Args.push_back("-fptrauth-indirect-gotos");
3455 if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
3456 options::OPT_fno_ptrauth_auth_traps))
3457 CC1Args.push_back("-fptrauth-auth-traps");
3458
3459 // C++ v-table ABI
3460 if (!DriverArgs.hasArg(
3461 options::OPT_fptrauth_vtable_pointer_address_discrimination,
3462 options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
3463 CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
3464 if (!DriverArgs.hasArg(
3465 options::OPT_fptrauth_vtable_pointer_type_discrimination,
3466 options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
3467 CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
3468
3469 // Objective-C ABI
3470 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_isa,
3471 options::OPT_fno_ptrauth_objc_isa))
3472 CC1Args.push_back("-fptrauth-objc-isa");
3473 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_class_ro,
3474 options::OPT_fno_ptrauth_objc_class_ro))
3475 CC1Args.push_back("-fptrauth-objc-class-ro");
3476 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_interface_sel,
3477 options::OPT_fno_ptrauth_objc_interface_sel))
3478 CC1Args.push_back("-fptrauth-objc-interface-sel");
3479 }
3480}
3481
3483 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
3484 Action::OffloadKind DeviceOffloadKind) const {
3485
3486 MachO::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3487
3488 // When compiling device code (e.g. SPIR-V for HIP), skip host-specific
3489 // flags like -faligned-alloc-unavailable and -fno-sized-deallocation
3490 // that depend on the host OS version and are irrelevant to device code.
3491 if (DeviceOffloadKind != Action::OFK_None)
3492 return;
3493
3494 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
3495 // enabled or disabled aligned allocations.
3496 if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
3497 options::OPT_fno_aligned_allocation) &&
3499 CC1Args.push_back("-faligned-alloc-unavailable");
3500
3501 // Enable objc_msgSend selector stubs by default if the linker supports it.
3502 // ld64-811.2+ does, for arm64, arm64e, and arm64_32.
3503 if (!DriverArgs.hasArgNoClaim(options::OPT_fobjc_msgsend_selector_stubs,
3504 options::OPT_fno_objc_msgsend_selector_stubs) &&
3505 getTriple().isAArch64() &&
3506 (getLinkerVersion(DriverArgs) >= VersionTuple(811, 2)))
3507 CC1Args.push_back("-fobjc-msgsend-selector-stubs");
3508
3509 // Enable objc_msgSend class selector stubs by default if the linker supports
3510 // it. ld64-1250+ does, for arm64, arm64e, and arm64_32.
3511 if (!DriverArgs.hasArgNoClaim(
3512 options::OPT_fobjc_msgsend_class_selector_stubs,
3513 options::OPT_fno_objc_msgsend_class_selector_stubs) &&
3514 getTriple().isAArch64() &&
3515 (getLinkerVersion(DriverArgs) >= VersionTuple(1250, 0)))
3516 CC1Args.push_back("-fobjc-msgsend-class-selector-stubs");
3517
3518 // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
3519 // or disabled sized deallocations.
3520 if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,
3521 options::OPT_fno_sized_deallocation) &&
3523 CC1Args.push_back("-fno-sized-deallocation");
3524
3525 addClangCC1ASTargetOptions(DriverArgs, CC1Args);
3526
3527 if (SDKInfo) {
3528 // Make the SDKSettings.json an explicit dependency for the compiler
3529 // invocation, in case the compiler needs to read it to remap versions.
3530 if (!SDKInfo->getFilePath().empty()) {
3531 SmallString<64> ExtraDepOpt("-fdepfile-entry=");
3532 ExtraDepOpt += SDKInfo->getFilePath();
3533 CC1Args.push_back(DriverArgs.MakeArgString(ExtraDepOpt));
3534 }
3535 }
3536
3537 // Enable compatibility mode for NSItemProviderCompletionHandler in
3538 // Foundation/NSItemProvider.h.
3539 CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking");
3540
3541 // Give static local variables in inline functions hidden visibility when
3542 // -fvisibility-inlines-hidden is enabled.
3543 if (!DriverArgs.getLastArgNoClaim(
3544 options::OPT_fvisibility_inlines_hidden_static_local_var,
3545 options::OPT_fno_visibility_inlines_hidden_static_local_var))
3546 CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");
3547
3548 // Earlier versions of the darwin SDK have the C standard library headers
3549 // all together in the Darwin module. That leads to module cycles with
3550 // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.
3551 // The builtin <stdint.h> include-nexts <stdint.h>. When both of those
3552 // darwin headers are in the Darwin module, there's a module cycle Darwin ->
3553 // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->
3554 // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,
3555 // but until then, the builtin headers need to join the system modules.
3556 // i.e. when the builtin stdint.h is in the Darwin module too, the cycle
3557 // goes away. Note that -fbuiltin-headers-in-system-modules does nothing
3558 // to fix the same problem with C++ headers, and is generally fragile.
3560 CC1Args.push_back("-fbuiltin-headers-in-system-modules");
3561
3562 if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros,
3563 options::OPT_fno_define_target_os_macros))
3564 CC1Args.push_back("-fdefine-target-os-macros");
3565
3566 // Disable subdirectory modulemap search on sufficiently recent SDKs.
3567 if (SDKInfo &&
3568 !DriverArgs.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search,
3569 options::OPT_fno_modulemap_allow_subdirectory_search,
3570 false)) {
3571 bool RequiresSubdirectorySearch;
3572 VersionTuple SDKVersion = SDKInfo->getVersion();
3573 switch (TargetPlatform) {
3574 default:
3575 RequiresSubdirectorySearch = true;
3576 break;
3577 case MacOS:
3578 RequiresSubdirectorySearch = SDKVersion < VersionTuple(15, 0);
3579 break;
3580 case IPhoneOS:
3581 case TvOS:
3582 RequiresSubdirectorySearch = SDKVersion < VersionTuple(18, 0);
3583 break;
3584 case WatchOS:
3585 RequiresSubdirectorySearch = SDKVersion < VersionTuple(11, 0);
3586 break;
3587 case XROS:
3588 RequiresSubdirectorySearch = SDKVersion < VersionTuple(2, 0);
3589 break;
3590 }
3591 if (!RequiresSubdirectorySearch)
3592 CC1Args.push_back("-fno-modulemap-allow-subdirectory-search");
3593 }
3594}
3595
3597 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const {
3598 if (TargetVariantTriple) {
3599 CC1ASArgs.push_back("-darwin-target-variant-triple");
3600 CC1ASArgs.push_back(Args.MakeArgString(TargetVariantTriple->getTriple()));
3601 }
3602
3603 if (SDKInfo) {
3604 /// Pass the SDK version to the compiler when the SDK information is
3605 /// available.
3606 auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) {
3607 std::string Arg;
3608 llvm::raw_string_ostream OS(Arg);
3609 OS << "-target-sdk-version=" << V;
3610 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3611 };
3612
3613 if (isTargetMacCatalyst()) {
3614 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
3616 std::optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(
3618 std::nullopt);
3619 EmitTargetSDKVersionArg(
3620 SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget());
3621 }
3622 } else {
3623 EmitTargetSDKVersionArg(SDKInfo->getVersion());
3624 }
3625
3626 /// Pass the target variant SDK version to the compiler when the SDK
3627 /// information is available and is required for target variant.
3628 if (TargetVariantTriple) {
3629 if (isTargetMacCatalyst()) {
3630 std::string Arg;
3631 llvm::raw_string_ostream OS(Arg);
3632 OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();
3633 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3634 } else if (const auto *MacOStoMacCatalystMapping =
3635 SDKInfo->getVersionMapping(
3637 if (std::optional<VersionTuple> SDKVersion =
3638 MacOStoMacCatalystMapping->map(
3640 std::nullopt)) {
3641 std::string Arg;
3642 llvm::raw_string_ostream OS(Arg);
3643 OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;
3644 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3645 }
3646 }
3647 }
3648 }
3649}
3650
3651DerivedArgList *
3652Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
3653 Action::OffloadKind DeviceOffloadKind) const {
3654 // First get the generic Apple args, before moving onto Darwin-specific ones.
3655 DerivedArgList *DAL =
3656 MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
3657
3658 // If no architecture is bound, none of the translations here are relevant.
3659 if (BoundArch.empty())
3660 return DAL;
3661
3662 // Add an explicit version min argument for the deployment target. We do this
3663 // after argument translation because -Xarch_ arguments may add a version min
3664 // argument.
3665 AddDeploymentTarget(*DAL);
3666
3667 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
3668 // FIXME: It would be far better to avoid inserting those -static arguments,
3669 // but we can't check the deployment target in the translation code until
3670 // it is set here.
3672 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
3673 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
3674 Arg *A = *it;
3675 ++it;
3676 if (A->getOption().getID() != options::OPT_mkernel &&
3677 A->getOption().getID() != options::OPT_fapple_kext)
3678 continue;
3679 assert(it != ie && "unexpected argument translation");
3680 A = *it;
3681 assert(A->getOption().getID() == options::OPT_static &&
3682 "missing expected -static argument");
3683 *it = nullptr;
3684 ++it;
3685 }
3686 }
3687
3689 if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {
3690 if (Args.hasFlag(options::OPT_fomit_frame_pointer,
3691 options::OPT_fno_omit_frame_pointer, false))
3692 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
3693 << "-fomit-frame-pointer" << BoundArch;
3694 }
3695
3696 return DAL;
3697}
3698
3700 // Unwind tables are not emitted if -fno-exceptions is supplied (except when
3701 // targeting x86_64).
3702 if (getArch() == llvm::Triple::x86_64 ||
3703 (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&
3704 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
3705 true)))
3706 return (getArch() == llvm::Triple::aarch64 ||
3707 getArch() == llvm::Triple::aarch64_32)
3710
3712}
3713
3715 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
3716 return S[0] != '\0';
3717 return false;
3718}
3719
3721 if (const char *S = ::getenv("RC_DEBUG_PREFIX_MAP"))
3722 return S;
3723 return {};
3724}
3725
3726llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {
3727 // Darwin uses SjLj exceptions on ARM.
3728 if (getTriple().getArch() != llvm::Triple::arm &&
3729 getTriple().getArch() != llvm::Triple::thumb)
3730 return llvm::ExceptionHandling::None;
3731
3732 // Only watchOS uses the new DWARF/Compact unwinding method.
3733 llvm::Triple Triple(ComputeLLVMTriple(Args));
3734 if (Triple.isWatchABI())
3735 return llvm::ExceptionHandling::DwarfCFI;
3736
3737 return llvm::ExceptionHandling::SjLj;
3738}
3739
3741 assert(TargetInitialized && "Target not initialized!");
3743 return false;
3744 return true;
3745}
3746
3747bool MachO::isPICDefault() const { return true; }
3748
3749bool MachO::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; }
3750
3752 return (getArch() == llvm::Triple::x86_64 ||
3753 getArch() == llvm::Triple::aarch64);
3754}
3755
3757 // Profiling instrumentation is only supported on x86.
3758 return getTriple().isX86();
3759}
3760
3761void Darwin::addMinVersionArgs(const ArgList &Args,
3762 ArgStringList &CmdArgs) const {
3763 VersionTuple TargetVersion = getTripleTargetVersion();
3764
3765 assert(!isTargetXROS() && "xrOS always uses -platform-version");
3766
3767 if (isTargetWatchOS())
3768 CmdArgs.push_back("-watchos_version_min");
3769 else if (isTargetWatchOSSimulator())
3770 CmdArgs.push_back("-watchos_simulator_version_min");
3771 else if (isTargetTvOS())
3772 CmdArgs.push_back("-tvos_version_min");
3773 else if (isTargetTvOSSimulator())
3774 CmdArgs.push_back("-tvos_simulator_version_min");
3775 else if (isTargetDriverKit())
3776 CmdArgs.push_back("-driverkit_version_min");
3777 else if (isTargetIOSSimulator())
3778 CmdArgs.push_back("-ios_simulator_version_min");
3779 else if (isTargetIOSBased())
3780 CmdArgs.push_back("-iphoneos_version_min");
3781 else if (isTargetMacCatalyst())
3782 CmdArgs.push_back("-maccatalyst_version_min");
3783 else {
3784 assert(isTargetMacOS() && "unexpected target");
3785 CmdArgs.push_back("-macosx_version_min");
3786 }
3787
3788 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
3789 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3790 TargetVersion = MinTgtVers;
3791 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3792 if (TargetVariantTriple) {
3793 assert(isTargetMacOSBased() && "unexpected target");
3794 VersionTuple VariantTargetVersion;
3795 if (TargetVariantTriple->isMacOSX()) {
3796 CmdArgs.push_back("-macosx_version_min");
3797 TargetVariantTriple->getMacOSXVersion(VariantTargetVersion);
3798 } else {
3799 assert(TargetVariantTriple->isiOS() &&
3800 TargetVariantTriple->isMacCatalystEnvironment() &&
3801 "unexpected target variant triple");
3802 CmdArgs.push_back("-maccatalyst_version_min");
3803 VariantTargetVersion = TargetVariantTriple->getiOSVersion();
3804 }
3805 VersionTuple MinTgtVers =
3806 TargetVariantTriple->getMinimumSupportedOSVersion();
3807 if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion)
3808 VariantTargetVersion = MinTgtVers;
3809 CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString()));
3810 }
3811}
3812
3814 Darwin::DarwinEnvironmentKind Environment) {
3815 switch (Platform) {
3816 case Darwin::MacOS:
3817 return "macos";
3818 case Darwin::IPhoneOS:
3819 if (Environment == Darwin::MacCatalyst)
3820 return "mac catalyst";
3821 return "ios";
3822 case Darwin::TvOS:
3823 return "tvos";
3824 case Darwin::WatchOS:
3825 return "watchos";
3826 case Darwin::XROS:
3827 return "xros";
3828 case Darwin::DriverKit:
3829 return "driverkit";
3830 default:
3831 break;
3832 }
3833 llvm_unreachable("invalid platform");
3834}
3835
3836void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
3837 llvm::opt::ArgStringList &CmdArgs) const {
3838 // Firmware doesn't use -platform_version.
3840 return MachO::addPlatformVersionArgs(Args, CmdArgs);
3841
3842 auto EmitPlatformVersionArg =
3843 [&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,
3845 const llvm::Triple &TT) {
3846 // -platform_version <platform> <target_version> <sdk_version>
3847 // Both the target and SDK version support only up to 3 components.
3848 CmdArgs.push_back("-platform_version");
3849 std::string PlatformName =
3852 PlatformName += "-simulator";
3853 CmdArgs.push_back(Args.MakeArgString(PlatformName));
3854 VersionTuple TargetVersion = TV.withoutBuild();
3857 getTriple().getArchName() == "arm64e" &&
3858 TargetVersion.getMajor() < 14) {
3859 // arm64e slice is supported on iOS/tvOS 14+ only.
3860 TargetVersion = VersionTuple(14, 0);
3861 }
3862 VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion();
3863 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3864 TargetVersion = MinTgtVers;
3865 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3866
3868 // Mac Catalyst programs must use the appropriate iOS SDK version
3869 // that corresponds to the macOS SDK version used for the compilation.
3870 std::optional<VersionTuple> iOSSDKVersion;
3871 if (SDKInfo) {
3872 if (const auto *MacOStoMacCatalystMapping =
3873 SDKInfo->getVersionMapping(
3875 iOSSDKVersion = MacOStoMacCatalystMapping->map(
3876 SDKInfo->getVersion().withoutBuild(),
3877 minimumMacCatalystDeploymentTarget(), std::nullopt);
3878 }
3879 }
3880 CmdArgs.push_back(Args.MakeArgString(
3881 (iOSSDKVersion ? *iOSSDKVersion
3883 .getAsString()));
3884 return;
3885 }
3886
3887 if (SDKInfo) {
3888 VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
3889 if (!SDKVersion.getMinor())
3890 SDKVersion = VersionTuple(SDKVersion.getMajor(), 0);
3891 CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
3892 } else {
3893 // Use an SDK version that's matching the deployment target if the SDK
3894 // version is missing. This is preferred over an empty SDK version
3895 // (0.0.0) as the system's runtime might expect the linked binary to
3896 // contain a valid SDK version in order for the binary to work
3897 // correctly. It's reasonable to use the deployment target version as
3898 // a proxy for the SDK version because older SDKs don't guarantee
3899 // support for deployment targets newer than the SDK versions, so that
3900 // rules out using some predetermined older SDK version, which leaves
3901 // the deployment target version as the only reasonable choice.
3902 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3903 }
3904 };
3905 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform,
3908 return;
3911 VersionTuple TargetVariantVersion;
3912 if (TargetVariantTriple->isMacOSX()) {
3913 TargetVariantTriple->getMacOSXVersion(TargetVariantVersion);
3914 Platform = Darwin::MacOS;
3915 Environment = Darwin::NativeEnvironment;
3916 } else {
3917 assert(TargetVariantTriple->isiOS() &&
3918 TargetVariantTriple->isMacCatalystEnvironment() &&
3919 "unexpected target variant triple");
3920 TargetVariantVersion = TargetVariantTriple->getiOSVersion();
3921 Platform = Darwin::IPhoneOS;
3922 Environment = Darwin::MacCatalyst;
3923 }
3924 EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment,
3926}
3927
3928// Add additional link args for the -dynamiclib option.
3929static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args,
3930 ArgStringList &CmdArgs) {
3931 // Derived from darwin_dylib1 spec.
3932 if (D.isTargetIPhoneOS()) {
3933 if (D.isIPhoneOSVersionLT(3, 1))
3934 CmdArgs.push_back("-ldylib1.o");
3935 return;
3936 }
3937
3938 if (!D.isTargetMacOS())
3939 return;
3940 if (D.isMacosxVersionLT(10, 5))
3941 CmdArgs.push_back("-ldylib1.o");
3942 else if (D.isMacosxVersionLT(10, 6))
3943 CmdArgs.push_back("-ldylib1.10.5.o");
3944}
3945
3946// Add additional link args for the -bundle option.
3947static void addBundleLinkArgs(const Darwin &D, const ArgList &Args,
3948 ArgStringList &CmdArgs) {
3949 if (Args.hasArg(options::OPT_static))
3950 return;
3951 // Derived from darwin_bundle1 spec.
3952 if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) ||
3953 (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6)))
3954 CmdArgs.push_back("-lbundle1.o");
3955}
3956
3957// Add additional link args for the -pg option.
3958static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,
3959 ArgStringList &CmdArgs) {
3960 if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) {
3961 if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) ||
3962 Args.hasArg(options::OPT_preload)) {
3963 CmdArgs.push_back("-lgcrt0.o");
3964 } else {
3965 CmdArgs.push_back("-lgcrt1.o");
3966
3967 // darwin_crt2 spec is empty.
3968 }
3969 // By default on OS X 10.8 and later, we don't link with a crt1.o
3970 // file and the linker knows to use _main as the entry point. But,
3971 // when compiling with -pg, we need to link with the gcrt1.o file,
3972 // so pass the -no_new_main option to tell the linker to use the
3973 // "start" symbol as the entry point.
3974 if (!D.isMacosxVersionLT(10, 8))
3975 CmdArgs.push_back("-no_new_main");
3976 } else {
3977 D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
3978 << D.isTargetMacOSBased();
3979 }
3980}
3981
3982static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args,
3983 ArgStringList &CmdArgs) {
3984 // Derived from darwin_crt1 spec.
3985 if (D.isTargetIPhoneOS()) {
3986 if (D.getArch() == llvm::Triple::aarch64)
3987 ; // iOS does not need any crt1 files for arm64
3988 else if (D.isIPhoneOSVersionLT(3, 1))
3989 CmdArgs.push_back("-lcrt1.o");
3990 else if (D.isIPhoneOSVersionLT(6, 0))
3991 CmdArgs.push_back("-lcrt1.3.1.o");
3992 return;
3993 }
3994
3995 if (!D.isTargetMacOS())
3996 return;
3997 if (D.isMacosxVersionLT(10, 5))
3998 CmdArgs.push_back("-lcrt1.o");
3999 else if (D.isMacosxVersionLT(10, 6))
4000 CmdArgs.push_back("-lcrt1.10.5.o");
4001 else if (D.isMacosxVersionLT(10, 8))
4002 CmdArgs.push_back("-lcrt1.10.6.o");
4003 // darwin_crt2 spec is empty.
4004}
4005
4006void Darwin::addStartObjectFileArgs(const ArgList &Args,
4007 ArgStringList &CmdArgs) const {
4008 // Firmware uses the "bare metal" start object file args.
4009 if (isTargetFirmware())
4010 return MachO::addStartObjectFileArgs(Args, CmdArgs);
4011
4012 // Derived from startfile spec.
4013 if (Args.hasArg(options::OPT_dynamiclib))
4014 addDynamicLibLinkArgs(*this, Args, CmdArgs);
4015 else if (Args.hasArg(options::OPT_bundle))
4016 addBundleLinkArgs(*this, Args, CmdArgs);
4017 else if (Args.hasArg(options::OPT_pg) && SupportsProfiling())
4018 addPgProfilingLinkArgs(*this, Args, CmdArgs);
4019 else if (Args.hasArg(options::OPT_static) ||
4020 Args.hasArg(options::OPT_object) ||
4021 Args.hasArg(options::OPT_preload))
4022 CmdArgs.push_back("-lcrt0.o");
4023 else
4024 addDefaultCRTLinkArgs(*this, Args, CmdArgs);
4025
4026 if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) &&
4027 isMacosxVersionLT(10, 5)) {
4028 const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
4029 CmdArgs.push_back(Str);
4030 }
4031}
4032
4035 if (!isTargetInitialized())
4036 return;
4039 return;
4040 getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
4041}
4042
4044 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
4045 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
4047 Res |= SanitizerKind::Address;
4048 Res |= SanitizerKind::PointerCompare;
4049 Res |= SanitizerKind::PointerSubtract;
4050 Res |= SanitizerKind::Realtime;
4051 Res |= SanitizerKind::Leak;
4052 Res |= SanitizerKind::Fuzzer;
4053 Res |= SanitizerKind::FuzzerNoLink;
4054 Res |= SanitizerKind::ObjCCast;
4055
4057 if (!isTargetInitialized())
4058 return Res;
4059 // Prior to 10.9, macOS shipped a version of the C++ standard library without
4060 // C++11 support. The same is true of iOS prior to version 5. These OS'es are
4061 // incompatible with -fsanitize=vptr.
4062 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
4064 Res |= SanitizerKind::Vptr;
4065
4066 if ((IsX86_64 || IsAArch64) &&
4069 Res |= SanitizerKind::Thread;
4070 }
4071
4072 if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
4073 Res |= SanitizerKind::Type;
4074 }
4075
4076 if (IsX86_64)
4077 Res |= SanitizerKind::NumericalStability;
4078
4079 return Res;
4080}
4081
4082void AppleMachO::printVerboseInfo(raw_ostream &OS) const {
4083 CudaInstallation->print(OS);
4084 RocmInstallation->print(OS);
4085}
#define V(N, I)
Defines a function that returns the minimum OS versions supporting C++17's aligned allocation functio...
static bool hasMultipleInvocations(const llvm::Triple &Triple, const ArgList &Args)
Definition Clang.cpp:1246
static bool checkRemarksOptions(const Driver &D, const ArgList &Args, const llvm::Triple &Triple)
Definition Clang.cpp:1257
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple, const InputInfo &Input, const InputInfo &Output, const JobAction &JA)
Definition Clang.cpp:1273
static bool sdkSupportsBuiltinModules(const std::optional< DarwinSDKInfo > &SDKInfo)
Definition Darwin.cpp:3350
static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3958
static const char * ArmMachOArchName(StringRef Arch)
Definition Darwin.cpp:1074
static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args)
Pass -no_deduplicate to ld64 under certain conditions:
Definition Darwin.cpp:213
static bool hasExportSymbolDirective(const ArgList &Args)
Check if the link command contains a symbol export directive.
Definition Darwin.cpp:1586
static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3982
static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3947
static llvm::VersionTuple sizedDeallocMinVersion(llvm::Triple::OSType OS)
Definition Darwin.cpp:3390
static VersionTuple minimumMacCatalystDeploymentTarget()
Definition Darwin.cpp:40
static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion)
Returns the most appropriate macOS target version for the current process.
Definition Darwin.cpp:1815
static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3929
static bool isObjCRuntimeLinked(const ArgList &Args)
Determine whether we are linking the ObjC runtime.
Definition Darwin.cpp:522
static const char * getPlatformName(Darwin::DarwinPlatformKind Platform, Darwin::DarwinEnvironmentKind Environment)
Definition Darwin.cpp:3813
static const char * ArmMachOArchNameCPU(StringRef CPU)
Definition Darwin.cpp:1094
static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol)
Add an export directive for Symbol to the link command.
Definition Darwin.cpp:1601
static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode)
Take a path that speculatively points into Xcode and return the XCODE/Contents/Developer path if it i...
Definition Darwin.cpp:1353
static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs, StringRef Segment, StringRef Section)
Add a sectalign directive for Segment and Section to the maximum expected page size for Darwin.
Definition Darwin.cpp:1612
Result
Implement __builtin_bit_cast and related operations.
static StringRef getTriple(const Command &Job)
Defines types useful for describing an Objective-C runtime.
const SDKPlatformInfo & getCanonicalPlatformInfo() const
const llvm::VersionTuple & getVersion() const
The basic abstraction for the target Objective-C runtime.
Definition ObjCRuntime.h:28
bool hasNativeARC() const
Does this runtime natively provide the ARC entrypoints?
bool hasSubscripting() const
Does this runtime directly support the subscripting methods?
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
Definition ObjCRuntime.h:35
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Definition ObjCRuntime.h:40
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Definition ObjCRuntime.h:45
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
Definition ObjCRuntime.h:49
The base class of the type hierarchy.
Definition TypeBase.h:1875
Action - Represent an abstract compilation step to perform.
Definition Action.h:47
types::ID getType() const
Definition Action.h:153
ActionClass getKind() const
Definition Action.h:152
ActionList & getInputs()
Definition Action.h:155
Compilation - A set of tasks to perform for a single driver invocation.
Definition Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:99
std::string SysRoot
sysroot, if present
Definition Driver.h:205
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
Definition Driver.cpp:6939
DiagnosticBuilder Diag(unsigned DiagID) const
Definition Driver.h:169
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
Definition Driver.cpp:7309
const llvm::opt::OptTable & getOpts() const
Definition Driver.h:417
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
Definition Driver.cpp:6928
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition Driver.h:180
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Definition Driver.h:744
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
Definition Driver.h:747
InputInfo - Wrapper for information about an input source.
Definition InputInfo.h:22
const char * getFilename() const
Definition InputInfo.h:83
bool isFilename() const
Definition InputInfo.h:75
types::ID getType() const
Definition InputInfo.h:77
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
static void addSystemFrameworkIncludes(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, ArrayRef< StringRef > Paths)
Utility function to add a list of system framework directories to CC1.
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
std::string GetFilePath(const char *Name) const
static bool needsProfileRT(const llvm::opt::ArgList &Args)
needsProfileRT - returns true if instrumentation profile is on.
StringRef getOS() const
Definition ToolChain.h:296
llvm::Triple::ArchType getArch() const
Definition ToolChain.h:293
const Driver & getDriver() const
Definition ToolChain.h:277
llvm::vfs::FileSystem & getVFS() const
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args)
Returns true if gcov instrumentation (-fprofile-arcs or –coverage) is on.
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition ToolChain.cpp:91
virtual bool SupportsEmbeddedBitcode() const
SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
Definition ToolChain.h:664
path_list & getProgramPaths()
Definition ToolChain.h:320
bool hasEffectiveTriple() const
Definition ToolChain.h:310
const llvm::Triple & getEffectiveTriple() const
Get the toolchain's effective clang triple.
Definition ToolChain.h:305
const llvm::Triple & getTriple() const
Definition ToolChain.h:279
virtual types::ID LookupTypeForExtension(StringRef Ext) const
LookupTypeForExtension - Return the default language type to use for the given extension.
const XRayArgs getXRayArgs(const llvm::opt::ArgList &) const
virtual void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const
Add options that need to be passed to cc1 for this target.
virtual Tool * getTool(Action::ActionClass AC) const
virtual std::string ComputeLLVMTriple(const llvm::opt::ArgList &Args, StringRef BoundArch={}, types::ID InputType=types::TY_INVALID) const
ComputeLLVMTriple - Return the LLVM target triple to use, after taking command line arguments into ac...
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
StringRef getArchName() const
Definition ToolChain.h:294
Tool - Information on a specific compilation tool.
Definition Tool.h:32
const ToolChain & getToolChain() const
Definition Tool.h:52
bool needsXRayRt() const
Definition XRayArgs.h:38
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition Darwin.cpp:3077
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific CUDA includes.
Definition Darwin.cpp:1055
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific HIP includes.
Definition Darwin.cpp:1060
void printVerboseInfo(raw_ostream &OS) const override
Dispatch to the specific toolchain for verbose printing.
Definition Darwin.cpp:4082
llvm::SmallString< 128 > GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const
Definition Darwin.cpp:2855
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition Darwin.cpp:2868
LazyDetector< RocmInstallationDetector > RocmInstallation
Definition Darwin.h:335
LazyDetector< SYCLInstallationDetector > SYCLInstallation
Definition Darwin.h:336
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
Definition Darwin.cpp:2968
LazyDetector< CudaInstallationDetector > CudaInstallation
}
Definition Darwin.h:334
AppleMachO(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition Darwin.cpp:997
void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific SYCL includes.
Definition Darwin.cpp:1065
void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override
Add warning options that need to be passed to cc1 for this target.
Definition Darwin.cpp:1319
void AppendPlatformPrefix(SmallString< 128 > &Path, const llvm::Triple &T) const override
Definition Darwin.cpp:2839
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition Darwin.cpp:2917
void AddCCKextLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCCKextLibArgs - Add the system specific linker arguments to use for kernel extensions (Darwin-spec...
Definition Darwin.cpp:3124
bool getDefaultDebugSimpleTemplateNames() const override
Returns true if this toolchain adds '-gsimple-template-names=simple' by default when generating debug...
Definition Darwin.cpp:1456
void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool ForceLinkBuiltinRT=false) const override
Add the linker arguments to link the compiler runtime library.
Definition Darwin.cpp:1678
RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override
Definition Darwin.cpp:1666
DarwinClang(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition Darwin.cpp:1315
void AddLinkARCArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Add the linker arguments to link the ARC runtime library.
Definition Darwin.cpp:1362
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition Darwin.cpp:1343
bool HasPlatformPrefix(const llvm::Triple &T) const override
Definition Darwin.cpp:2829
unsigned GetDefaultDwarfVersion() const override
Definition Darwin.cpp:1439
Darwin - The base Darwin tool chain.
Definition Darwin.h:349
VersionTuple TargetVersion
The native OS version we are targeting.
Definition Darwin.h:378
void addPlatformVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition Darwin.cpp:3836
bool TargetInitialized
Whether the information on the target has been initialized.
Definition Darwin.h:356
bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const
Definition Darwin.h:562
bool SupportsEmbeddedBitcode() const override
SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
Definition Darwin.cpp:3740
void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass a suitable profile runtime ...
Definition Darwin.cpp:1619
Darwin(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Darwin - Darwin tool chain for i386 and x86_64.
Definition Darwin.cpp:1003
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition Darwin.cpp:4043
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition Darwin.cpp:3482
void CheckObjCARC() const override
Complain if this tool chain doesn't support Objective-C ARC.
Definition Darwin.cpp:4033
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition Darwin.cpp:3726
std::optional< DarwinSDKInfo > SDKInfo
The information about the darwin SDK that was used.
Definition Darwin.h:383
bool isSizedDeallocationUnavailable() const
Return true if c++14 sized deallocation functions are not implemented in the c++ standard library of ...
Definition Darwin.cpp:3407
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static, bool IsFortran=false) const override
Definition Darwin.cpp:1523
void ensureTargetInitialized() const
Lazily initialize the target platform from the triple when AddDeploymentTarget has not run yet (e....
Definition Darwin.cpp:1168
ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override
Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
Definition Darwin.cpp:1024
bool hasBlocksRuntime() const override
Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
Definition Darwin.cpp:1042
bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const
Returns true if the minimum supported macOS version for the slice that's being built is less than the...
Definition Darwin.h:572
bool isTargetAppleSiliconMac() const
Definition Darwin.h:546
static StringRef getSDKName(StringRef isysroot)
Definition Darwin.cpp:1546
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition Darwin.cpp:3652
void addClangCC1ASTargetOptions(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const override
Add options that need to be passed to cc1as for this target.
Definition Darwin.cpp:3596
void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, unsigned Major, unsigned Minor, unsigned Micro, VersionTuple NativeTargetVersion) const
Definition Darwin.h:442
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, llvm::StringRef BoundArch, types::ID InputType) const override
Definition Darwin.cpp:1249
CXXStdlibType GetDefaultCXXStdlibType() const override
Definition Darwin.cpp:1018
bool isTargetWatchOSSimulator() const
Definition Darwin.h:515
DarwinPlatformKind TargetPlatform
Definition Darwin.h:374
StringRef getOSLibraryNameSuffix(bool IgnoreSim=false) const override
Definition Darwin.cpp:1558
void addMinVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition Darwin.cpp:3761
void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition Darwin.cpp:4006
std::optional< llvm::Triple > TargetVariantTriple
The target variant triple that was specified (if any).
Definition Darwin.h:386
VersionTuple getTripleTargetVersion() const
The version of the OS that's used by the OS specified in the target triple.
Definition Darwin.h:557
bool isAlignedAllocationUnavailable() const
Return true if c++17 aligned allocation/deallocation functions are not implemented in the c++ standar...
Definition Darwin.cpp:3324
DarwinEnvironmentKind TargetEnvironment
Definition Darwin.h:375
VersionTuple getLinkerVersion(const llvm::opt::ArgList &Args) const
Get the version of the linker known to be available for a particular compiler invocation (via the -ml...
Definition Darwin.cpp:1141
Tool * buildLinker() const override
Definition Darwin.cpp:1305
Tool * buildStaticLibTool() const override
Definition Darwin.cpp:1307
bool isTargetIOSBased() const
Is the target either iOS or an iOS simulator?
Definition Darwin.h:210
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
Definition Darwin.cpp:3747
virtual void AppendPlatformPrefix(SmallString< 128 > &Path, const llvm::Triple &T) const
Definition Darwin.h:202
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
Definition Darwin.cpp:3751
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition Darwin.h:290
Tool * getTool(Action::ActionClass AC) const override
Definition Darwin.cpp:1286
types::ID LookupTypeForExtension(StringRef Ext) const override
LookupTypeForExtension - Return the default language type to use for the given extension.
Definition Darwin.cpp:1006
void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, StringRef Component, RuntimeLinkOptions Opts=RuntimeLinkOptions(), bool IsShared=false) const
Add a runtime library to the list of items to link.
Definition Darwin.cpp:1471
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition Darwin.cpp:3433
virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Definition Darwin.h:193
virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Definition Darwin.h:196
UnwindTableLevel getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override
How detailed should the unwind tables be by default.
Definition Darwin.cpp:3699
bool HasNativeLLVMSupport() const override
HasNativeLTOLinker - Check whether the linker and related tools have native LLVM support.
Definition Darwin.cpp:1016
std::string GetGlobalDebugPathRemapping() const override
Add an additional -fdebug-prefix-map entry.
Definition Darwin.cpp:3720
virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Definition Darwin.h:189
virtual bool HasPlatformPrefix(const llvm::Triple &T) const
Definition Darwin.h:200
bool SupportsProfiling() const override
SupportsProfiling - Does this tool chain support -pg.
Definition Darwin.cpp:3756
RuntimeLinkOptions
Options to control how a runtime library is linked.
Definition Darwin.h:213
@ RLO_IsEmbedded
Use the embedded runtime from the macho_embedded directory.
Definition Darwin.h:218
@ RLO_AddRPath
Emit rpaths for @executable_path as well as the resource directory.
Definition Darwin.h:221
@ RLO_AlwaysLink
Link the library in even if it can't be found in the VFS.
Definition Darwin.h:215
MachO(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition Darwin.cpp:991
virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool ForceLinkBuiltinRT=false) const
Add the linker arguments to link the compiler runtime library.
Definition Darwin.cpp:3308
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static, bool IsFortran=false) const override
Definition Darwin.cpp:1504
StringRef getMachOArchName(const llvm::opt::ArgList &Args) const
Get the "MachO" arch name for a particular compiler invocation.
Definition Darwin.cpp:1113
Tool * buildAssembler() const override
Definition Darwin.cpp:1311
bool isPIEDefault(const llvm::opt::ArgList &Args) const override
Test whether this toolchain defaults to PIE.
Definition Darwin.cpp:3749
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition Darwin.cpp:3156
bool UseDwarfDebugFlags() const override
UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf compile unit information.
Definition Darwin.cpp:3714
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:112
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:946
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:599
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:921
const toolchains::MachO & getMachOToolChain() const
Definition Darwin.h:43
void AddMachOArch(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Definition Darwin.cpp:182
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:873
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition Darwin.cpp:967
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args)
llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str)
Definition Darwin.cpp:44
void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str, const llvm::opt::ArgList &Args)
llvm::opt::Arg * getLastCSProfileGenerateArg(const llvm::opt::ArgList &Args)
llvm::opt::Arg * getLastProfileUseArg(const llvm::opt::ArgList &Args)
llvm::StringRef getLTOParallelism(const llvm::opt::ArgList &Args, const Driver &D)
bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, const llvm::opt::ArgList &Args, bool ForceStaticHostRuntime=false, bool IsOffloadingHost=false, bool GompNeedsRT=false)
Returns true, if an OpenMP runtime has been added.
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
SmallString< 128 > getStatsFileName(const llvm::opt::ArgList &Args, const InputInfo &Output, const InputInfo &Input, const Driver &D)
Handles the -save-stats option and returns the filename to save statistics to.
bool isObjCAutoRefCount(const llvm::opt::ArgList &Args)
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
Definition Types.cpp:80
SmallVector< InputInfo, 4 > InputInfoList
Definition Driver.h:50
bool willEmitRemarks(const llvm::opt::ArgList &Args)
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
Expected< std::optional< DarwinSDKInfo > > parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath)
Parse the SDK information from the SDKSettings.json file.
llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS)
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:62
bool(*)(llvm::ArrayRef< const char * >, llvm::raw_ostream &, llvm::raw_ostream &, bool, bool) Driver
Definition Wasm.cpp:36
#define false
Definition stdbool.h:26
static constexpr OSEnvPair macCatalystToMacOSPair()
Returns the os-environment mapping pair that's used to represent the Mac Catalyst -> macOS version ma...
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
llvm::Triple::OSType getOS() const
llvm::Triple::EnvironmentType getEnvironment() const
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition Job.h:78
static constexpr ResponseFileSupport AtFileUTF8()
Definition Job.h:85