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