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)) {
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
569static void AppendPlatformPrefix(SmallString<128> &Path, const llvm::Triple &T);
570
572 const InputInfo &Output,
573 const InputInfoList &Inputs,
574 const ArgList &Args,
575 const char *LinkingOutput) const {
576 assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
577
578 // If the number of arguments surpasses the system limits, we will encode the
579 // input files in a separate file, shortening the command line. To this end,
580 // build a list of input file names that can be passed via a file with the
581 // -filelist linker option.
582 llvm::opt::ArgStringList InputFileList;
583
584 // The logic here is derived from gcc's behavior; most of which
585 // comes from specs (starting with link_command). Consult gcc for
586 // more information.
587 ArgStringList CmdArgs;
588
589 VersionTuple Version = getMachOToolChain().getLinkerVersion(Args);
590
591 bool LinkerIsLLD;
592 const char *Exec =
593 Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD));
594
595 // xrOS always uses -platform-version.
596 bool UsePlatformVersion = getToolChain().getTriple().isXROS();
597
598 // I'm not sure why this particular decomposition exists in gcc, but
599 // we follow suite for ease of comparison.
600 AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD,
601 UsePlatformVersion);
602
603 if (willEmitRemarks(Args) &&
604 checkRemarksOptions(getToolChain().getDriver(), Args,
605 getToolChain().getTriple()))
606 renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA);
607
608 // Propagate the -moutline flag to the linker in LTO.
609 if (Arg *A =
610 Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) {
611 if (A->getOption().matches(options::OPT_moutline)) {
612 if (getMachOToolChain().getMachOArchName(Args) == "arm64") {
613 CmdArgs.push_back("-mllvm");
614 CmdArgs.push_back("-enable-machine-outliner");
615 }
616 } else {
617 // Disable all outlining behaviour if we have mno-outline. We need to do
618 // this explicitly, because targets which support default outlining will
619 // try to do work if we don't.
620 CmdArgs.push_back("-mllvm");
621 CmdArgs.push_back("-enable-machine-outliner=never");
622 }
623 }
624
625 // Outline from linkonceodr functions by default in LTO, whenever the outliner
626 // is enabled. Note that the target may enable the machine outliner
627 // independently of -moutline.
628 CmdArgs.push_back("-mllvm");
629 CmdArgs.push_back("-enable-linkonceodr-outlining");
630
631 // Propagate codegen data flags to the linker for the LLVM backend.
632 auto *CodeGenDataGenArg =
633 Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
634 auto *CodeGenDataUseArg = Args.getLastArg(options::OPT_fcodegen_data_use_EQ);
635
636 // We only allow one of them to be specified.
637 const Driver &D = getToolChain().getDriver();
638 if (CodeGenDataGenArg && CodeGenDataUseArg)
639 D.Diag(diag::err_drv_argument_not_allowed_with)
640 << CodeGenDataGenArg->getAsString(Args)
641 << CodeGenDataUseArg->getAsString(Args);
642
643 // For codegen data gen, the output file is passed to the linker
644 // while a boolean flag is passed to the LLVM backend.
645 if (CodeGenDataGenArg) {
646 CmdArgs.push_back("-mllvm");
647 CmdArgs.push_back("-codegen-data-generate");
648 }
649
650 // For codegen data use, the input file is passed to the LLVM backend.
651 if (CodeGenDataUseArg) {
652 CmdArgs.push_back("-mllvm");
653 CmdArgs.push_back(Args.MakeArgString(Twine("-codegen-data-use-path=") +
654 CodeGenDataUseArg->getValue()));
655 }
656
657 // Setup statistics file output.
658 SmallString<128> StatsFile =
659 getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());
660 if (!StatsFile.empty()) {
661 CmdArgs.push_back("-mllvm");
662 CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str()));
663 }
664
665 // It seems that the 'e' option is completely ignored for dynamic executables
666 // (the default), and with static executables, the last one wins, as expected.
667 Args.addAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
668 options::OPT_Z_Flag, options::OPT_u_Group});
669
670 // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
671 // members of static archive libraries which implement Objective-C classes or
672 // categories.
673 if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
674 CmdArgs.push_back("-ObjC");
675
676 CmdArgs.push_back("-o");
677 CmdArgs.push_back(Output.getFilename());
678
679 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
680 getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
681
682 Args.AddAllArgs(CmdArgs, options::OPT_L);
683
684 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
685 // Build the input file for -filelist (list of linker input files) in case we
686 // need it later
687 for (const auto &II : Inputs) {
688 if (!II.isFilename()) {
689 // This is a linker input argument.
690 // We cannot mix input arguments and file names in a -filelist input, thus
691 // we prematurely stop our list (remaining files shall be passed as
692 // arguments).
693 if (InputFileList.size() > 0)
694 break;
695
696 continue;
697 }
698
699 InputFileList.push_back(II.getFilename());
700 }
701
702 // Additional linker set-up and flags for Fortran. This is required in order
703 // to generate executables.
704 if (getToolChain().getDriver().IsFlangMode() &&
705 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
706 getToolChain().addFortranRuntimeLibraryPath(Args, CmdArgs);
707 getToolChain().addFortranRuntimeLibs(Args, CmdArgs);
708 }
709
710 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
711 addOpenMPRuntime(C, CmdArgs, getToolChain(), Args);
712
713 if (isObjCRuntimeLinked(Args) &&
714 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
715 // We use arclite library for both ARC and subscripting support.
716 getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
717
718 CmdArgs.push_back("-framework");
719 CmdArgs.push_back("Foundation");
720 // Link libobj.
721 CmdArgs.push_back("-lobjc");
722 }
723
724 if (LinkingOutput) {
725 CmdArgs.push_back("-arch_multiple");
726 CmdArgs.push_back("-final_output");
727 CmdArgs.push_back(LinkingOutput);
728 }
729
730 if (Args.hasArg(options::OPT_fnested_functions))
731 CmdArgs.push_back("-allow_stack_execute");
732
733 getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
734
735 StringRef Parallelism = getLTOParallelism(Args, getToolChain().getDriver());
736 if (!Parallelism.empty()) {
737 CmdArgs.push_back("-mllvm");
738 unsigned NumThreads =
739 llvm::get_threadpool_strategy(Parallelism)->compute_thread_count();
740 CmdArgs.push_back(Args.MakeArgString("-threads=" + Twine(NumThreads)));
741 }
742
743 if (getToolChain().ShouldLinkCXXStdlib(Args))
744 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
745
746 bool NoStdOrDefaultLibs =
747 Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
748 bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib);
749 if (!NoStdOrDefaultLibs || ForceLinkBuiltins) {
750 // link_ssp spec is empty.
751
752 // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then
753 // we just want to link the builtins, not the other libs like libSystem.
754 if (NoStdOrDefaultLibs && ForceLinkBuiltins) {
755 getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins");
756 } else {
757 // Let the tool chain choose which runtime library to link.
758 getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs,
759 ForceLinkBuiltins);
760
761 // No need to do anything for pthreads. Claim argument to avoid warning.
762 Args.ClaimAllArgs(options::OPT_pthread);
763 Args.ClaimAllArgs(options::OPT_pthreads);
764 }
765 }
766
767 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
768 // endfile_spec is empty.
769 }
770
771 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
772 Args.AddAllArgs(CmdArgs, options::OPT_F);
773
774 // -iframework should be forwarded as -F.
775 for (const Arg *A : Args.filtered(options::OPT_iframework))
776 CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
777
778 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
779 if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
780 if (A->getValue() == StringRef("Accelerate")) {
781 CmdArgs.push_back("-framework");
782 CmdArgs.push_back("Accelerate");
783 }
784 }
785 }
786
787 // Add non-standard, platform-specific search paths, e.g., for DriverKit:
788 // -L<sysroot>/System/DriverKit/usr/lib
789 // -F<sysroot>/System/DriverKit/System/Library/Framework
790 {
791 bool NonStandardSearchPath = false;
792 const auto &Triple = getToolChain().getTriple();
793 if (Triple.isDriverKit()) {
794 // ld64 fixed the implicit -F and -L paths in ld64-605.1+.
795 NonStandardSearchPath =
796 Version.getMajor() < 605 ||
797 (Version.getMajor() == 605 && Version.getMinor().value_or(0) < 1);
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 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(clang::driver::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 &, 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 &, 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 AddCXXStdlibLibArgs(Args, CmdArgs);
1614 }
1615 if (Sanitize.needsStatsRt()) {
1616 AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
1617 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
1618 }
1619 }
1620
1621 if (Sanitize.needsMemProfRt())
1622 if (hasExportSymbolDirective(Args))
1624 CmdArgs,
1625 llvm::memprof::getMemprofOptionsSymbolDarwinLinkageName().data());
1626
1627 const XRayArgs &XRay = getXRayArgs(Args);
1628 if (XRay.needsXRayRt()) {
1629 AddLinkRuntimeLib(Args, CmdArgs, "xray");
1630 AddLinkRuntimeLib(Args, CmdArgs, "xray-basic");
1631 AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr");
1632 }
1633
1634 if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) {
1635 CmdArgs.push_back("-framework");
1636 CmdArgs.push_back("DriverKit");
1637 }
1638
1639 // Otherwise link libSystem, then the dynamic runtime library, and finally any
1640 // target specific static runtime library.
1641 if (!isTargetDriverKit())
1642 CmdArgs.push_back("-lSystem");
1643
1644 // Select the dynamic runtime library and the target specific static library.
1645 // Some old Darwin versions put builtins, libunwind, and some other stuff in
1646 // libgcc_s.1.dylib. MacOS X 10.6 and iOS 5 moved those functions to
1647 // libSystem, and made libgcc_s.1.dylib a stub. We never link libgcc_s when
1648 // building for aarch64 or iOS simulator, since libgcc_s was made obsolete
1649 // before either existed.
1650 if (getTriple().getArch() != llvm::Triple::aarch64 &&
1654 CmdArgs.push_back("-lgcc_s.1");
1655 AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1656}
1657
1658/// Returns the most appropriate macOS target version for the current process.
1659///
1660/// If the macOS SDK version is the same or earlier than the system version,
1661/// then the SDK version is returned. Otherwise the system version is returned.
1662static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
1663 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
1664 if (!SystemTriple.isMacOSX())
1665 return std::string(MacOSSDKVersion);
1666 VersionTuple SystemVersion;
1667 SystemTriple.getMacOSXVersion(SystemVersion);
1668
1669 unsigned Major, Minor, Micro;
1670 bool HadExtra;
1671 if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
1672 HadExtra))
1673 return std::string(MacOSSDKVersion);
1674 VersionTuple SDKVersion(Major, Minor, Micro);
1675
1676 if (SDKVersion > SystemVersion)
1677 return SystemVersion.getAsString();
1678 return std::string(MacOSSDKVersion);
1679}
1680
1681namespace {
1682
1683/// The Darwin OS and version that was selected or inferred from arguments or
1684/// environment.
1685struct DarwinPlatform {
1686 enum SourceKind {
1687 /// The OS was specified using the -target argument.
1688 TargetArg,
1689 /// The OS was specified using the -mtargetos= argument.
1690 MTargetOSArg,
1691 /// The OS was specified using the -m<os>-version-min argument.
1692 OSVersionArg,
1693 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
1694 DeploymentTargetEnv,
1695 /// The OS was inferred from the SDK.
1696 InferredFromSDK,
1697 /// The OS was inferred from the -arch.
1698 InferredFromArch
1699 };
1700
1701 using DarwinPlatformKind = Darwin::DarwinPlatformKind;
1702 using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind;
1703
1704 DarwinPlatformKind getPlatform() const { return Platform; }
1705
1706 DarwinEnvironmentKind getEnvironment() const { return Environment; }
1707
1708 void setEnvironment(DarwinEnvironmentKind Kind) {
1709 Environment = Kind;
1710 InferSimulatorFromArch = false;
1711 }
1712
1713 const VersionTuple getOSVersion() const {
1714 return UnderlyingOSVersion.value_or(VersionTuple());
1715 }
1716
1717 VersionTuple takeOSVersion() {
1718 assert(UnderlyingOSVersion.has_value() &&
1719 "attempting to get an unset OS version");
1720 VersionTuple Result = *UnderlyingOSVersion;
1721 UnderlyingOSVersion.reset();
1722 return Result;
1723 }
1724 bool isValidOSVersion() const {
1725 return llvm::Triple::isValidVersionForOS(getOSFromPlatform(Platform),
1726 getOSVersion());
1727 }
1728
1729 VersionTuple getCanonicalOSVersion() const {
1730 return llvm::Triple::getCanonicalVersionForOS(
1731 getOSFromPlatform(Platform), getOSVersion(), /*IsInValidRange=*/true);
1732 }
1733
1734 void setOSVersion(const VersionTuple &Version) {
1735 UnderlyingOSVersion = Version;
1736 }
1737
1738 bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); }
1739
1740 VersionTuple getZipperedOSVersion() const {
1741 assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
1742 "zippered target version is specified only for Mac Catalyst");
1743 return ZipperedOSVersion;
1744 }
1745
1746 /// Returns true if the target OS was explicitly specified.
1747 bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
1748
1749 /// Returns true if the simulator environment can be inferred from the arch.
1750 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }
1751
1752 const std::optional<llvm::Triple> &getTargetVariantTriple() const {
1753 return TargetVariantTriple;
1754 }
1755
1756 /// Adds the -m<os>-version-min argument to the compiler invocation.
1757 void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
1758 auto &[Arg, OSVersionStr] = Arguments;
1759 if (Arg)
1760 return;
1761 assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1762 "Invalid kind");
1763 options::ID Opt;
1764 switch (Platform) {
1765 case DarwinPlatformKind::MacOS:
1766 Opt = options::OPT_mmacos_version_min_EQ;
1767 break;
1768 case DarwinPlatformKind::IPhoneOS:
1769 Opt = options::OPT_mios_version_min_EQ;
1770 break;
1771 case DarwinPlatformKind::TvOS:
1772 Opt = options::OPT_mtvos_version_min_EQ;
1773 break;
1774 case DarwinPlatformKind::WatchOS:
1775 Opt = options::OPT_mwatchos_version_min_EQ;
1776 break;
1777 case DarwinPlatformKind::XROS:
1778 // xrOS always explicitly provides a version in the triple.
1779 return;
1780 case DarwinPlatformKind::DriverKit:
1781 // DriverKit always explicitly provides a version in the triple.
1782 return;
1783 }
1784 Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);
1785 Args.append(Arg);
1786 }
1787
1788 /// Returns the OS version with the argument / environment variable that
1789 /// specified it.
1790 std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
1791 auto &[Arg, OSVersionStr] = Arguments;
1792 switch (Kind) {
1793 case TargetArg:
1794 case MTargetOSArg:
1795 case OSVersionArg:
1796 assert(Arg && "OS version argument not yet inferred");
1797 return Arg->getAsString(Args);
1798 case DeploymentTargetEnv:
1799 return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
1800 case InferredFromSDK:
1801 case InferredFromArch:
1802 llvm_unreachable("Cannot print arguments for inferred OS version");
1803 }
1804 llvm_unreachable("Unsupported Darwin Source Kind");
1805 }
1806
1807 // Returns the inferred source of how the OS version was resolved.
1808 std::string getInferredSource() {
1809 assert(!isExplicitlySpecified() && "OS version was not inferred");
1810 return InferredSource.str();
1811 }
1812
1813 void setEnvironment(llvm::Triple::EnvironmentType EnvType,
1814 const VersionTuple &OSVersion,
1815 const std::optional<DarwinSDKInfo> &SDKInfo) {
1816 switch (EnvType) {
1817 case llvm::Triple::Simulator:
1818 Environment = DarwinEnvironmentKind::Simulator;
1819 break;
1820 case llvm::Triple::MacABI: {
1821 Environment = DarwinEnvironmentKind::MacCatalyst;
1822 // The minimum native macOS target for MacCatalyst is macOS 10.15.
1823 ZipperedOSVersion = VersionTuple(10, 15);
1824 if (hasOSVersion() && SDKInfo) {
1825 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
1827 if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
1828 OSVersion, ZipperedOSVersion, std::nullopt)) {
1829 ZipperedOSVersion = *MacOSVersion;
1830 }
1831 }
1832 }
1833 // In a zippered build, we could be building for a macOS target that's
1834 // lower than the version that's implied by the OS version. In that case
1835 // we need to use the minimum version as the native target version.
1836 if (TargetVariantTriple) {
1837 auto TargetVariantVersion = TargetVariantTriple->getOSVersion();
1838 if (TargetVariantVersion.getMajor()) {
1839 if (TargetVariantVersion < ZipperedOSVersion)
1840 ZipperedOSVersion = TargetVariantVersion;
1841 }
1842 }
1843 break;
1844 }
1845 default:
1846 break;
1847 }
1848 }
1849
1850 static DarwinPlatform
1851 createFromTarget(const llvm::Triple &TT, Arg *A,
1852 std::optional<llvm::Triple> TargetVariantTriple,
1853 const std::optional<DarwinSDKInfo> &SDKInfo) {
1854 DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()),
1855 TT.getOSVersion(), A);
1856 VersionTuple OsVersion = TT.getOSVersion();
1857 Result.TargetVariantTriple = TargetVariantTriple;
1858 Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);
1859 return Result;
1860 }
1861 static DarwinPlatform
1862 createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
1863 llvm::Triple::EnvironmentType Environment, Arg *A,
1864 const std::optional<DarwinSDKInfo> &SDKInfo) {
1865 DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), OSVersion, A);
1866 Result.InferSimulatorFromArch = false;
1867 Result.setEnvironment(Environment, OSVersion, SDKInfo);
1868 return Result;
1869 }
1870 static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A,
1871 bool IsSimulator) {
1872 DarwinPlatform Result{OSVersionArg, Platform,
1873 getVersionFromString(A->getValue()), A};
1874 if (IsSimulator)
1875 Result.Environment = DarwinEnvironmentKind::Simulator;
1876 return Result;
1877 }
1878 static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,
1879 StringRef EnvVarName,
1880 StringRef OSVersion) {
1881 DarwinPlatform Result(DeploymentTargetEnv, Platform,
1882 getVersionFromString(OSVersion));
1883 Result.EnvVarName = EnvVarName;
1884 return Result;
1885 }
1886 static DarwinPlatform createFromSDK(StringRef SDKRoot,
1887 DarwinPlatformKind Platform,
1888 StringRef Value,
1889 bool IsSimulator = false) {
1890 DarwinPlatform Result(InferredFromSDK, Platform,
1891 getVersionFromString(Value));
1892 if (IsSimulator)
1893 Result.Environment = DarwinEnvironmentKind::Simulator;
1894 Result.InferSimulatorFromArch = false;
1895 Result.InferredSource = SDKRoot;
1896 return Result;
1897 }
1898 static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,
1899 VersionTuple Version) {
1900 auto Result =
1901 DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
1902 Result.InferredSource = Arch;
1903 return Result;
1904 }
1905
1906 /// Constructs an inferred SDKInfo value based on the version inferred from
1907 /// the SDK path itself. Only works for values that were created by inferring
1908 /// the platform from the SDKPath.
1909 DarwinSDKInfo inferSDKInfo() {
1910 assert(Kind == InferredFromSDK && "can infer SDK info only");
1911 return DarwinSDKInfo(getOSVersion(),
1912 /*MaximumDeploymentTarget=*/
1913 VersionTuple(getOSVersion().getMajor(), 0, 99),
1914 getOSFromPlatform(Platform));
1915 }
1916
1917private:
1918 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
1919 : Kind(Kind), Platform(Platform),
1920 Arguments({Argument, VersionTuple().getAsString()}) {}
1921 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,
1922 VersionTuple Value, Arg *Argument = nullptr)
1923 : Kind(Kind), Platform(Platform),
1924 Arguments({Argument, Value.getAsString()}) {
1925 if (!Value.empty())
1926 UnderlyingOSVersion = Value;
1927 }
1928
1929 static VersionTuple getVersionFromString(const StringRef Input) {
1930 llvm::VersionTuple Version;
1931 bool IsValid = !Version.tryParse(Input);
1932 assert(IsValid && "unable to convert input version to version tuple");
1933 (void)IsValid;
1934 return Version;
1935 }
1936
1937 static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {
1938 switch (OS) {
1939 case llvm::Triple::Darwin:
1940 case llvm::Triple::MacOSX:
1941 return DarwinPlatformKind::MacOS;
1942 case llvm::Triple::IOS:
1943 return DarwinPlatformKind::IPhoneOS;
1944 case llvm::Triple::TvOS:
1945 return DarwinPlatformKind::TvOS;
1946 case llvm::Triple::WatchOS:
1947 return DarwinPlatformKind::WatchOS;
1948 case llvm::Triple::XROS:
1949 return DarwinPlatformKind::XROS;
1950 case llvm::Triple::DriverKit:
1951 return DarwinPlatformKind::DriverKit;
1952 default:
1953 llvm_unreachable("Unable to infer Darwin variant");
1954 }
1955 }
1956
1957 static llvm::Triple::OSType getOSFromPlatform(DarwinPlatformKind Platform) {
1958 switch (Platform) {
1959 case DarwinPlatformKind::MacOS:
1960 return llvm::Triple::MacOSX;
1961 case DarwinPlatformKind::IPhoneOS:
1962 return llvm::Triple::IOS;
1963 case DarwinPlatformKind::TvOS:
1964 return llvm::Triple::TvOS;
1965 case DarwinPlatformKind::WatchOS:
1966 return llvm::Triple::WatchOS;
1967 case DarwinPlatformKind::DriverKit:
1968 return llvm::Triple::DriverKit;
1969 case DarwinPlatformKind::XROS:
1970 return llvm::Triple::XROS;
1971 }
1972 llvm_unreachable("Unknown DarwinPlatformKind enum");
1973 }
1974
1975 SourceKind Kind;
1976 DarwinPlatformKind Platform;
1977 DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
1978 // When compiling for a zippered target, this means both target &
1979 // target variant is set on the command line, ZipperedOSVersion holds the
1980 // OSVersion tied to the main target value.
1981 VersionTuple ZipperedOSVersion;
1982 // We allow multiple ways to set or default the OS
1983 // version used for compilation. When set, UnderlyingOSVersion represents
1984 // the intended version to match the platform information computed from
1985 // arguments.
1986 std::optional<VersionTuple> UnderlyingOSVersion;
1987 bool InferSimulatorFromArch = true;
1988 std::pair<Arg *, std::string> Arguments;
1989 StringRef EnvVarName;
1990 // If the DarwinPlatform information is derived from an inferred source, this
1991 // captures what that source input was for error reporting.
1992 StringRef InferredSource;
1993 // When compiling for a zippered target, this value represents the target
1994 // triple encoded in the target variant.
1995 std::optional<llvm::Triple> TargetVariantTriple;
1996};
1997
1998/// Returns the deployment target that's specified using the -m<os>-version-min
1999/// argument.
2000std::optional<DarwinPlatform>
2001getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
2002 const Driver &TheDriver) {
2003 Arg *macOSVersion = Args.getLastArg(options::OPT_mmacos_version_min_EQ);
2004 Arg *iOSVersion = Args.getLastArg(options::OPT_mios_version_min_EQ,
2005 options::OPT_mios_simulator_version_min_EQ);
2006 Arg *TvOSVersion =
2007 Args.getLastArg(options::OPT_mtvos_version_min_EQ,
2008 options::OPT_mtvos_simulator_version_min_EQ);
2009 Arg *WatchOSVersion =
2010 Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
2011 options::OPT_mwatchos_simulator_version_min_EQ);
2012
2013 auto GetDarwinPlatform =
2014 [&](DarwinPlatform::DarwinPlatformKind Platform, Arg *VersionArg,
2015 bool IsSimulator) -> std::optional<DarwinPlatform> {
2016 if (StringRef(VersionArg->getValue()).empty()) {
2017 TheDriver.Diag(diag::err_drv_missing_version_number)
2018 << VersionArg->getAsString(Args);
2019 return std::nullopt;
2020 }
2021 return DarwinPlatform::createOSVersionArg(Platform, VersionArg,
2022 /*IsSimulator=*/IsSimulator);
2023 };
2024
2025 if (macOSVersion) {
2026 if (iOSVersion || TvOSVersion || WatchOSVersion) {
2027 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2028 << macOSVersion->getAsString(Args)
2029 << (iOSVersion ? iOSVersion
2030 : TvOSVersion ? TvOSVersion : WatchOSVersion)
2031 ->getAsString(Args);
2032 }
2033 return GetDarwinPlatform(Darwin::MacOS, macOSVersion,
2034 /*IsSimulator=*/false);
2035
2036 } else if (iOSVersion) {
2037 if (TvOSVersion || WatchOSVersion) {
2038 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2039 << iOSVersion->getAsString(Args)
2040 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
2041 }
2042 return GetDarwinPlatform(Darwin::IPhoneOS, iOSVersion,
2043 iOSVersion->getOption().getID() ==
2044 options::OPT_mios_simulator_version_min_EQ);
2045 } else if (TvOSVersion) {
2046 if (WatchOSVersion) {
2047 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2048 << TvOSVersion->getAsString(Args)
2049 << WatchOSVersion->getAsString(Args);
2050 }
2051 return GetDarwinPlatform(Darwin::TvOS, TvOSVersion,
2052 TvOSVersion->getOption().getID() ==
2053 options::OPT_mtvos_simulator_version_min_EQ);
2054 } else if (WatchOSVersion)
2055 return GetDarwinPlatform(
2056 Darwin::WatchOS, WatchOSVersion,
2057 WatchOSVersion->getOption().getID() ==
2058 options::OPT_mwatchos_simulator_version_min_EQ);
2059 return std::nullopt;
2060}
2061
2062/// Returns the deployment target that's specified using the
2063/// OS_DEPLOYMENT_TARGET environment variable.
2064std::optional<DarwinPlatform>
2065getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
2066 const llvm::Triple &Triple) {
2067 std::string Targets[Darwin::LastDarwinPlatform + 1];
2068 const char *EnvVars[] = {
2069 "MACOSX_DEPLOYMENT_TARGET",
2070 "IPHONEOS_DEPLOYMENT_TARGET",
2071 "TVOS_DEPLOYMENT_TARGET",
2072 "WATCHOS_DEPLOYMENT_TARGET",
2073 "DRIVERKIT_DEPLOYMENT_TARGET",
2074 "XROS_DEPLOYMENT_TARGET"
2075 };
2076 static_assert(std::size(EnvVars) == Darwin::LastDarwinPlatform + 1,
2077 "Missing platform");
2078 for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) {
2079 if (char *Env = ::getenv(I.value()))
2080 Targets[I.index()] = Env;
2081 }
2082
2083 // Allow conflicts among OSX and iOS for historical reasons, but choose the
2084 // default platform.
2085 if (!Targets[Darwin::MacOS].empty() &&
2086 (!Targets[Darwin::IPhoneOS].empty() ||
2087 !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty() ||
2088 !Targets[Darwin::XROS].empty())) {
2089 if (Triple.getArch() == llvm::Triple::arm ||
2090 Triple.getArch() == llvm::Triple::aarch64 ||
2091 Triple.getArch() == llvm::Triple::thumb)
2092 Targets[Darwin::MacOS] = "";
2093 else
2094 Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] =
2095 Targets[Darwin::TvOS] = Targets[Darwin::XROS] = "";
2096 } else {
2097 // Don't allow conflicts in any other platform.
2098 unsigned FirstTarget = std::size(Targets);
2099 for (unsigned I = 0; I != std::size(Targets); ++I) {
2100 if (Targets[I].empty())
2101 continue;
2102 if (FirstTarget == std::size(Targets))
2103 FirstTarget = I;
2104 else
2105 TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
2106 << Targets[FirstTarget] << Targets[I];
2107 }
2108 }
2109
2110 for (const auto &Target : llvm::enumerate(llvm::ArrayRef(Targets))) {
2111 if (!Target.value().empty())
2112 return DarwinPlatform::createDeploymentTargetEnv(
2113 (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],
2114 Target.value());
2115 }
2116 return std::nullopt;
2117}
2118
2119/// Returns the SDK name without the optional prefix that ends with a '.' or an
2120/// empty string otherwise.
2121static StringRef dropSDKNamePrefix(StringRef SDKName) {
2122 size_t PrefixPos = SDKName.find('.');
2123 if (PrefixPos == StringRef::npos)
2124 return "";
2125 return SDKName.substr(PrefixPos + 1);
2126}
2127
2128/// Tries to infer the deployment target from the SDK specified by -isysroot
2129/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
2130/// it's available.
2131std::optional<DarwinPlatform>
2132inferDeploymentTargetFromSDK(DerivedArgList &Args,
2133 const std::optional<DarwinSDKInfo> &SDKInfo) {
2134 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2135 if (!A)
2136 return std::nullopt;
2137 StringRef isysroot = A->getValue();
2138 StringRef SDK = Darwin::getSDKName(isysroot);
2139 if (!SDK.size())
2140 return std::nullopt;
2141
2142 std::string Version;
2143 if (SDKInfo) {
2144 // Get the version from the SDKSettings.json if it's available.
2145 Version = SDKInfo->getVersion().getAsString();
2146 } else {
2147 // Slice the version number out.
2148 // Version number is between the first and the last number.
2149 size_t StartVer = SDK.find_first_of("0123456789");
2150 size_t EndVer = SDK.find_last_of("0123456789");
2151 if (StartVer != StringRef::npos && EndVer > StartVer)
2152 Version = std::string(SDK.slice(StartVer, EndVer + 1));
2153 }
2154 if (Version.empty())
2155 return std::nullopt;
2156
2157 auto CreatePlatformFromSDKName =
2158 [&](StringRef SDK) -> std::optional<DarwinPlatform> {
2159 if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
2160 return DarwinPlatform::createFromSDK(
2161 isysroot, Darwin::IPhoneOS, Version,
2162 /*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
2163 else if (SDK.starts_with("MacOSX"))
2164 return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,
2166 else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
2167 return DarwinPlatform::createFromSDK(
2168 isysroot, Darwin::WatchOS, Version,
2169 /*IsSimulator=*/SDK.starts_with("WatchSimulator"));
2170 else if (SDK.starts_with("AppleTVOS") ||
2171 SDK.starts_with("AppleTVSimulator"))
2172 return DarwinPlatform::createFromSDK(
2173 isysroot, Darwin::TvOS, Version,
2174 /*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
2175 else if (SDK.starts_with("XR"))
2176 return DarwinPlatform::createFromSDK(
2177 isysroot, Darwin::XROS, Version,
2178 /*IsSimulator=*/SDK.contains("Simulator"));
2179 else if (SDK.starts_with("DriverKit"))
2180 return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit,
2181 Version);
2182 return std::nullopt;
2183 };
2184 if (auto Result = CreatePlatformFromSDKName(SDK))
2185 return Result;
2186 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
2187 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK));
2188}
2189// Compute & get the OS Version when the target triple omitted one.
2190VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,
2191 const llvm::Triple &Triple,
2192 const Driver &TheDriver) {
2193 VersionTuple OsVersion;
2194 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
2195 switch (OS) {
2196 case llvm::Triple::Darwin:
2197 case llvm::Triple::MacOSX:
2198 // If there is no version specified on triple, and both host and target are
2199 // macos, use the host triple to infer OS version.
2200 if (Triple.isMacOSX() && SystemTriple.isMacOSX() &&
2201 !Triple.getOSMajorVersion())
2202 SystemTriple.getMacOSXVersion(OsVersion);
2203 else if (!Triple.getMacOSXVersion(OsVersion))
2204 TheDriver.Diag(diag::err_drv_invalid_darwin_version)
2205 << Triple.getOSName();
2206 break;
2207 case llvm::Triple::IOS:
2208 if (Triple.isMacCatalystEnvironment() && !Triple.getOSMajorVersion()) {
2209 OsVersion = VersionTuple(13, 1);
2210 } else
2211 OsVersion = Triple.getiOSVersion();
2212 break;
2213 case llvm::Triple::TvOS:
2214 OsVersion = Triple.getOSVersion();
2215 break;
2216 case llvm::Triple::WatchOS:
2217 OsVersion = Triple.getWatchOSVersion();
2218 break;
2219 case llvm::Triple::XROS:
2220 OsVersion = Triple.getOSVersion();
2221 if (!OsVersion.getMajor())
2222 OsVersion = OsVersion.withMajorReplaced(1);
2223 break;
2224 case llvm::Triple::DriverKit:
2225 OsVersion = Triple.getDriverKitVersion();
2226 break;
2227 default:
2228 llvm_unreachable("Unexpected OS type");
2229 break;
2230 }
2231 return OsVersion;
2232}
2233
2234/// Tries to infer the target OS from the -arch.
2235std::optional<DarwinPlatform>
2236inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
2237 const llvm::Triple &Triple,
2238 const Driver &TheDriver) {
2239 llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
2240
2241 StringRef MachOArchName = Toolchain.getMachOArchName(Args);
2242 if (MachOArchName == "arm64" || MachOArchName == "arm64e")
2243 OSTy = llvm::Triple::MacOSX;
2244 else if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
2245 MachOArchName == "armv6")
2246 OSTy = llvm::Triple::IOS;
2247 else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32")
2248 OSTy = llvm::Triple::WatchOS;
2249 else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
2250 MachOArchName != "armv7em")
2251 OSTy = llvm::Triple::MacOSX;
2252 if (OSTy == llvm::Triple::UnknownOS)
2253 return std::nullopt;
2254 return DarwinPlatform::createFromArch(
2255 MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
2256}
2257
2258/// Returns the deployment target that's specified using the -target option.
2259std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2260 DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver,
2261 const std::optional<DarwinSDKInfo> &SDKInfo) {
2262 if (!Args.hasArg(options::OPT_target))
2263 return std::nullopt;
2264 if (Triple.getOS() == llvm::Triple::Darwin ||
2265 Triple.getOS() == llvm::Triple::UnknownOS)
2266 return std::nullopt;
2267 std::optional<llvm::Triple> TargetVariantTriple;
2268 for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
2269 llvm::Triple TVT(A->getValue());
2270 // Find a matching <arch>-<vendor> target variant triple that can be used.
2271 if ((Triple.getArch() == llvm::Triple::aarch64 ||
2272 TVT.getArchName() == Triple.getArchName()) &&
2273 TVT.getArch() == Triple.getArch() &&
2274 TVT.getSubArch() == Triple.getSubArch() &&
2275 TVT.getVendor() == Triple.getVendor()) {
2276 if (TargetVariantTriple)
2277 continue;
2278 A->claim();
2279 // Accept a -target-variant triple when compiling code that may run on
2280 // macOS or Mac Catalyst.
2281 if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS &&
2282 TVT.isMacCatalystEnvironment()) ||
2283 (TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS &&
2284 Triple.isMacCatalystEnvironment())) {
2285 TargetVariantTriple = TVT;
2286 continue;
2287 }
2288 TheDriver.Diag(diag::err_drv_target_variant_invalid)
2289 << A->getSpelling() << A->getValue();
2290 }
2291 }
2292 DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget(
2293 Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
2294 SDKInfo);
2295
2296 return PlatformAndVersion;
2297}
2298
2299/// Returns the deployment target that's specified using the -mtargetos option.
2300std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg(
2301 DerivedArgList &Args, const Driver &TheDriver,
2302 const std::optional<DarwinSDKInfo> &SDKInfo) {
2303 auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
2304 if (!A)
2305 return std::nullopt;
2306 llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
2307 switch (TT.getOS()) {
2308 case llvm::Triple::MacOSX:
2309 case llvm::Triple::IOS:
2310 case llvm::Triple::TvOS:
2311 case llvm::Triple::WatchOS:
2312 case llvm::Triple::XROS:
2313 break;
2314 default:
2315 TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
2316 << TT.getOSName() << A->getAsString(Args);
2317 return std::nullopt;
2318 }
2319
2320 VersionTuple Version = TT.getOSVersion();
2321 if (!Version.getMajor()) {
2322 TheDriver.Diag(diag::err_drv_invalid_version_number)
2323 << A->getAsString(Args);
2324 return std::nullopt;
2325 }
2326 return DarwinPlatform::createFromMTargetOS(TT.getOS(), Version,
2327 TT.getEnvironment(), A, SDKInfo);
2328}
2329
2330std::optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
2331 const ArgList &Args,
2332 const Driver &TheDriver) {
2333 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2334 if (!A)
2335 return std::nullopt;
2336 StringRef isysroot = A->getValue();
2337 auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot);
2338 if (!SDKInfoOrErr) {
2339 llvm::consumeError(SDKInfoOrErr.takeError());
2340 TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);
2341 return std::nullopt;
2342 }
2343 return *SDKInfoOrErr;
2344}
2345
2346} // namespace
2347
2348void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2349 const OptTable &Opts = getDriver().getOpts();
2350
2351 // Support allowing the SDKROOT environment variable used by xcrun and other
2352 // Xcode tools to define the default sysroot, by making it the default for
2353 // isysroot.
2354 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2355 // Warn if the path does not exist.
2356 if (!getVFS().exists(A->getValue()))
2357 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
2358 } else {
2359 if (char *env = ::getenv("SDKROOT")) {
2360 // We only use this value as the default if it is an absolute path,
2361 // exists, and it is not the root path.
2362 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
2363 StringRef(env) != "/") {
2364 Args.append(Args.MakeSeparateArg(
2365 nullptr, Opts.getOption(options::OPT_isysroot), env));
2366 }
2367 }
2368 }
2369
2370 // Read the SDKSettings.json file for more information, like the SDK version
2371 // that we can pass down to the compiler.
2372 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
2373
2374 // The OS and the version can be specified using the -target argument.
2375 std::optional<DarwinPlatform> PlatformAndVersion =
2376 getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
2377 if (PlatformAndVersion) {
2378 // Disallow mixing -target and -mtargetos=.
2379 if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
2380 std::string TargetArgStr = PlatformAndVersion->getAsString(Args, Opts);
2381 std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
2382 getDriver().Diag(diag::err_drv_cannot_mix_options)
2383 << TargetArgStr << MTargetOSArgStr;
2384 }
2385 // Implicitly allow resolving the OS version when it wasn't explicitly set.
2386 bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion();
2387 if (!TripleProvidedOSVersion)
2388 PlatformAndVersion->setOSVersion(
2389 getInferredOSVersion(getTriple().getOS(), getTriple(), getDriver()));
2390
2391 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2392 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2393 if (PlatformAndVersionFromOSVersionArg) {
2394 unsigned TargetMajor, TargetMinor, TargetMicro;
2395 bool TargetExtra;
2396 unsigned ArgMajor, ArgMinor, ArgMicro;
2397 bool ArgExtra;
2398 if (PlatformAndVersion->getPlatform() !=
2399 PlatformAndVersionFromOSVersionArg->getPlatform() ||
2401 PlatformAndVersion->getOSVersion().getAsString(), TargetMajor,
2402 TargetMinor, TargetMicro, TargetExtra) &&
2404 PlatformAndVersionFromOSVersionArg->getOSVersion().getAsString(),
2405 ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
2406 (VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
2407 VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
2408 TargetExtra != ArgExtra))) {
2409 // Select the OS version from the -m<os>-version-min argument when
2410 // the -target does not include an OS version.
2411 if (PlatformAndVersion->getPlatform() ==
2412 PlatformAndVersionFromOSVersionArg->getPlatform() &&
2413 !TripleProvidedOSVersion) {
2414 PlatformAndVersion->setOSVersion(
2415 PlatformAndVersionFromOSVersionArg->getOSVersion());
2416 } else {
2417 // Warn about -m<os>-version-min that doesn't match the OS version
2418 // that's specified in the target.
2419 std::string OSVersionArg =
2420 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2421 std::string TargetArg = PlatformAndVersion->getAsString(Args, Opts);
2422 getDriver().Diag(clang::diag::warn_drv_overriding_option)
2423 << OSVersionArg << TargetArg;
2424 }
2425 }
2426 }
2427 } else if ((PlatformAndVersion = getDeploymentTargetFromMTargetOSArg(
2428 Args, getDriver(), SDKInfo))) {
2429 // The OS target can be specified using the -mtargetos= argument.
2430 // Disallow mixing -mtargetos= and -m<os>version-min=.
2431 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2432 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2433 if (PlatformAndVersionFromOSVersionArg) {
2434 std::string MTargetOSArgStr = PlatformAndVersion->getAsString(Args, Opts);
2435 std::string OSVersionArgStr =
2436 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2437 getDriver().Diag(diag::err_drv_cannot_mix_options)
2438 << MTargetOSArgStr << OSVersionArgStr;
2439 }
2440 } else {
2441 // The OS target can be specified using the -m<os>version-min argument.
2442 PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver());
2443 // If no deployment target was specified on the command line, check for
2444 // environment defines.
2445 if (!PlatformAndVersion) {
2446 PlatformAndVersion =
2447 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
2448 if (PlatformAndVersion) {
2449 // Don't infer simulator from the arch when the SDK is also specified.
2450 std::optional<DarwinPlatform> SDKTarget =
2451 inferDeploymentTargetFromSDK(Args, SDKInfo);
2452 if (SDKTarget)
2453 PlatformAndVersion->setEnvironment(SDKTarget->getEnvironment());
2454 }
2455 }
2456 // If there is no command-line argument to specify the Target version and
2457 // no environment variable defined, see if we can set the default based
2458 // on -isysroot using SDKSettings.json if it exists.
2459 if (!PlatformAndVersion) {
2460 PlatformAndVersion = inferDeploymentTargetFromSDK(Args, SDKInfo);
2461 /// If the target was successfully constructed from the SDK path, try to
2462 /// infer the SDK info if the SDK doesn't have it.
2463 if (PlatformAndVersion && !SDKInfo)
2464 SDKInfo = PlatformAndVersion->inferSDKInfo();
2465 }
2466 // If no OS targets have been specified, try to guess platform from -target
2467 // or arch name and compute the version from the triple.
2468 if (!PlatformAndVersion)
2469 PlatformAndVersion =
2470 inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
2471 }
2472
2473 assert(PlatformAndVersion && "Unable to infer Darwin variant");
2474 if (!PlatformAndVersion->isValidOSVersion()) {
2475 if (PlatformAndVersion->isExplicitlySpecified())
2476 getDriver().Diag(diag::err_drv_invalid_version_number)
2477 << PlatformAndVersion->getAsString(Args, Opts);
2478 else
2479 getDriver().Diag(diag::err_drv_invalid_version_number_inferred)
2480 << PlatformAndVersion->getOSVersion().getAsString()
2481 << PlatformAndVersion->getInferredSource();
2482 }
2483 // After the deployment OS version has been resolved, set it to the canonical
2484 // version before further error detection and converting to a proper target
2485 // triple.
2486 VersionTuple CanonicalVersion = PlatformAndVersion->getCanonicalOSVersion();
2487 if (CanonicalVersion != PlatformAndVersion->getOSVersion()) {
2488 getDriver().Diag(diag::warn_drv_overriding_deployment_version)
2489 << PlatformAndVersion->getOSVersion().getAsString()
2490 << CanonicalVersion.getAsString();
2491 PlatformAndVersion->setOSVersion(CanonicalVersion);
2492 }
2493
2494 PlatformAndVersion->addOSVersionMinArgument(Args, Opts);
2495 DarwinPlatformKind Platform = PlatformAndVersion->getPlatform();
2496
2497 unsigned Major, Minor, Micro;
2498 bool HadExtra;
2499 // The major version should not be over this number.
2500 const unsigned MajorVersionLimit = 1000;
2501 const VersionTuple OSVersion = PlatformAndVersion->takeOSVersion();
2502 const std::string OSVersionStr = OSVersion.getAsString();
2503 // Set the tool chain target information.
2504 if (Platform == MacOS) {
2505 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2506 HadExtra) ||
2507 HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||
2508 Micro >= 100)
2509 getDriver().Diag(diag::err_drv_invalid_version_number)
2510 << PlatformAndVersion->getAsString(Args, Opts);
2511 } else if (Platform == IPhoneOS) {
2512 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2513 HadExtra) ||
2514 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2515 getDriver().Diag(diag::err_drv_invalid_version_number)
2516 << PlatformAndVersion->getAsString(Args, Opts);
2517 ;
2518 if (PlatformAndVersion->getEnvironment() == MacCatalyst &&
2519 (Major < 13 || (Major == 13 && Minor < 1))) {
2520 getDriver().Diag(diag::err_drv_invalid_version_number)
2521 << PlatformAndVersion->getAsString(Args, Opts);
2522 Major = 13;
2523 Minor = 1;
2524 Micro = 0;
2525 }
2526 // For 32-bit targets, the deployment target for iOS has to be earlier than
2527 // iOS 11.
2528 if (getTriple().isArch32Bit() && Major >= 11) {
2529 // If the deployment target is explicitly specified, print a diagnostic.
2530 if (PlatformAndVersion->isExplicitlySpecified()) {
2531 if (PlatformAndVersion->getEnvironment() == MacCatalyst)
2532 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
2533 else
2534 getDriver().Diag(diag::warn_invalid_ios_deployment_target)
2535 << PlatformAndVersion->getAsString(Args, Opts);
2536 // Otherwise, set it to 10.99.99.
2537 } else {
2538 Major = 10;
2539 Minor = 99;
2540 Micro = 99;
2541 }
2542 }
2543 } else if (Platform == TvOS) {
2544 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2545 HadExtra) ||
2546 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2547 getDriver().Diag(diag::err_drv_invalid_version_number)
2548 << PlatformAndVersion->getAsString(Args, Opts);
2549 } else if (Platform == WatchOS) {
2550 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2551 HadExtra) ||
2552 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2553 getDriver().Diag(diag::err_drv_invalid_version_number)
2554 << PlatformAndVersion->getAsString(Args, Opts);
2555 } else if (Platform == DriverKit) {
2556 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2557 HadExtra) ||
2558 HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||
2559 Micro >= 100)
2560 getDriver().Diag(diag::err_drv_invalid_version_number)
2561 << PlatformAndVersion->getAsString(Args, Opts);
2562 } else if (Platform == XROS) {
2563 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2564 HadExtra) ||
2565 HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||
2566 Micro >= 100)
2567 getDriver().Diag(diag::err_drv_invalid_version_number)
2568 << PlatformAndVersion->getAsString(Args, Opts);
2569 } else
2570 llvm_unreachable("unknown kind of Darwin platform");
2571
2572 DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();
2573 // Recognize iOS targets with an x86 architecture as the iOS simulator.
2574 if (Environment == NativeEnvironment && Platform != MacOS &&
2575 Platform != DriverKit &&
2576 PlatformAndVersion->canInferSimulatorFromArch() && getTriple().isX86())
2577 Environment = Simulator;
2578
2579 VersionTuple ZipperedOSVersion;
2580 if (Environment == MacCatalyst)
2581 ZipperedOSVersion = PlatformAndVersion->getZipperedOSVersion();
2582 setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);
2583 TargetVariantTriple = PlatformAndVersion->getTargetVariantTriple();
2584 if (TargetVariantTriple &&
2585 !llvm::Triple::isValidVersionForOS(TargetVariantTriple->getOS(),
2586 TargetVariantTriple->getOSVersion())) {
2587 getDriver().Diag(diag::err_drv_invalid_version_number)
2588 << TargetVariantTriple->str();
2589 }
2590
2591 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2592 StringRef SDK = getSDKName(A->getValue());
2593 if (SDK.size() > 0) {
2594 size_t StartVer = SDK.find_first_of("0123456789");
2595 StringRef SDKName = SDK.slice(0, StartVer);
2596 if (!SDKName.starts_with(getPlatformFamily()) &&
2597 !dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily()))
2598 getDriver().Diag(diag::warn_incompatible_sysroot)
2599 << SDKName << getPlatformFamily();
2600 }
2601 }
2602}
2603
2604// For certain platforms/environments almost all resources (e.g., headers) are
2605// located in sub-directories, e.g., for DriverKit they live in
2606// <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).
2608 const llvm::Triple &T) {
2609 if (T.isDriverKit()) {
2610 llvm::sys::path::append(Path, "System", "DriverKit");
2611 }
2612}
2613
2614// Returns the effective sysroot from either -isysroot or --sysroot, plus the
2615// platform prefix (if any).
2617AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
2619 if (DriverArgs.hasArg(options::OPT_isysroot))
2620 Path = DriverArgs.getLastArgValue(options::OPT_isysroot);
2621 else if (!getDriver().SysRoot.empty())
2623
2624 if (hasEffectiveTriple()) {
2626 }
2627 return Path;
2628}
2629
2631 const llvm::opt::ArgList &DriverArgs,
2632 llvm::opt::ArgStringList &CC1Args) const {
2633 const Driver &D = getDriver();
2634
2635 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2636
2637 bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);
2638 bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);
2639 bool NoBuiltinInc = DriverArgs.hasFlag(
2640 options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false);
2641 bool ForceBuiltinInc = DriverArgs.hasFlag(
2642 options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false);
2643
2644 // Add <sysroot>/usr/local/include
2645 if (!NoStdInc && !NoStdlibInc) {
2646 SmallString<128> P(Sysroot);
2647 llvm::sys::path::append(P, "usr", "local", "include");
2648 addSystemInclude(DriverArgs, CC1Args, P);
2649 }
2650
2651 // Add the Clang builtin headers (<resource>/include)
2652 if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) {
2653 SmallString<128> P(D.ResourceDir);
2654 llvm::sys::path::append(P, "include");
2655 addSystemInclude(DriverArgs, CC1Args, P);
2656 }
2657
2658 if (NoStdInc || NoStdlibInc)
2659 return;
2660
2661 // Check for configure-time C include directories.
2662 llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
2663 if (!CIncludeDirs.empty()) {
2665 CIncludeDirs.split(dirs, ":");
2666 for (llvm::StringRef dir : dirs) {
2667 llvm::StringRef Prefix =
2668 llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot);
2669 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
2670 }
2671 } else {
2672 // Otherwise, add <sysroot>/usr/include.
2673 SmallString<128> P(Sysroot);
2674 llvm::sys::path::append(P, "usr", "include");
2675 addExternCSystemInclude(DriverArgs, CC1Args, P.str());
2676 }
2677}
2678
2680 const llvm::opt::ArgList &DriverArgs,
2681 llvm::opt::ArgStringList &CC1Args) const {
2682 AppleMachO::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
2683
2684 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc))
2685 return;
2686
2687 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2688
2689 // Add <sysroot>/System/Library/Frameworks
2690 // Add <sysroot>/System/Library/SubFrameworks
2691 // Add <sysroot>/Library/Frameworks
2692 SmallString<128> P1(Sysroot), P2(Sysroot), P3(Sysroot);
2693 llvm::sys::path::append(P1, "System", "Library", "Frameworks");
2694 llvm::sys::path::append(P2, "System", "Library", "SubFrameworks");
2695 llvm::sys::path::append(P3, "Library", "Frameworks");
2696 addSystemFrameworkIncludes(DriverArgs, CC1Args, {P1, P2, P3});
2697}
2698
2699bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
2700 llvm::opt::ArgStringList &CC1Args,
2702 llvm::StringRef Version,
2703 llvm::StringRef ArchDir,
2704 llvm::StringRef BitDir) const {
2705 llvm::sys::path::append(Base, Version);
2706
2707 // Add the base dir
2708 addSystemInclude(DriverArgs, CC1Args, Base);
2709
2710 // Add the multilib dirs
2711 {
2713 if (!ArchDir.empty())
2714 llvm::sys::path::append(P, ArchDir);
2715 if (!BitDir.empty())
2716 llvm::sys::path::append(P, BitDir);
2717 addSystemInclude(DriverArgs, CC1Args, P);
2718 }
2719
2720 // Add the backward dir
2721 {
2723 llvm::sys::path::append(P, "backward");
2724 addSystemInclude(DriverArgs, CC1Args, P);
2725 }
2726
2727 return getVFS().exists(Base);
2728}
2729
2731 const llvm::opt::ArgList &DriverArgs,
2732 llvm::opt::ArgStringList &CC1Args) const {
2733 // The implementation from a base class will pass through the -stdlib to
2734 // CC1Args.
2735 // FIXME: this should not be necessary, remove usages in the frontend
2736 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
2737 // Also check whether this is used for setting library search paths.
2738 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
2739
2740 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
2741 options::OPT_nostdincxx))
2742 return;
2743
2744 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2745
2746 switch (GetCXXStdlibType(DriverArgs)) {
2747 case ToolChain::CST_Libcxx: {
2748 // On Darwin, libc++ can be installed in one of the following places:
2749 // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
2750 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
2751 //
2752 // The precedence of paths is as listed above, i.e. we take the first path
2753 // that exists. Note that we never include libc++ twice -- we take the first
2754 // path that exists and don't send the other paths to CC1 (otherwise
2755 // include_next could break).
2756
2757 // Check for (1)
2758 // Get from '<install>/bin' to '<install>/include/c++/v1'.
2759 // Note that InstallBin can be relative, so we use '..' instead of
2760 // parent_path.
2761 llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin
2762 llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
2763 if (getVFS().exists(InstallBin)) {
2764 addSystemInclude(DriverArgs, CC1Args, InstallBin);
2765 return;
2766 } else if (DriverArgs.hasArg(options::OPT_v)) {
2767 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
2768 << "\"\n";
2769 }
2770
2771 // Otherwise, check for (2)
2772 llvm::SmallString<128> SysrootUsr = Sysroot;
2773 llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
2774 if (getVFS().exists(SysrootUsr)) {
2775 addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
2776 return;
2777 } else if (DriverArgs.hasArg(options::OPT_v)) {
2778 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
2779 << "\"\n";
2780 }
2781
2782 // Otherwise, don't add any path.
2783 break;
2784 }
2785
2787 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
2788 break;
2789 }
2790}
2791
2792void AppleMachO::AddGnuCPlusPlusIncludePaths(
2793 const llvm::opt::ArgList &DriverArgs,
2794 llvm::opt::ArgStringList &CC1Args) const {}
2795
2796void DarwinClang::AddGnuCPlusPlusIncludePaths(
2797 const llvm::opt::ArgList &DriverArgs,
2798 llvm::opt::ArgStringList &CC1Args) const {
2799 llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);
2800 llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
2801
2802 llvm::Triple::ArchType arch = getTriple().getArch();
2803 bool IsBaseFound = true;
2804 switch (arch) {
2805 default:
2806 break;
2807
2808 case llvm::Triple::x86:
2809 case llvm::Triple::x86_64:
2810 IsBaseFound = AddGnuCPlusPlusIncludePaths(
2811 DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",
2812 arch == llvm::Triple::x86_64 ? "x86_64" : "");
2813 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
2814 DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");
2815 break;
2816
2817 case llvm::Triple::arm:
2818 case llvm::Triple::thumb:
2819 IsBaseFound =
2820 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2821 "arm-apple-darwin10", "v7");
2822 IsBaseFound |=
2823 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2824 "arm-apple-darwin10", "v6");
2825 break;
2826
2827 case llvm::Triple::aarch64:
2828 IsBaseFound =
2829 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2830 "arm64-apple-darwin10", "");
2831 break;
2832 }
2833
2834 if (!IsBaseFound) {
2835 getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
2836 }
2837}
2838
2839void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
2840 ArgStringList &CmdArgs) const {
2842
2843 switch (Type) {
2845 CmdArgs.push_back("-lc++");
2846 if (Args.hasArg(options::OPT_fexperimental_library))
2847 CmdArgs.push_back("-lc++experimental");
2848 break;
2849
2851 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
2852 // it was previously found in the gcc lib dir. However, for all the Darwin
2853 // platforms we care about it was -lstdc++.6, so we search for that
2854 // explicitly if we can't see an obvious -lstdc++ candidate.
2855
2856 // Check in the sysroot first.
2857 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2858 SmallString<128> P(A->getValue());
2859 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
2860
2861 if (!getVFS().exists(P)) {
2862 llvm::sys::path::remove_filename(P);
2863 llvm::sys::path::append(P, "libstdc++.6.dylib");
2864 if (getVFS().exists(P)) {
2865 CmdArgs.push_back(Args.MakeArgString(P));
2866 return;
2867 }
2868 }
2869 }
2870
2871 // Otherwise, look in the root.
2872 // FIXME: This should be removed someday when we don't have to care about
2873 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
2874 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
2875 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
2876 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
2877 return;
2878 }
2879
2880 // Otherwise, let the linker search.
2881 CmdArgs.push_back("-lstdc++");
2882 break;
2883 }
2884}
2885
2886void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
2887 ArgStringList &CmdArgs) const {
2888 // For Darwin platforms, use the compiler-rt-based support library
2889 // instead of the gcc-provided one (which is also incidentally
2890 // only present in the gcc lib dir, which makes it hard to find).
2891
2892 SmallString<128> P(getDriver().ResourceDir);
2893 llvm::sys::path::append(P, "lib", "darwin");
2894
2895 // Use the newer cc_kext for iOS ARM after 6.0.
2896 if (isTargetWatchOS()) {
2897 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
2898 } else if (isTargetTvOS()) {
2899 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
2900 } else if (isTargetIPhoneOS()) {
2901 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
2902 } else if (isTargetDriverKit()) {
2903 // DriverKit doesn't want extra runtime support.
2904 } else if (isTargetXROSDevice()) {
2905 llvm::sys::path::append(
2906 P, llvm::Twine("libclang_rt.cc_kext_") +
2907 llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a");
2908 } else {
2909 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
2910 }
2911
2912 // For now, allow missing resource libraries to support developers who may
2913 // not have compiler-rt checked out or integrated into their build.
2914 if (getVFS().exists(P))
2915 CmdArgs.push_back(Args.MakeArgString(P));
2916}
2917
2918DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
2919 StringRef BoundArch,
2920 Action::OffloadKind) const {
2921 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
2922 const OptTable &Opts = getDriver().getOpts();
2923
2924 // FIXME: We really want to get out of the tool chain level argument
2925 // translation business, as it makes the driver functionality much
2926 // more opaque. For now, we follow gcc closely solely for the
2927 // purpose of easily achieving feature parity & testability. Once we
2928 // have something that works, we should reevaluate each translation
2929 // and try to push it down into tool specific logic.
2930
2931 for (Arg *A : Args) {
2932 // Sob. These is strictly gcc compatible for the time being. Apple
2933 // gcc translates options twice, which means that self-expanding
2934 // options add duplicates.
2935 switch ((options::ID)A->getOption().getID()) {
2936 default:
2937 DAL->append(A);
2938 break;
2939
2940 case options::OPT_mkernel:
2941 case options::OPT_fapple_kext:
2942 DAL->append(A);
2943 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
2944 break;
2945
2946 case options::OPT_dependency_file:
2947 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
2948 break;
2949
2950 case options::OPT_gfull:
2951 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2952 DAL->AddFlagArg(
2953 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
2954 break;
2955
2956 case options::OPT_gused:
2957 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2958 DAL->AddFlagArg(
2959 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
2960 break;
2961
2962 case options::OPT_shared:
2963 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
2964 break;
2965
2966 case options::OPT_fconstant_cfstrings:
2967 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
2968 break;
2969
2970 case options::OPT_fno_constant_cfstrings:
2971 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
2972 break;
2973
2974 case options::OPT_Wnonportable_cfstrings:
2975 DAL->AddFlagArg(A,
2976 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
2977 break;
2978
2979 case options::OPT_Wno_nonportable_cfstrings:
2980 DAL->AddFlagArg(
2981 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
2982 break;
2983 }
2984 }
2985
2986 // Add the arch options based on the particular spelling of -arch, to match
2987 // how the driver works.
2988 if (!BoundArch.empty()) {
2989 StringRef Name = BoundArch;
2990 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
2991 const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ);
2992
2993 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
2994 // which defines the list of which architectures we accept.
2995 if (Name == "ppc")
2996 ;
2997 else if (Name == "ppc601")
2998 DAL->AddJoinedArg(nullptr, MCpu, "601");
2999 else if (Name == "ppc603")
3000 DAL->AddJoinedArg(nullptr, MCpu, "603");
3001 else if (Name == "ppc604")
3002 DAL->AddJoinedArg(nullptr, MCpu, "604");
3003 else if (Name == "ppc604e")
3004 DAL->AddJoinedArg(nullptr, MCpu, "604e");
3005 else if (Name == "ppc750")
3006 DAL->AddJoinedArg(nullptr, MCpu, "750");
3007 else if (Name == "ppc7400")
3008 DAL->AddJoinedArg(nullptr, MCpu, "7400");
3009 else if (Name == "ppc7450")
3010 DAL->AddJoinedArg(nullptr, MCpu, "7450");
3011 else if (Name == "ppc970")
3012 DAL->AddJoinedArg(nullptr, MCpu, "970");
3013
3014 else if (Name == "ppc64" || Name == "ppc64le")
3015 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3016
3017 else if (Name == "i386")
3018 ;
3019 else if (Name == "i486")
3020 DAL->AddJoinedArg(nullptr, MArch, "i486");
3021 else if (Name == "i586")
3022 DAL->AddJoinedArg(nullptr, MArch, "i586");
3023 else if (Name == "i686")
3024 DAL->AddJoinedArg(nullptr, MArch, "i686");
3025 else if (Name == "pentium")
3026 DAL->AddJoinedArg(nullptr, MArch, "pentium");
3027 else if (Name == "pentium2")
3028 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3029 else if (Name == "pentpro")
3030 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
3031 else if (Name == "pentIIm3")
3032 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3033
3034 else if (Name == "x86_64" || Name == "x86_64h")
3035 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3036
3037 else if (Name == "arm")
3038 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3039 else if (Name == "armv4t")
3040 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3041 else if (Name == "armv5")
3042 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
3043 else if (Name == "xscale")
3044 DAL->AddJoinedArg(nullptr, MArch, "xscale");
3045 else if (Name == "armv6")
3046 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
3047 else if (Name == "armv6m")
3048 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
3049 else if (Name == "armv7")
3050 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
3051 else if (Name == "armv7em")
3052 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
3053 else if (Name == "armv7k")
3054 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
3055 else if (Name == "armv7m")
3056 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
3057 else if (Name == "armv7s")
3058 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
3059 }
3060
3061 return DAL;
3062}
3063
3064void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
3065 ArgStringList &CmdArgs,
3066 bool ForceLinkBuiltinRT) const {
3067 // Embedded targets are simple at the moment, not supporting sanitizers and
3068 // with different libraries for each member of the product { static, PIC } x
3069 // { hard-float, soft-float }
3070 llvm::SmallString<32> CompilerRT = StringRef("");
3071 CompilerRT +=
3073 ? "hard"
3074 : "soft";
3075 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static";
3076
3077 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);
3078}
3079
3081 llvm::Triple::OSType OS;
3082
3083 if (isTargetMacCatalyst())
3084 return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX);
3085 switch (TargetPlatform) {
3086 case MacOS: // Earlier than 10.13.
3087 OS = llvm::Triple::MacOSX;
3088 break;
3089 case IPhoneOS:
3090 OS = llvm::Triple::IOS;
3091 break;
3092 case TvOS: // Earlier than 11.0.
3093 OS = llvm::Triple::TvOS;
3094 break;
3095 case WatchOS: // Earlier than 4.0.
3096 OS = llvm::Triple::WatchOS;
3097 break;
3098 case XROS: // Always available.
3099 return false;
3100 case DriverKit: // Always available.
3101 return false;
3102 }
3103
3105}
3106
3107static bool
3108sdkSupportsBuiltinModules(const std::optional<DarwinSDKInfo> &SDKInfo) {
3109 if (!SDKInfo)
3110 // If there is no SDK info, assume this is building against a
3111 // pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those
3112 // don't support modules anyway, but the headers definitely
3113 // don't support builtin modules either. It might also be some
3114 // kind of degenerate build environment, err on the side of
3115 // the old behavior which is to not use builtin modules.
3116 return false;
3117
3118 VersionTuple SDKVersion = SDKInfo->getVersion();
3119 switch (SDKInfo->getOS()) {
3120 // Existing SDKs added support for builtin modules in the fall
3121 // 2024 major releases.
3122 case llvm::Triple::MacOSX:
3123 return SDKVersion >= VersionTuple(15U);
3124 case llvm::Triple::IOS:
3125 return SDKVersion >= VersionTuple(18U);
3126 case llvm::Triple::TvOS:
3127 return SDKVersion >= VersionTuple(18U);
3128 case llvm::Triple::WatchOS:
3129 return SDKVersion >= VersionTuple(11U);
3130 case llvm::Triple::XROS:
3131 return SDKVersion >= VersionTuple(2U);
3132
3133 // New SDKs support builtin modules from the start.
3134 default:
3135 return true;
3136 }
3137}
3138
3139static inline llvm::VersionTuple
3140sizedDeallocMinVersion(llvm::Triple::OSType OS) {
3141 switch (OS) {
3142 default:
3143 break;
3144 case llvm::Triple::Darwin:
3145 case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.
3146 return llvm::VersionTuple(10U, 12U);
3147 case llvm::Triple::IOS:
3148 case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0.
3149 return llvm::VersionTuple(10U);
3150 case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0.
3151 return llvm::VersionTuple(3U);
3152 }
3153
3154 llvm_unreachable("Unexpected OS");
3155}
3156
3158 llvm::Triple::OSType OS;
3159
3160 if (isTargetMacCatalyst())
3161 return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX);
3162 switch (TargetPlatform) {
3163 case MacOS: // Earlier than 10.12.
3164 OS = llvm::Triple::MacOSX;
3165 break;
3166 case IPhoneOS:
3167 OS = llvm::Triple::IOS;
3168 break;
3169 case TvOS: // Earlier than 10.0.
3170 OS = llvm::Triple::TvOS;
3171 break;
3172 case WatchOS: // Earlier than 3.0.
3173 OS = llvm::Triple::WatchOS;
3174 break;
3175 case DriverKit:
3176 case XROS:
3177 // Always available.
3178 return false;
3179 }
3180
3182}
3183
3184void MachO::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
3185 llvm::opt::ArgStringList &CC1Args,
3186 Action::OffloadKind DeviceOffloadKind) const {
3187
3188 ToolChain::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3189
3190 // On arm64e, we enable all the features required for the Darwin userspace
3191 // ABI
3192 if (getTriple().isArm64e()) {
3193 // Core platform ABI
3194 if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
3195 options::OPT_fno_ptrauth_calls))
3196 CC1Args.push_back("-fptrauth-calls");
3197 if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
3198 options::OPT_fno_ptrauth_returns))
3199 CC1Args.push_back("-fptrauth-returns");
3200 if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
3201 options::OPT_fno_ptrauth_intrinsics))
3202 CC1Args.push_back("-fptrauth-intrinsics");
3203 if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos,
3204 options::OPT_fno_ptrauth_indirect_gotos))
3205 CC1Args.push_back("-fptrauth-indirect-gotos");
3206 if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
3207 options::OPT_fno_ptrauth_auth_traps))
3208 CC1Args.push_back("-fptrauth-auth-traps");
3209
3210 // C++ v-table ABI
3211 if (!DriverArgs.hasArg(
3212 options::OPT_fptrauth_vtable_pointer_address_discrimination,
3213 options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
3214 CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
3215 if (!DriverArgs.hasArg(
3216 options::OPT_fptrauth_vtable_pointer_type_discrimination,
3217 options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
3218 CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
3219
3220 // Objective-C ABI
3221 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_isa,
3222 options::OPT_fno_ptrauth_objc_isa))
3223 CC1Args.push_back("-fptrauth-objc-isa");
3224 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_class_ro,
3225 options::OPT_fno_ptrauth_objc_class_ro))
3226 CC1Args.push_back("-fptrauth-objc-class-ro");
3227 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_interface_sel,
3228 options::OPT_fno_ptrauth_objc_interface_sel))
3229 CC1Args.push_back("-fptrauth-objc-interface-sel");
3230 }
3231}
3232
3234 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
3235 Action::OffloadKind DeviceOffloadKind) const {
3236
3237 MachO::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3238
3239 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
3240 // enabled or disabled aligned allocations.
3241 if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
3242 options::OPT_fno_aligned_allocation) &&
3244 CC1Args.push_back("-faligned-alloc-unavailable");
3245
3246 // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
3247 // or disabled sized deallocations.
3248 if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,
3249 options::OPT_fno_sized_deallocation) &&
3251 CC1Args.push_back("-fno-sized-deallocation");
3252
3253 addClangCC1ASTargetOptions(DriverArgs, CC1Args);
3254
3255 // Enable compatibility mode for NSItemProviderCompletionHandler in
3256 // Foundation/NSItemProvider.h.
3257 CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking");
3258
3259 // Give static local variables in inline functions hidden visibility when
3260 // -fvisibility-inlines-hidden is enabled.
3261 if (!DriverArgs.getLastArgNoClaim(
3262 options::OPT_fvisibility_inlines_hidden_static_local_var,
3263 options::OPT_fno_visibility_inlines_hidden_static_local_var))
3264 CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");
3265
3266 // Earlier versions of the darwin SDK have the C standard library headers
3267 // all together in the Darwin module. That leads to module cycles with
3268 // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.
3269 // The builtin <stdint.h> include-nexts <stdint.h>. When both of those
3270 // darwin headers are in the Darwin module, there's a module cycle Darwin ->
3271 // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->
3272 // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,
3273 // but until then, the builtin headers need to join the system modules.
3274 // i.e. when the builtin stdint.h is in the Darwin module too, the cycle
3275 // goes away. Note that -fbuiltin-headers-in-system-modules does nothing
3276 // to fix the same problem with C++ headers, and is generally fragile.
3278 CC1Args.push_back("-fbuiltin-headers-in-system-modules");
3279
3280 if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros,
3281 options::OPT_fno_define_target_os_macros))
3282 CC1Args.push_back("-fdefine-target-os-macros");
3283
3284 // Disable subdirectory modulemap search on sufficiently recent SDKs.
3285 if (SDKInfo &&
3286 !DriverArgs.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search,
3287 options::OPT_fno_modulemap_allow_subdirectory_search,
3288 false)) {
3289 bool RequiresSubdirectorySearch;
3290 VersionTuple SDKVersion = SDKInfo->getVersion();
3291 switch (TargetPlatform) {
3292 default:
3293 RequiresSubdirectorySearch = true;
3294 break;
3295 case MacOS:
3296 RequiresSubdirectorySearch = SDKVersion < VersionTuple(15, 0);
3297 break;
3298 case IPhoneOS:
3299 case TvOS:
3300 RequiresSubdirectorySearch = SDKVersion < VersionTuple(18, 0);
3301 break;
3302 case WatchOS:
3303 RequiresSubdirectorySearch = SDKVersion < VersionTuple(11, 0);
3304 break;
3305 case XROS:
3306 RequiresSubdirectorySearch = SDKVersion < VersionTuple(2, 0);
3307 break;
3308 }
3309 if (!RequiresSubdirectorySearch)
3310 CC1Args.push_back("-fno-modulemap-allow-subdirectory-search");
3311 }
3312}
3313
3315 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const {
3316 if (TargetVariantTriple) {
3317 CC1ASArgs.push_back("-darwin-target-variant-triple");
3318 CC1ASArgs.push_back(Args.MakeArgString(TargetVariantTriple->getTriple()));
3319 }
3320
3321 if (SDKInfo) {
3322 /// Pass the SDK version to the compiler when the SDK information is
3323 /// available.
3324 auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) {
3325 std::string Arg;
3326 llvm::raw_string_ostream OS(Arg);
3327 OS << "-target-sdk-version=" << V;
3328 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3329 };
3330
3331 if (isTargetMacCatalyst()) {
3332 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
3334 std::optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(
3336 std::nullopt);
3337 EmitTargetSDKVersionArg(
3338 SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget());
3339 }
3340 } else {
3341 EmitTargetSDKVersionArg(SDKInfo->getVersion());
3342 }
3343
3344 /// Pass the target variant SDK version to the compiler when the SDK
3345 /// information is available and is required for target variant.
3346 if (TargetVariantTriple) {
3347 if (isTargetMacCatalyst()) {
3348 std::string Arg;
3349 llvm::raw_string_ostream OS(Arg);
3350 OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();
3351 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3352 } else if (const auto *MacOStoMacCatalystMapping =
3353 SDKInfo->getVersionMapping(
3355 if (std::optional<VersionTuple> SDKVersion =
3356 MacOStoMacCatalystMapping->map(
3358 std::nullopt)) {
3359 std::string Arg;
3360 llvm::raw_string_ostream OS(Arg);
3361 OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;
3362 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3363 }
3364 }
3365 }
3366 }
3367}
3368
3369DerivedArgList *
3370Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
3371 Action::OffloadKind DeviceOffloadKind) const {
3372 // First get the generic Apple args, before moving onto Darwin-specific ones.
3373 DerivedArgList *DAL =
3374 MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
3375
3376 // If no architecture is bound, none of the translations here are relevant.
3377 if (BoundArch.empty())
3378 return DAL;
3379
3380 // Add an explicit version min argument for the deployment target. We do this
3381 // after argument translation because -Xarch_ arguments may add a version min
3382 // argument.
3383 AddDeploymentTarget(*DAL);
3384
3385 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
3386 // FIXME: It would be far better to avoid inserting those -static arguments,
3387 // but we can't check the deployment target in the translation code until
3388 // it is set here.
3390 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
3391 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
3392 Arg *A = *it;
3393 ++it;
3394 if (A->getOption().getID() != options::OPT_mkernel &&
3395 A->getOption().getID() != options::OPT_fapple_kext)
3396 continue;
3397 assert(it != ie && "unexpected argument translation");
3398 A = *it;
3399 assert(A->getOption().getID() == options::OPT_static &&
3400 "missing expected -static argument");
3401 *it = nullptr;
3402 ++it;
3403 }
3404 }
3405
3407 if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {
3408 if (Args.hasFlag(options::OPT_fomit_frame_pointer,
3409 options::OPT_fno_omit_frame_pointer, false))
3410 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
3411 << "-fomit-frame-pointer" << BoundArch;
3412 }
3413
3414 return DAL;
3415}
3416
3418 // Unwind tables are not emitted if -fno-exceptions is supplied (except when
3419 // targeting x86_64).
3420 if (getArch() == llvm::Triple::x86_64 ||
3421 (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&
3422 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
3423 true)))
3424 return (getArch() == llvm::Triple::aarch64 ||
3425 getArch() == llvm::Triple::aarch64_32)
3428
3430}
3431
3433 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
3434 return S[0] != '\0';
3435 return false;
3436}
3437
3439 if (const char *S = ::getenv("RC_DEBUG_PREFIX_MAP"))
3440 return S;
3441 return {};
3442}
3443
3444llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {
3445 // Darwin uses SjLj exceptions on ARM.
3446 if (getTriple().getArch() != llvm::Triple::arm &&
3447 getTriple().getArch() != llvm::Triple::thumb)
3448 return llvm::ExceptionHandling::None;
3449
3450 // Only watchOS uses the new DWARF/Compact unwinding method.
3451 llvm::Triple Triple(ComputeLLVMTriple(Args));
3452 if (Triple.isWatchABI())
3453 return llvm::ExceptionHandling::DwarfCFI;
3454
3455 return llvm::ExceptionHandling::SjLj;
3456}
3457
3459 assert(TargetInitialized && "Target not initialized!");
3461 return false;
3462 return true;
3463}
3464
3465bool MachO::isPICDefault() const { return true; }
3466
3467bool MachO::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; }
3468
3470 return (getArch() == llvm::Triple::x86_64 ||
3471 getArch() == llvm::Triple::aarch64);
3472}
3473
3475 // Profiling instrumentation is only supported on x86.
3476 return getTriple().isX86();
3477}
3478
3479void Darwin::addMinVersionArgs(const ArgList &Args,
3480 ArgStringList &CmdArgs) const {
3481 VersionTuple TargetVersion = getTripleTargetVersion();
3482
3483 assert(!isTargetXROS() && "xrOS always uses -platform-version");
3484
3485 if (isTargetWatchOS())
3486 CmdArgs.push_back("-watchos_version_min");
3487 else if (isTargetWatchOSSimulator())
3488 CmdArgs.push_back("-watchos_simulator_version_min");
3489 else if (isTargetTvOS())
3490 CmdArgs.push_back("-tvos_version_min");
3491 else if (isTargetTvOSSimulator())
3492 CmdArgs.push_back("-tvos_simulator_version_min");
3493 else if (isTargetDriverKit())
3494 CmdArgs.push_back("-driverkit_version_min");
3495 else if (isTargetIOSSimulator())
3496 CmdArgs.push_back("-ios_simulator_version_min");
3497 else if (isTargetIOSBased())
3498 CmdArgs.push_back("-iphoneos_version_min");
3499 else if (isTargetMacCatalyst())
3500 CmdArgs.push_back("-maccatalyst_version_min");
3501 else {
3502 assert(isTargetMacOS() && "unexpected target");
3503 CmdArgs.push_back("-macosx_version_min");
3504 }
3505
3506 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
3507 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3508 TargetVersion = MinTgtVers;
3509 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3510 if (TargetVariantTriple) {
3511 assert(isTargetMacOSBased() && "unexpected target");
3512 VersionTuple VariantTargetVersion;
3513 if (TargetVariantTriple->isMacOSX()) {
3514 CmdArgs.push_back("-macosx_version_min");
3515 TargetVariantTriple->getMacOSXVersion(VariantTargetVersion);
3516 } else {
3517 assert(TargetVariantTriple->isiOS() &&
3518 TargetVariantTriple->isMacCatalystEnvironment() &&
3519 "unexpected target variant triple");
3520 CmdArgs.push_back("-maccatalyst_version_min");
3521 VariantTargetVersion = TargetVariantTriple->getiOSVersion();
3522 }
3523 VersionTuple MinTgtVers =
3524 TargetVariantTriple->getMinimumSupportedOSVersion();
3525 if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion)
3526 VariantTargetVersion = MinTgtVers;
3527 CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString()));
3528 }
3529}
3530
3532 Darwin::DarwinEnvironmentKind Environment) {
3533 switch (Platform) {
3534 case Darwin::MacOS:
3535 return "macos";
3536 case Darwin::IPhoneOS:
3537 if (Environment == Darwin::MacCatalyst)
3538 return "mac catalyst";
3539 return "ios";
3540 case Darwin::TvOS:
3541 return "tvos";
3542 case Darwin::WatchOS:
3543 return "watchos";
3544 case Darwin::XROS:
3545 return "xros";
3546 case Darwin::DriverKit:
3547 return "driverkit";
3548 }
3549 llvm_unreachable("invalid platform");
3550}
3551
3552void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
3553 llvm::opt::ArgStringList &CmdArgs) const {
3554 auto EmitPlatformVersionArg =
3555 [&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,
3557 const llvm::Triple &TT) {
3558 // -platform_version <platform> <target_version> <sdk_version>
3559 // Both the target and SDK version support only up to 3 components.
3560 CmdArgs.push_back("-platform_version");
3561 std::string PlatformName =
3564 PlatformName += "-simulator";
3565 CmdArgs.push_back(Args.MakeArgString(PlatformName));
3566 VersionTuple TargetVersion = TV.withoutBuild();
3569 getTriple().getArchName() == "arm64e" &&
3570 TargetVersion.getMajor() < 14) {
3571 // arm64e slice is supported on iOS/tvOS 14+ only.
3572 TargetVersion = VersionTuple(14, 0);
3573 }
3574 VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion();
3575 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3576 TargetVersion = MinTgtVers;
3577 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3578
3580 // Mac Catalyst programs must use the appropriate iOS SDK version
3581 // that corresponds to the macOS SDK version used for the compilation.
3582 std::optional<VersionTuple> iOSSDKVersion;
3583 if (SDKInfo) {
3584 if (const auto *MacOStoMacCatalystMapping =
3585 SDKInfo->getVersionMapping(
3587 iOSSDKVersion = MacOStoMacCatalystMapping->map(
3588 SDKInfo->getVersion().withoutBuild(),
3589 minimumMacCatalystDeploymentTarget(), std::nullopt);
3590 }
3591 }
3592 CmdArgs.push_back(Args.MakeArgString(
3593 (iOSSDKVersion ? *iOSSDKVersion
3595 .getAsString()));
3596 return;
3597 }
3598
3599 if (SDKInfo) {
3600 VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
3601 if (!SDKVersion.getMinor())
3602 SDKVersion = VersionTuple(SDKVersion.getMajor(), 0);
3603 CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
3604 } else {
3605 // Use an SDK version that's matching the deployment target if the SDK
3606 // version is missing. This is preferred over an empty SDK version
3607 // (0.0.0) as the system's runtime might expect the linked binary to
3608 // contain a valid SDK version in order for the binary to work
3609 // correctly. It's reasonable to use the deployment target version as
3610 // a proxy for the SDK version because older SDKs don't guarantee
3611 // support for deployment targets newer than the SDK versions, so that
3612 // rules out using some predetermined older SDK version, which leaves
3613 // the deployment target version as the only reasonable choice.
3614 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3615 }
3616 };
3617 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform,
3620 return;
3623 VersionTuple TargetVariantVersion;
3624 if (TargetVariantTriple->isMacOSX()) {
3625 TargetVariantTriple->getMacOSXVersion(TargetVariantVersion);
3626 Platform = Darwin::MacOS;
3627 Environment = Darwin::NativeEnvironment;
3628 } else {
3629 assert(TargetVariantTriple->isiOS() &&
3630 TargetVariantTriple->isMacCatalystEnvironment() &&
3631 "unexpected target variant triple");
3632 TargetVariantVersion = TargetVariantTriple->getiOSVersion();
3633 Platform = Darwin::IPhoneOS;
3634 Environment = Darwin::MacCatalyst;
3635 }
3636 EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment,
3638}
3639
3640// Add additional link args for the -dynamiclib option.
3641static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args,
3642 ArgStringList &CmdArgs) {
3643 // Derived from darwin_dylib1 spec.
3644 if (D.isTargetIPhoneOS()) {
3645 if (D.isIPhoneOSVersionLT(3, 1))
3646 CmdArgs.push_back("-ldylib1.o");
3647 return;
3648 }
3649
3650 if (!D.isTargetMacOS())
3651 return;
3652 if (D.isMacosxVersionLT(10, 5))
3653 CmdArgs.push_back("-ldylib1.o");
3654 else if (D.isMacosxVersionLT(10, 6))
3655 CmdArgs.push_back("-ldylib1.10.5.o");
3656}
3657
3658// Add additional link args for the -bundle option.
3659static void addBundleLinkArgs(const Darwin &D, const ArgList &Args,
3660 ArgStringList &CmdArgs) {
3661 if (Args.hasArg(options::OPT_static))
3662 return;
3663 // Derived from darwin_bundle1 spec.
3664 if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) ||
3665 (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6)))
3666 CmdArgs.push_back("-lbundle1.o");
3667}
3668
3669// Add additional link args for the -pg option.
3670static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,
3671 ArgStringList &CmdArgs) {
3672 if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) {
3673 if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) ||
3674 Args.hasArg(options::OPT_preload)) {
3675 CmdArgs.push_back("-lgcrt0.o");
3676 } else {
3677 CmdArgs.push_back("-lgcrt1.o");
3678
3679 // darwin_crt2 spec is empty.
3680 }
3681 // By default on OS X 10.8 and later, we don't link with a crt1.o
3682 // file and the linker knows to use _main as the entry point. But,
3683 // when compiling with -pg, we need to link with the gcrt1.o file,
3684 // so pass the -no_new_main option to tell the linker to use the
3685 // "start" symbol as the entry point.
3686 if (!D.isMacosxVersionLT(10, 8))
3687 CmdArgs.push_back("-no_new_main");
3688 } else {
3689 D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
3690 << D.isTargetMacOSBased();
3691 }
3692}
3693
3694static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args,
3695 ArgStringList &CmdArgs) {
3696 // Derived from darwin_crt1 spec.
3697 if (D.isTargetIPhoneOS()) {
3698 if (D.getArch() == llvm::Triple::aarch64)
3699 ; // iOS does not need any crt1 files for arm64
3700 else if (D.isIPhoneOSVersionLT(3, 1))
3701 CmdArgs.push_back("-lcrt1.o");
3702 else if (D.isIPhoneOSVersionLT(6, 0))
3703 CmdArgs.push_back("-lcrt1.3.1.o");
3704 return;
3705 }
3706
3707 if (!D.isTargetMacOS())
3708 return;
3709 if (D.isMacosxVersionLT(10, 5))
3710 CmdArgs.push_back("-lcrt1.o");
3711 else if (D.isMacosxVersionLT(10, 6))
3712 CmdArgs.push_back("-lcrt1.10.5.o");
3713 else if (D.isMacosxVersionLT(10, 8))
3714 CmdArgs.push_back("-lcrt1.10.6.o");
3715 // darwin_crt2 spec is empty.
3716}
3717
3718void Darwin::addStartObjectFileArgs(const ArgList &Args,
3719 ArgStringList &CmdArgs) const {
3720 // Derived from startfile spec.
3721 if (Args.hasArg(options::OPT_dynamiclib))
3722 addDynamicLibLinkArgs(*this, Args, CmdArgs);
3723 else if (Args.hasArg(options::OPT_bundle))
3724 addBundleLinkArgs(*this, Args, CmdArgs);
3725 else if (Args.hasArg(options::OPT_pg) && SupportsProfiling())
3726 addPgProfilingLinkArgs(*this, Args, CmdArgs);
3727 else if (Args.hasArg(options::OPT_static) ||
3728 Args.hasArg(options::OPT_object) ||
3729 Args.hasArg(options::OPT_preload))
3730 CmdArgs.push_back("-lcrt0.o");
3731 else
3732 addDefaultCRTLinkArgs(*this, Args, CmdArgs);
3733
3734 if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) &&
3735 isMacosxVersionLT(10, 5)) {
3736 const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
3737 CmdArgs.push_back(Str);
3738 }
3739}
3740
3744 return;
3745 getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
3746}
3747
3749 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3750 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
3752 Res |= SanitizerKind::Address;
3753 Res |= SanitizerKind::PointerCompare;
3754 Res |= SanitizerKind::PointerSubtract;
3755 Res |= SanitizerKind::Realtime;
3756 Res |= SanitizerKind::Leak;
3757 Res |= SanitizerKind::Fuzzer;
3758 Res |= SanitizerKind::FuzzerNoLink;
3759 Res |= SanitizerKind::ObjCCast;
3760
3761 // Prior to 10.9, macOS shipped a version of the C++ standard library without
3762 // C++11 support. The same is true of iOS prior to version 5. These OS'es are
3763 // incompatible with -fsanitize=vptr.
3764 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
3766 Res |= SanitizerKind::Vptr;
3767
3768 if ((IsX86_64 || IsAArch64) &&
3771 Res |= SanitizerKind::Thread;
3772 }
3773
3774 if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
3775 Res |= SanitizerKind::Type;
3776 }
3777
3778 if (IsX86_64)
3779 Res |= SanitizerKind::NumericalStability;
3780
3781 return Res;
3782}
3783
3784void AppleMachO::printVerboseInfo(raw_ostream &OS) const {
3785 CudaInstallation->print(OS);
3786 RocmInstallation->print(OS);
3787}
#define V(N, I)
Definition: ASTContext.h:3597
StringRef P
Defines a function that returns the minimum OS versions supporting C++17's aligned allocation functio...
const Decl * D
IndirectLocalPath & Path
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
static bool hasMultipleInvocations(const llvm::Triple &Triple, const ArgList &Args)
Definition: Clang.cpp:1197
static bool checkRemarksOptions(const Driver &D, const ArgList &Args, const llvm::Triple &Triple)
Definition: Clang.cpp:1208
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple, const InputInfo &Input, const InputInfo &Output, const JobAction &JA)
Definition: Clang.cpp:1224
static bool sdkSupportsBuiltinModules(const std::optional< DarwinSDKInfo > &SDKInfo)
Definition: Darwin.cpp:3108
static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition: Darwin.cpp:3670
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:3694
static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition: Darwin.cpp:3659
static llvm::VersionTuple sizedDeallocMinVersion(llvm::Triple::OSType OS)
Definition: Darwin.cpp:3140
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:1662
static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition: Darwin.cpp:3641
static void AppendPlatformPrefix(SmallString< 128 > &Path, const llvm::Triple &T)
Definition: Darwin.cpp:2607
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:3531
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
const Environment & Env
Definition: HTMLLogger.cpp:147
CompileCommand Cmd
llvm::MachO::Target Target
Definition: MachO.h:51
Defines types useful for describing an Objective-C runtime.
OffloadArch Arch
Definition: OffloadArch.cpp:10
const char * ArchName
Definition: OffloadArch.cpp:11
The information about the darwin SDK that was used during this compilation.
Definition: DarwinSDKInfo.h:29
The basic abstraction for the target Objective-C runtime.
Definition: ObjCRuntime.h:28
bool hasNativeARC() const
Does this runtime natively provide the ARC entrypoints?
Definition: ObjCRuntime.h:170
bool hasSubscripting() const
Does this runtime directly support the subscripting methods?
Definition: ObjCRuntime.h:314
@ 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
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:7026
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:428
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
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
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.
Definition: ToolChain.cpp:1436
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.
Definition: ToolChain.cpp:1444
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.
Definition: ToolChain.cpp:1421
std::string GetFilePath(const char *Name) const
Definition: ToolChain.cpp:1090
static bool needsProfileRT(const llvm::opt::ArgList &Args)
needsProfileRT - returns true if instrumentation profile is on.
Definition: ToolChain.cpp:1059
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
Definition: ToolChain.cpp:115
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args)
Returns true if gcov instrumentation (-fprofile-arcs or –coverage) is on.
Definition: ToolChain.cpp:1074
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...
Definition: ToolChain.cpp:1232
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.
Definition: ToolChain.cpp:1177
const XRayArgs getXRayArgs(const llvm::opt::ArgList &) const
Definition: ToolChain.cpp:410
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...
Definition: ToolChain.cpp:1493
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
Definition: ToolChain.cpp:527
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
Definition: ToolChain.cpp:404
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1380
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.
Definition: ToolChain.cpp:1301
virtual Tool * getTool(Action::ActionClass AC) const
Definition: ToolChain.cpp:633
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1614
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
Apple specific MachO extensions.
Definition: Darwin.h:300
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:2839
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:3784
llvm::SmallString< 128 > GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const
Definition: Darwin.cpp:2617
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:2630
LazyDetector< RocmInstallationDetector > RocmInstallation
Definition: Darwin.h:330
LazyDetector< SYCLInstallationDetector > SYCLInstallation
Definition: Darwin.h:331
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:2730
LazyDetector< CudaInstallationDetector > CudaInstallation
}
Definition: Darwin.h:329
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 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: Darwin.cpp:2679
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:2886
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
unsigned GetDefaultDwarfVersion() const override
Definition: Darwin.cpp:1297
Darwin - The base Darwin tool chain.
Definition: Darwin.h:344
VersionTuple TargetVersion
The native OS version we are targeting.
Definition: Darwin.h:372
void addPlatformVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition: Darwin.cpp:3552
bool TargetInitialized
Whether the information on the target has been initialized.
Definition: Darwin.h:351
bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const
Definition: Darwin.h:544
bool SupportsEmbeddedBitcode() const override
SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
Definition: Darwin.cpp:3458
void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Add any profiling runtime libraries that are needed.
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:3748
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:3233
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:3741
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition: Darwin.cpp:3444
std::optional< DarwinSDKInfo > SDKInfo
The information about the darwin SDK that was used.
Definition: Darwin.h:377
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:3157
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:554
bool isTargetInitialized() const
Definition: Darwin.h:533
bool isTargetAppleSiliconMac() const
Definition: Darwin.h:528
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:3370
bool isTargetTvOSSimulator() const
Definition: Darwin.h:484
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:3314
void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, unsigned Major, unsigned Minor, unsigned Micro, VersionTuple NativeTargetVersion) const
Definition: Darwin.h:426
bool isTargetMacCatalyst() const
Definition: Darwin.h:514
CXXStdlibType GetDefaultCXXStdlibType() const override
Definition: Darwin.cpp:976
bool isTargetWatchOSSimulator() const
Definition: Darwin.h:499
DarwinPlatformKind TargetPlatform
Definition: Darwin.h:368
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:3479
void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition: Darwin.cpp:3718
bool isTargetWatchOSBased() const
Definition: Darwin.h:504
std::optional< llvm::Triple > TargetVariantTriple
The target variant triple that was specified (if any).
Definition: Darwin.h:380
VersionTuple getTripleTargetVersion() const
The version of the OS that's used by the OS specified in the target triple.
Definition: Darwin.h:539
bool isAlignedAllocationUnavailable() const
Return true if c++17 aligned allocation/deallocation functions are not implemented in the c++ standar...
Definition: Darwin.cpp:3080
bool isTargetIOSSimulator() const
Definition: Darwin.h:458
DarwinEnvironmentKind TargetEnvironment
Definition: Darwin.h:369
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:205
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
Definition: Darwin.cpp:3465
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
Definition: Darwin.cpp:3469
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition: Darwin.h:285
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:3184
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:3417
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:3438
bool SupportsProfiling() const override
SupportsProfiling - Does this tool chain support -pg.
Definition: Darwin.cpp:3474
RuntimeLinkOptions
Options to control how a runtime library is linked.
Definition: Darwin.h:208
@ RLO_IsEmbedded
Use the embedded runtime from the macho_embedded directory.
Definition: Darwin.h:213
@ RLO_AddRPath
Emit rpaths for @executable_path as well as the resource directory.
Definition: Darwin.h:216
@ RLO_AlwaysLink
Link the library in even if it can't be found in the VFS.
Definition: Darwin.h:210
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:3064
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:3467
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:2918
bool UseDwarfDebugFlags() const override
UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf compile unit information.
Definition: Darwin.cpp:3432
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:571
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
bool willEmitRemarks(const llvm::opt::ArgList &Args)
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.
llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS)
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:60
#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...
Definition: DarwinSDKInfo.h:56
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
Definition: DarwinSDKInfo.h:49
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