clang 22.0.0git
Darwin.cpp
Go to the documentation of this file.
1//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Darwin.h"
10#include "Arch/ARM.h"
13#include "clang/Config/config.h"
16#include "clang/Driver/Driver.h"
19#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Option/ArgList.h"
21#include "llvm/ProfileData/InstrProf.h"
22#include "llvm/ProfileData/MemProf.h"
23#include "llvm/Support/Path.h"
24#include "llvm/Support/Threading.h"
25#include "llvm/Support/VirtualFileSystem.h"
26#include "llvm/TargetParser/TargetParser.h"
27#include "llvm/TargetParser/Triple.h"
28#include <cstdlib> // ::getenv
29
30using namespace clang::driver;
31using namespace clang::driver::tools;
32using namespace clang::driver::toolchains;
33using namespace clang;
34using namespace llvm::opt;
35
37 return VersionTuple(13, 1);
38}
39
40llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
41 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
42 // archs which Darwin doesn't use.
43
44 // The matching this routine does is fairly pointless, since it is neither the
45 // complete architecture list, nor a reasonable subset. The problem is that
46 // historically the driver accepts this and also ties its -march=
47 // handling to the architecture name, so we need to be careful before removing
48 // support for it.
49
50 // This code must be kept in sync with Clang's Darwin specific argument
51 // translation.
52
53 return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
54 .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
55 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
56 llvm::Triple::x86)
57 .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
58 // This is derived from the driver.
59 .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
60 .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
61 .Cases("armv7s", "xscale", llvm::Triple::arm)
62 .Cases("arm64", "arm64e", llvm::Triple::aarch64)
63 .Case("arm64_32", llvm::Triple::aarch64_32)
64 .Case("r600", llvm::Triple::r600)
65 .Case("amdgcn", llvm::Triple::amdgcn)
66 .Case("nvptx", llvm::Triple::nvptx)
67 .Case("nvptx64", llvm::Triple::nvptx64)
68 .Case("amdil", llvm::Triple::amdil)
69 .Case("spir", llvm::Triple::spir)
70 .Default(llvm::Triple::UnknownArch);
71}
72
73void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str,
74 const ArgList &Args) {
75 const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
76 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str);
77 T.setArch(Arch);
78 if (Arch != llvm::Triple::UnknownArch)
79 T.setArchName(Str);
80
81 if (ArchKind == llvm::ARM::ArchKind::ARMV6M ||
82 ArchKind == llvm::ARM::ArchKind::ARMV7M ||
83 ArchKind == llvm::ARM::ArchKind::ARMV7EM) {
84 // Don't reject these -version-min= if we have the appropriate triple.
85 if (T.getOS() == llvm::Triple::IOS)
86 for (Arg *A : Args.filtered(options::OPT_mios_version_min_EQ))
87 A->ignoreTargetSpecific();
88 if (T.getOS() == llvm::Triple::WatchOS)
89 for (Arg *A : Args.filtered(options::OPT_mwatchos_version_min_EQ))
90 A->ignoreTargetSpecific();
91 if (T.getOS() == llvm::Triple::TvOS)
92 for (Arg *A : Args.filtered(options::OPT_mtvos_version_min_EQ))
93 A->ignoreTargetSpecific();
94
95 T.setOS(llvm::Triple::UnknownOS);
96 T.setObjectFormat(llvm::Triple::MachO);
97 }
98}
99
101 const InputInfo &Output,
102 const InputInfoList &Inputs,
103 const ArgList &Args,
104 const char *LinkingOutput) const {
105 const llvm::Triple &T(getToolChain().getTriple());
106
107 ArgStringList CmdArgs;
108
109 assert(Inputs.size() == 1 && "Unexpected number of inputs.");
110 const InputInfo &Input = Inputs[0];
111
112 // Determine the original source input.
113 const Action *SourceAction = &JA;
114 while (SourceAction->getKind() != Action::InputClass) {
115 assert(!SourceAction->getInputs().empty() && "unexpected root action!");
116 SourceAction = SourceAction->getInputs()[0];
117 }
118
119 // If -fno-integrated-as is used add -Q to the darwin assembler driver to make
120 // sure it runs its system assembler not clang's integrated assembler.
121 // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as.
122 // FIXME: at run-time detect assembler capabilities or rely on version
123 // information forwarded by -target-assembler-version.
124 if (Args.hasArg(options::OPT_fno_integrated_as)) {
125 if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
126 CmdArgs.push_back("-Q");
127 }
128
129 // Forward -g, assuming we are dealing with an actual assembly file.
130 if (SourceAction->getType() == types::TY_Asm ||
131 SourceAction->getType() == types::TY_PP_Asm) {
132 if (Args.hasArg(options::OPT_gstabs))
133 CmdArgs.push_back("--gstabs");
134 else if (Args.hasArg(options::OPT_g_Group))
135 CmdArgs.push_back("-g");
136 }
137
138 // Derived from asm spec.
139 AddMachOArch(Args, CmdArgs);
140
141 // Use -force_cpusubtype_ALL on x86 by default.
142 if (T.isX86() || Args.hasArg(options::OPT_force__cpusubtype__ALL))
143 CmdArgs.push_back("-force_cpusubtype_ALL");
144
145 if (getToolChain().getArch() != llvm::Triple::x86_64 &&
146 (((Args.hasArg(options::OPT_mkernel) ||
147 Args.hasArg(options::OPT_fapple_kext)) &&
148 getMachOToolChain().isKernelStatic()) ||
149 Args.hasArg(options::OPT_static)))
150 CmdArgs.push_back("-static");
151
152 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
153
154 assert(Output.isFilename() && "Unexpected lipo output.");
155 CmdArgs.push_back("-o");
156 CmdArgs.push_back(Output.getFilename());
157
158 assert(Input.isFilename() && "Invalid input.");
159 CmdArgs.push_back(Input.getFilename());
160
161 // asm_final spec is empty.
162
163 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
164 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
165 Exec, CmdArgs, Inputs, Output));
166}
167
168void darwin::MachOTool::anchor() {}
169
170void darwin::MachOTool::AddMachOArch(const ArgList &Args,
171 ArgStringList &CmdArgs) const {
172 StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
173
174 // Derived from darwin_arch spec.
175 CmdArgs.push_back("-arch");
176 CmdArgs.push_back(Args.MakeArgString(ArchName));
177
178 // FIXME: Is this needed anymore?
179 if (ArchName == "arm")
180 CmdArgs.push_back("-force_cpusubtype_ALL");
181}
182
183bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {
184 // We only need to generate a temp path for LTO if we aren't compiling object
185 // files. When compiling source files, we run 'dsymutil' after linking. We
186 // don't run 'dsymutil' when compiling object files.
187 for (const auto &Input : Inputs)
188 if (Input.getType() != types::TY_Object)
189 return true;
190
191 return false;
192}
193
194/// Pass -no_deduplicate to ld64 under certain conditions:
195///
196/// - Either -O0 or -O1 is explicitly specified
197/// - No -O option is specified *and* this is a compile+link (implicit -O0)
198///
199/// Also do *not* add -no_deduplicate when no -O option is specified and this
200/// is just a link (we can't imply -O0)
201static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
202 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
203 if (A->getOption().matches(options::OPT_O0))
204 return true;
205 if (A->getOption().matches(options::OPT_O))
206 return llvm::StringSwitch<bool>(A->getValue())
207 .Case("1", true)
208 .Default(false);
209 return false; // OPT_Ofast & OPT_O4
210 }
211
212 if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.
213 return true;
214 return false;
215}
216
217void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
218 ArgStringList &CmdArgs,
219 const InputInfoList &Inputs,
220 VersionTuple Version, bool LinkerIsLLD,
221 bool UsePlatformVersion) const {
222 const Driver &D = getToolChain().getDriver();
223 const toolchains::MachO &MachOTC = getMachOToolChain();
224
225 // Newer linkers support -demangle. Pass it if supported and not disabled by
226 // the user.
227 if ((Version >= VersionTuple(100) || LinkerIsLLD) &&
228 !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
229 CmdArgs.push_back("-demangle");
230
231 if (Args.hasArg(options::OPT_rdynamic) &&
232 (Version >= VersionTuple(137) || LinkerIsLLD))
233 CmdArgs.push_back("-export_dynamic");
234
235 // If we are using App Extension restrictions, pass a flag to the linker
236 // telling it that the compiled code has been audited.
237 if (Args.hasFlag(options::OPT_fapplication_extension,
238 options::OPT_fno_application_extension, false))
239 CmdArgs.push_back("-application_extension");
240
241 if (D.isUsingLTO() && (Version >= VersionTuple(116) || LinkerIsLLD) &&
242 NeedsTempPath(Inputs)) {
243 std::string TmpPathName;
244 if (D.getLTOMode() == LTOK_Full) {
245 // If we are using full LTO, then automatically create a temporary file
246 // path for the linker to use, so that it's lifetime will extend past a
247 // possible dsymutil step.
248 TmpPathName =
249 D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object));
250 } else if (D.getLTOMode() == LTOK_Thin)
251 // If we are using thin LTO, then create a directory instead.
252 TmpPathName = D.GetTemporaryDirectory("thinlto");
253
254 if (!TmpPathName.empty()) {
255 auto *TmpPath = C.getArgs().MakeArgString(TmpPathName);
256 C.addTempFile(TmpPath);
257 CmdArgs.push_back("-object_path_lto");
258 CmdArgs.push_back(TmpPath);
259 }
260 }
261
262 // Use -lto_library option to specify the libLTO.dylib path. Try to find
263 // it in clang installed libraries. ld64 will only look at this argument
264 // when it actually uses LTO, so libLTO.dylib only needs to exist at link
265 // time if ld64 decides that it needs to use LTO.
266 // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
267 // next to it. That's ok since ld64 using a libLTO.dylib not matching the
268 // clang version won't work anyways.
269 // lld is built at the same revision as clang and statically links in
270 // LLVM libraries, so it doesn't need libLTO.dylib.
271 if (Version >= VersionTuple(133) && !LinkerIsLLD) {
272 // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
273 StringRef P = llvm::sys::path::parent_path(D.Dir);
274 SmallString<128> LibLTOPath(P);
275 llvm::sys::path::append(LibLTOPath, "lib");
276 llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
277 CmdArgs.push_back("-lto_library");
278 CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
279 }
280
281 // ld64 version 262 and above runs the deduplicate pass by default.
282 // FIXME: lld doesn't dedup by default. Should we pass `--icf=safe`
283 // if `!shouldLinkerNotDedup()` if LinkerIsLLD here?
284 if (Version >= VersionTuple(262) &&
285 shouldLinkerNotDedup(C.getJobs().empty(), Args))
286 CmdArgs.push_back("-no_deduplicate");
287
288 // Derived from the "link" spec.
289 Args.AddAllArgs(CmdArgs, options::OPT_static);
290 if (!Args.hasArg(options::OPT_static))
291 CmdArgs.push_back("-dynamic");
292 if (Args.hasArg(options::OPT_fgnu_runtime)) {
293 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
294 // here. How do we wish to handle such things?
295 }
296
297 if (!Args.hasArg(options::OPT_dynamiclib)) {
298 AddMachOArch(Args, CmdArgs);
299 // FIXME: Why do this only on this path?
300 Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
301
302 Args.AddLastArg(CmdArgs, options::OPT_bundle);
303 Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
304 Args.AddAllArgs(CmdArgs, options::OPT_client__name);
305
306 Arg *A;
307 if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
308 (A = Args.getLastArg(options::OPT_current__version)) ||
309 (A = Args.getLastArg(options::OPT_install__name)))
310 D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
311 << "-dynamiclib";
312
313 Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
314 Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
315 Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
316 } else {
317 CmdArgs.push_back("-dylib");
318
319 Arg *A;
320 if ((A = Args.getLastArg(options::OPT_bundle)) ||
321 (A = Args.getLastArg(options::OPT_bundle__loader)) ||
322 (A = Args.getLastArg(options::OPT_client__name)) ||
323 (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
324 (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
325 (A = Args.getLastArg(options::OPT_private__bundle)))
326 D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
327 << "-dynamiclib";
328
329 Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
330 "-dylib_compatibility_version");
331 Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
332 "-dylib_current_version");
333
334 AddMachOArch(Args, CmdArgs);
335
336 Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
337 "-dylib_install_name");
338 }
339
340 Args.AddLastArg(CmdArgs, options::OPT_all__load);
341 Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
342 Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
343 if (MachOTC.isTargetIOSBased())
344 Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
345 Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
346 Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
347 Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
348 Args.AddLastArg(CmdArgs, options::OPT_dynamic);
349 Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
350 Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
351 Args.AddAllArgs(CmdArgs, options::OPT_force__load);
352 Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
353 Args.AddAllArgs(CmdArgs, options::OPT_image__base);
354 Args.AddAllArgs(CmdArgs, options::OPT_init);
355
356 // Add the deployment target.
357 if (Version >= VersionTuple(520) || LinkerIsLLD || UsePlatformVersion)
358 MachOTC.addPlatformVersionArgs(Args, CmdArgs);
359 else
360 MachOTC.addMinVersionArgs(Args, CmdArgs);
361
362 Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
363 Args.AddLastArg(CmdArgs, options::OPT_multi__module);
364 Args.AddLastArg(CmdArgs, options::OPT_single__module);
365 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
366 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
367
368 if (const Arg *A =
369 Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
370 options::OPT_fno_pie, options::OPT_fno_PIE)) {
371 if (A->getOption().matches(options::OPT_fpie) ||
372 A->getOption().matches(options::OPT_fPIE))
373 CmdArgs.push_back("-pie");
374 else
375 CmdArgs.push_back("-no_pie");
376 }
377
378 // for embed-bitcode, use -bitcode_bundle in linker command
379 if (C.getDriver().embedBitcodeEnabled()) {
380 // Check if the toolchain supports bitcode build flow.
381 if (MachOTC.SupportsEmbeddedBitcode()) {
382 CmdArgs.push_back("-bitcode_bundle");
383 // FIXME: Pass this if LinkerIsLLD too, once it implements this flag.
384 if (C.getDriver().embedBitcodeMarkerOnly() &&
385 Version >= VersionTuple(278)) {
386 CmdArgs.push_back("-bitcode_process_mode");
387 CmdArgs.push_back("marker");
388 }
389 } else
390 D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
391 }
392
393 // If GlobalISel is enabled, pass it through to LLVM.
394 if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
395 options::OPT_fno_global_isel)) {
396 if (A->getOption().matches(options::OPT_fglobal_isel)) {
397 CmdArgs.push_back("-mllvm");
398 CmdArgs.push_back("-global-isel");
399 // Disable abort and fall back to SDAG silently.
400 CmdArgs.push_back("-mllvm");
401 CmdArgs.push_back("-global-isel-abort=0");
402 }
403 }
404
405 if (Args.hasArg(options::OPT_mkernel) ||
406 Args.hasArg(options::OPT_fapple_kext) ||
407 Args.hasArg(options::OPT_ffreestanding)) {
408 CmdArgs.push_back("-mllvm");
409 CmdArgs.push_back("-disable-atexit-based-global-dtor-lowering");
410 }
411
412 Args.AddLastArg(CmdArgs, options::OPT_prebind);
413 Args.AddLastArg(CmdArgs, options::OPT_noprebind);
414 Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
415 Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
416 Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
417 Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
418 Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
419 Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
420 Args.AddAllArgs(CmdArgs, options::OPT_segprot);
421 Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
422 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
423 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
424 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
425 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
426 Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
427 Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
428
429 // Give --sysroot= preference, over the Apple specific behavior to also use
430 // --isysroot as the syslibroot.
431 // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we
432 // prioritise command line arguments over configuration of `DEFAULT_SYSROOT`.
433 if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) {
434 CmdArgs.push_back("-syslibroot");
435 CmdArgs.push_back(A->getValue());
436 } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
437 CmdArgs.push_back("-syslibroot");
438 CmdArgs.push_back(A->getValue());
439 } else if (StringRef sysroot = C.getSysRoot(); sysroot != "") {
440 CmdArgs.push_back("-syslibroot");
441 CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
442 }
443
444 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
445 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
446 Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
447 Args.AddAllArgs(CmdArgs, options::OPT_undefined);
448 Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
449 Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
450 Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
451 Args.AddAllArgs(CmdArgs, options::OPT_y);
452 Args.AddLastArg(CmdArgs, options::OPT_w);
453 Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
454 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
455 Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
456 Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
457 Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
458 Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
459 Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
460 Args.AddLastArg(CmdArgs, options::OPT_why_load);
461 Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
462 Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
463 Args.AddLastArg(CmdArgs, options::OPT_dylinker);
464 Args.AddLastArg(CmdArgs, options::OPT_Mach);
465
466 if (LinkerIsLLD) {
467 if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {
468 SmallString<128> Path(CSPGOGenerateArg->getNumValues() == 0
469 ? ""
470 : CSPGOGenerateArg->getValue());
471 llvm::sys::path::append(Path, "default_%m.profraw");
472 CmdArgs.push_back("--cs-profile-generate");
473 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));
474 } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {
475 SmallString<128> Path(
476 ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
477 if (Path.empty() || llvm::sys::fs::is_directory(Path))
478 llvm::sys::path::append(Path, "default.profdata");
479 CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));
480 }
481
482 auto *CodeGenDataGenArg =
483 Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
484 if (CodeGenDataGenArg)
485 CmdArgs.push_back(
486 Args.MakeArgString(Twine("--codegen-data-generate-path=") +
487 CodeGenDataGenArg->getValue()));
488 }
489}
490
491/// Determine whether we are linking the ObjC runtime.
492static bool isObjCRuntimeLinked(const ArgList &Args) {
493 if (isObjCAutoRefCount(Args)) {
494 Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
495 return true;
496 }
497 return Args.hasArg(options::OPT_fobjc_link_runtime);
498}
499
500static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
501 const llvm::Triple &Triple) {
502 // When enabling remarks, we need to error if:
503 // * The remark file is specified but we're targeting multiple architectures,
504 // which means more than one remark file is being generated.
506 Args.getAllArgValues(options::OPT_arch).size() > 1;
507 bool hasExplicitOutputFile =
508 Args.getLastArg(options::OPT_foptimization_record_file_EQ);
509 if (hasMultipleInvocations && hasExplicitOutputFile) {
510 D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
511 << "-foptimization-record-file";
512 return false;
513 }
514 return true;
515}
516
517static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
518 const llvm::Triple &Triple,
519 const InputInfo &Output, const JobAction &JA) {
520 StringRef Format = "yaml";
521 if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
522 Format = A->getValue();
523
524 CmdArgs.push_back("-mllvm");
525 CmdArgs.push_back("-lto-pass-remarks-output");
526 CmdArgs.push_back("-mllvm");
527
528 const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
529 if (A) {
530 CmdArgs.push_back(A->getValue());
531 } else {
532 assert(Output.isFilename() && "Unexpected ld output.");
534 F = Output.getFilename();
535 F += ".opt.";
536 F += Format;
537
538 CmdArgs.push_back(Args.MakeArgString(F));
539 }
540
541 if (const Arg *A =
542 Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
543 CmdArgs.push_back("-mllvm");
544 std::string Passes =
545 std::string("-lto-pass-remarks-filter=") + A->getValue();
546 CmdArgs.push_back(Args.MakeArgString(Passes));
547 }
548
549 if (!Format.empty()) {
550 CmdArgs.push_back("-mllvm");
551 Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format;
552 CmdArgs.push_back(Args.MakeArgString(FormatArg));
553 }
554
555 if (getLastProfileUseArg(Args)) {
556 CmdArgs.push_back("-mllvm");
557 CmdArgs.push_back("-lto-pass-remarks-with-hotness");
558
559 if (const Arg *A =
560 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
561 CmdArgs.push_back("-mllvm");
562 std::string Opt =
563 std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue();
564 CmdArgs.push_back(Args.MakeArgString(Opt));
565 }
566 }
567}
568
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 // Since darwin::Linker::ConstructJob already adds -lc++ for clang++
1614 // by default if ShouldLinkCXXStdlib(Args), we only add the option if
1615 // !ShouldLinkCXXStdlib(Args). This avoids duplicate library errors
1616 // on Darwin.
1617 if (!ShouldLinkCXXStdlib(Args))
1618 AddCXXStdlibLibArgs(Args, CmdArgs);
1619 }
1620 if (Sanitize.needsStatsRt()) {
1621 AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
1622 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
1623 }
1624 }
1625
1626 if (Sanitize.needsMemProfRt())
1627 if (hasExportSymbolDirective(Args))
1629 CmdArgs,
1630 llvm::memprof::getMemprofOptionsSymbolDarwinLinkageName().data());
1631
1632 const XRayArgs &XRay = getXRayArgs(Args);
1633 if (XRay.needsXRayRt()) {
1634 AddLinkRuntimeLib(Args, CmdArgs, "xray");
1635 AddLinkRuntimeLib(Args, CmdArgs, "xray-basic");
1636 AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr");
1637 }
1638
1639 if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) {
1640 CmdArgs.push_back("-framework");
1641 CmdArgs.push_back("DriverKit");
1642 }
1643
1644 // Otherwise link libSystem, then the dynamic runtime library, and finally any
1645 // target specific static runtime library.
1646 if (!isTargetDriverKit())
1647 CmdArgs.push_back("-lSystem");
1648
1649 // Select the dynamic runtime library and the target specific static library.
1650 // Some old Darwin versions put builtins, libunwind, and some other stuff in
1651 // libgcc_s.1.dylib. MacOS X 10.6 and iOS 5 moved those functions to
1652 // libSystem, and made libgcc_s.1.dylib a stub. We never link libgcc_s when
1653 // building for aarch64 or iOS simulator, since libgcc_s was made obsolete
1654 // before either existed.
1655 if (getTriple().getArch() != llvm::Triple::aarch64 &&
1659 CmdArgs.push_back("-lgcc_s.1");
1660 AddLinkRuntimeLib(Args, CmdArgs, "builtins");
1661}
1662
1663/// Returns the most appropriate macOS target version for the current process.
1664///
1665/// If the macOS SDK version is the same or earlier than the system version,
1666/// then the SDK version is returned. Otherwise the system version is returned.
1667static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
1668 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
1669 if (!SystemTriple.isMacOSX())
1670 return std::string(MacOSSDKVersion);
1671 VersionTuple SystemVersion;
1672 SystemTriple.getMacOSXVersion(SystemVersion);
1673
1674 unsigned Major, Minor, Micro;
1675 bool HadExtra;
1676 if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
1677 HadExtra))
1678 return std::string(MacOSSDKVersion);
1679 VersionTuple SDKVersion(Major, Minor, Micro);
1680
1681 if (SDKVersion > SystemVersion)
1682 return SystemVersion.getAsString();
1683 return std::string(MacOSSDKVersion);
1684}
1685
1686namespace {
1687
1688/// The Darwin OS and version that was selected or inferred from arguments or
1689/// environment.
1690struct DarwinPlatform {
1691 enum SourceKind {
1692 /// The OS was specified using the -target argument.
1693 TargetArg,
1694 /// The OS was specified using the -mtargetos= argument.
1695 MTargetOSArg,
1696 /// The OS was specified using the -m<os>-version-min argument.
1697 OSVersionArg,
1698 /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
1699 DeploymentTargetEnv,
1700 /// The OS was inferred from the SDK.
1701 InferredFromSDK,
1702 /// The OS was inferred from the -arch.
1703 InferredFromArch
1704 };
1705
1706 using DarwinPlatformKind = Darwin::DarwinPlatformKind;
1707 using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind;
1708
1709 DarwinPlatformKind getPlatform() const { return Platform; }
1710
1711 DarwinEnvironmentKind getEnvironment() const { return Environment; }
1712
1713 void setEnvironment(DarwinEnvironmentKind Kind) {
1714 Environment = Kind;
1715 InferSimulatorFromArch = false;
1716 }
1717
1718 const VersionTuple getOSVersion() const {
1719 return UnderlyingOSVersion.value_or(VersionTuple());
1720 }
1721
1722 VersionTuple takeOSVersion() {
1723 assert(UnderlyingOSVersion.has_value() &&
1724 "attempting to get an unset OS version");
1725 VersionTuple Result = *UnderlyingOSVersion;
1726 UnderlyingOSVersion.reset();
1727 return Result;
1728 }
1729 bool isValidOSVersion() const {
1730 return llvm::Triple::isValidVersionForOS(getOSFromPlatform(Platform),
1731 getOSVersion());
1732 }
1733
1734 VersionTuple getCanonicalOSVersion() const {
1735 return llvm::Triple::getCanonicalVersionForOS(
1736 getOSFromPlatform(Platform), getOSVersion(), /*IsInValidRange=*/true);
1737 }
1738
1739 void setOSVersion(const VersionTuple &Version) {
1740 UnderlyingOSVersion = Version;
1741 }
1742
1743 bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); }
1744
1745 VersionTuple getZipperedOSVersion() const {
1746 assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
1747 "zippered target version is specified only for Mac Catalyst");
1748 return ZipperedOSVersion;
1749 }
1750
1751 /// Returns true if the target OS was explicitly specified.
1752 bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
1753
1754 /// Returns true if the simulator environment can be inferred from the arch.
1755 bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }
1756
1757 const std::optional<llvm::Triple> &getTargetVariantTriple() const {
1758 return TargetVariantTriple;
1759 }
1760
1761 /// Adds the -m<os>-version-min argument to the compiler invocation.
1762 void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
1763 auto &[Arg, OSVersionStr] = Arguments;
1764 if (Arg)
1765 return;
1766 assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1767 "Invalid kind");
1768 options::ID Opt;
1769 switch (Platform) {
1770 case DarwinPlatformKind::MacOS:
1771 Opt = options::OPT_mmacos_version_min_EQ;
1772 break;
1773 case DarwinPlatformKind::IPhoneOS:
1774 Opt = options::OPT_mios_version_min_EQ;
1775 break;
1776 case DarwinPlatformKind::TvOS:
1777 Opt = options::OPT_mtvos_version_min_EQ;
1778 break;
1779 case DarwinPlatformKind::WatchOS:
1780 Opt = options::OPT_mwatchos_version_min_EQ;
1781 break;
1782 case DarwinPlatformKind::XROS:
1783 // xrOS always explicitly provides a version in the triple.
1784 return;
1785 case DarwinPlatformKind::DriverKit:
1786 // DriverKit always explicitly provides a version in the triple.
1787 return;
1788 }
1789 Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);
1790 Args.append(Arg);
1791 }
1792
1793 /// Returns the OS version with the argument / environment variable that
1794 /// specified it.
1795 std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
1796 auto &[Arg, OSVersionStr] = Arguments;
1797 switch (Kind) {
1798 case TargetArg:
1799 case MTargetOSArg:
1800 case OSVersionArg:
1801 assert(Arg && "OS version argument not yet inferred");
1802 return Arg->getAsString(Args);
1803 case DeploymentTargetEnv:
1804 return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
1805 case InferredFromSDK:
1806 case InferredFromArch:
1807 llvm_unreachable("Cannot print arguments for inferred OS version");
1808 }
1809 llvm_unreachable("Unsupported Darwin Source Kind");
1810 }
1811
1812 // Returns the inferred source of how the OS version was resolved.
1813 std::string getInferredSource() {
1814 assert(!isExplicitlySpecified() && "OS version was not inferred");
1815 return InferredSource.str();
1816 }
1817
1818 void setEnvironment(llvm::Triple::EnvironmentType EnvType,
1819 const VersionTuple &OSVersion,
1820 const std::optional<DarwinSDKInfo> &SDKInfo) {
1821 switch (EnvType) {
1822 case llvm::Triple::Simulator:
1823 Environment = DarwinEnvironmentKind::Simulator;
1824 break;
1825 case llvm::Triple::MacABI: {
1826 Environment = DarwinEnvironmentKind::MacCatalyst;
1827 // The minimum native macOS target for MacCatalyst is macOS 10.15.
1828 ZipperedOSVersion = VersionTuple(10, 15);
1829 if (hasOSVersion() && SDKInfo) {
1830 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
1832 if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
1833 OSVersion, ZipperedOSVersion, std::nullopt)) {
1834 ZipperedOSVersion = *MacOSVersion;
1835 }
1836 }
1837 }
1838 // In a zippered build, we could be building for a macOS target that's
1839 // lower than the version that's implied by the OS version. In that case
1840 // we need to use the minimum version as the native target version.
1841 if (TargetVariantTriple) {
1842 auto TargetVariantVersion = TargetVariantTriple->getOSVersion();
1843 if (TargetVariantVersion.getMajor()) {
1844 if (TargetVariantVersion < ZipperedOSVersion)
1845 ZipperedOSVersion = TargetVariantVersion;
1846 }
1847 }
1848 break;
1849 }
1850 default:
1851 break;
1852 }
1853 }
1854
1855 static DarwinPlatform
1856 createFromTarget(const llvm::Triple &TT, Arg *A,
1857 std::optional<llvm::Triple> TargetVariantTriple,
1858 const std::optional<DarwinSDKInfo> &SDKInfo) {
1859 DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()),
1860 TT.getOSVersion(), A);
1861 VersionTuple OsVersion = TT.getOSVersion();
1862 Result.TargetVariantTriple = TargetVariantTriple;
1863 Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);
1864 return Result;
1865 }
1866 static DarwinPlatform
1867 createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
1868 llvm::Triple::EnvironmentType Environment, Arg *A,
1869 const std::optional<DarwinSDKInfo> &SDKInfo) {
1870 DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), OSVersion, A);
1871 Result.InferSimulatorFromArch = false;
1872 Result.setEnvironment(Environment, OSVersion, SDKInfo);
1873 return Result;
1874 }
1875 static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A,
1876 bool IsSimulator) {
1877 DarwinPlatform Result{OSVersionArg, Platform,
1878 getVersionFromString(A->getValue()), A};
1879 if (IsSimulator)
1880 Result.Environment = DarwinEnvironmentKind::Simulator;
1881 return Result;
1882 }
1883 static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,
1884 StringRef EnvVarName,
1885 StringRef OSVersion) {
1886 DarwinPlatform Result(DeploymentTargetEnv, Platform,
1887 getVersionFromString(OSVersion));
1888 Result.EnvVarName = EnvVarName;
1889 return Result;
1890 }
1891 static DarwinPlatform createFromSDK(StringRef SDKRoot,
1892 DarwinPlatformKind Platform,
1893 StringRef Value,
1894 bool IsSimulator = false) {
1895 DarwinPlatform Result(InferredFromSDK, Platform,
1896 getVersionFromString(Value));
1897 if (IsSimulator)
1898 Result.Environment = DarwinEnvironmentKind::Simulator;
1899 Result.InferSimulatorFromArch = false;
1900 Result.InferredSource = SDKRoot;
1901 return Result;
1902 }
1903 static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,
1904 VersionTuple Version) {
1905 auto Result =
1906 DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
1907 Result.InferredSource = Arch;
1908 return Result;
1909 }
1910
1911 /// Constructs an inferred SDKInfo value based on the version inferred from
1912 /// the SDK path itself. Only works for values that were created by inferring
1913 /// the platform from the SDKPath.
1914 DarwinSDKInfo inferSDKInfo() {
1915 assert(Kind == InferredFromSDK && "can infer SDK info only");
1916 return DarwinSDKInfo(getOSVersion(),
1917 /*MaximumDeploymentTarget=*/
1918 VersionTuple(getOSVersion().getMajor(), 0, 99),
1919 getOSFromPlatform(Platform));
1920 }
1921
1922private:
1923 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
1924 : Kind(Kind), Platform(Platform),
1925 Arguments({Argument, VersionTuple().getAsString()}) {}
1926 DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,
1927 VersionTuple Value, Arg *Argument = nullptr)
1928 : Kind(Kind), Platform(Platform),
1929 Arguments({Argument, Value.getAsString()}) {
1930 if (!Value.empty())
1931 UnderlyingOSVersion = Value;
1932 }
1933
1934 static VersionTuple getVersionFromString(const StringRef Input) {
1935 llvm::VersionTuple Version;
1936 bool IsValid = !Version.tryParse(Input);
1937 assert(IsValid && "unable to convert input version to version tuple");
1938 (void)IsValid;
1939 return Version;
1940 }
1941
1942 static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {
1943 switch (OS) {
1944 case llvm::Triple::Darwin:
1945 case llvm::Triple::MacOSX:
1946 return DarwinPlatformKind::MacOS;
1947 case llvm::Triple::IOS:
1948 return DarwinPlatformKind::IPhoneOS;
1949 case llvm::Triple::TvOS:
1950 return DarwinPlatformKind::TvOS;
1951 case llvm::Triple::WatchOS:
1952 return DarwinPlatformKind::WatchOS;
1953 case llvm::Triple::XROS:
1954 return DarwinPlatformKind::XROS;
1955 case llvm::Triple::DriverKit:
1956 return DarwinPlatformKind::DriverKit;
1957 default:
1958 llvm_unreachable("Unable to infer Darwin variant");
1959 }
1960 }
1961
1962 static llvm::Triple::OSType getOSFromPlatform(DarwinPlatformKind Platform) {
1963 switch (Platform) {
1964 case DarwinPlatformKind::MacOS:
1965 return llvm::Triple::MacOSX;
1966 case DarwinPlatformKind::IPhoneOS:
1967 return llvm::Triple::IOS;
1968 case DarwinPlatformKind::TvOS:
1969 return llvm::Triple::TvOS;
1970 case DarwinPlatformKind::WatchOS:
1971 return llvm::Triple::WatchOS;
1972 case DarwinPlatformKind::DriverKit:
1973 return llvm::Triple::DriverKit;
1974 case DarwinPlatformKind::XROS:
1975 return llvm::Triple::XROS;
1976 }
1977 llvm_unreachable("Unknown DarwinPlatformKind enum");
1978 }
1979
1980 SourceKind Kind;
1981 DarwinPlatformKind Platform;
1982 DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
1983 // When compiling for a zippered target, this means both target &
1984 // target variant is set on the command line, ZipperedOSVersion holds the
1985 // OSVersion tied to the main target value.
1986 VersionTuple ZipperedOSVersion;
1987 // We allow multiple ways to set or default the OS
1988 // version used for compilation. When set, UnderlyingOSVersion represents
1989 // the intended version to match the platform information computed from
1990 // arguments.
1991 std::optional<VersionTuple> UnderlyingOSVersion;
1992 bool InferSimulatorFromArch = true;
1993 std::pair<Arg *, std::string> Arguments;
1994 StringRef EnvVarName;
1995 // If the DarwinPlatform information is derived from an inferred source, this
1996 // captures what that source input was for error reporting.
1997 StringRef InferredSource;
1998 // When compiling for a zippered target, this value represents the target
1999 // triple encoded in the target variant.
2000 std::optional<llvm::Triple> TargetVariantTriple;
2001};
2002
2003/// Returns the deployment target that's specified using the -m<os>-version-min
2004/// argument.
2005std::optional<DarwinPlatform>
2006getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
2007 const Driver &TheDriver) {
2008 Arg *macOSVersion = Args.getLastArg(options::OPT_mmacos_version_min_EQ);
2009 Arg *iOSVersion = Args.getLastArg(options::OPT_mios_version_min_EQ,
2010 options::OPT_mios_simulator_version_min_EQ);
2011 Arg *TvOSVersion =
2012 Args.getLastArg(options::OPT_mtvos_version_min_EQ,
2013 options::OPT_mtvos_simulator_version_min_EQ);
2014 Arg *WatchOSVersion =
2015 Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
2016 options::OPT_mwatchos_simulator_version_min_EQ);
2017
2018 auto GetDarwinPlatform =
2019 [&](DarwinPlatform::DarwinPlatformKind Platform, Arg *VersionArg,
2020 bool IsSimulator) -> std::optional<DarwinPlatform> {
2021 if (StringRef(VersionArg->getValue()).empty()) {
2022 TheDriver.Diag(diag::err_drv_missing_version_number)
2023 << VersionArg->getAsString(Args);
2024 return std::nullopt;
2025 }
2026 return DarwinPlatform::createOSVersionArg(Platform, VersionArg,
2027 /*IsSimulator=*/IsSimulator);
2028 };
2029
2030 if (macOSVersion) {
2031 if (iOSVersion || TvOSVersion || WatchOSVersion) {
2032 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2033 << macOSVersion->getAsString(Args)
2034 << (iOSVersion ? iOSVersion
2035 : TvOSVersion ? TvOSVersion : WatchOSVersion)
2036 ->getAsString(Args);
2037 }
2038 return GetDarwinPlatform(Darwin::MacOS, macOSVersion,
2039 /*IsSimulator=*/false);
2040
2041 } else if (iOSVersion) {
2042 if (TvOSVersion || WatchOSVersion) {
2043 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2044 << iOSVersion->getAsString(Args)
2045 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
2046 }
2047 return GetDarwinPlatform(Darwin::IPhoneOS, iOSVersion,
2048 iOSVersion->getOption().getID() ==
2049 options::OPT_mios_simulator_version_min_EQ);
2050 } else if (TvOSVersion) {
2051 if (WatchOSVersion) {
2052 TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
2053 << TvOSVersion->getAsString(Args)
2054 << WatchOSVersion->getAsString(Args);
2055 }
2056 return GetDarwinPlatform(Darwin::TvOS, TvOSVersion,
2057 TvOSVersion->getOption().getID() ==
2058 options::OPT_mtvos_simulator_version_min_EQ);
2059 } else if (WatchOSVersion)
2060 return GetDarwinPlatform(
2061 Darwin::WatchOS, WatchOSVersion,
2062 WatchOSVersion->getOption().getID() ==
2063 options::OPT_mwatchos_simulator_version_min_EQ);
2064 return std::nullopt;
2065}
2066
2067/// Returns the deployment target that's specified using the
2068/// OS_DEPLOYMENT_TARGET environment variable.
2069std::optional<DarwinPlatform>
2070getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
2071 const llvm::Triple &Triple) {
2072 std::string Targets[Darwin::LastDarwinPlatform + 1];
2073 const char *EnvVars[] = {
2074 "MACOSX_DEPLOYMENT_TARGET",
2075 "IPHONEOS_DEPLOYMENT_TARGET",
2076 "TVOS_DEPLOYMENT_TARGET",
2077 "WATCHOS_DEPLOYMENT_TARGET",
2078 "DRIVERKIT_DEPLOYMENT_TARGET",
2079 "XROS_DEPLOYMENT_TARGET"
2080 };
2081 static_assert(std::size(EnvVars) == Darwin::LastDarwinPlatform + 1,
2082 "Missing platform");
2083 for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) {
2084 if (char *Env = ::getenv(I.value()))
2085 Targets[I.index()] = Env;
2086 }
2087
2088 // Allow conflicts among OSX and iOS for historical reasons, but choose the
2089 // default platform.
2090 if (!Targets[Darwin::MacOS].empty() &&
2091 (!Targets[Darwin::IPhoneOS].empty() ||
2092 !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty() ||
2093 !Targets[Darwin::XROS].empty())) {
2094 if (Triple.getArch() == llvm::Triple::arm ||
2095 Triple.getArch() == llvm::Triple::aarch64 ||
2096 Triple.getArch() == llvm::Triple::thumb)
2097 Targets[Darwin::MacOS] = "";
2098 else
2099 Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] =
2100 Targets[Darwin::TvOS] = Targets[Darwin::XROS] = "";
2101 } else {
2102 // Don't allow conflicts in any other platform.
2103 unsigned FirstTarget = std::size(Targets);
2104 for (unsigned I = 0; I != std::size(Targets); ++I) {
2105 if (Targets[I].empty())
2106 continue;
2107 if (FirstTarget == std::size(Targets))
2108 FirstTarget = I;
2109 else
2110 TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
2111 << Targets[FirstTarget] << Targets[I];
2112 }
2113 }
2114
2115 for (const auto &Target : llvm::enumerate(llvm::ArrayRef(Targets))) {
2116 if (!Target.value().empty())
2117 return DarwinPlatform::createDeploymentTargetEnv(
2118 (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],
2119 Target.value());
2120 }
2121 return std::nullopt;
2122}
2123
2124/// Returns the SDK name without the optional prefix that ends with a '.' or an
2125/// empty string otherwise.
2126static StringRef dropSDKNamePrefix(StringRef SDKName) {
2127 size_t PrefixPos = SDKName.find('.');
2128 if (PrefixPos == StringRef::npos)
2129 return "";
2130 return SDKName.substr(PrefixPos + 1);
2131}
2132
2133/// Tries to infer the deployment target from the SDK specified by -isysroot
2134/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
2135/// it's available.
2136std::optional<DarwinPlatform>
2137inferDeploymentTargetFromSDK(DerivedArgList &Args,
2138 const std::optional<DarwinSDKInfo> &SDKInfo) {
2139 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2140 if (!A)
2141 return std::nullopt;
2142 StringRef isysroot = A->getValue();
2143 StringRef SDK = Darwin::getSDKName(isysroot);
2144 if (!SDK.size())
2145 return std::nullopt;
2146
2147 std::string Version;
2148 if (SDKInfo) {
2149 // Get the version from the SDKSettings.json if it's available.
2150 Version = SDKInfo->getVersion().getAsString();
2151 } else {
2152 // Slice the version number out.
2153 // Version number is between the first and the last number.
2154 size_t StartVer = SDK.find_first_of("0123456789");
2155 size_t EndVer = SDK.find_last_of("0123456789");
2156 if (StartVer != StringRef::npos && EndVer > StartVer)
2157 Version = std::string(SDK.slice(StartVer, EndVer + 1));
2158 }
2159 if (Version.empty())
2160 return std::nullopt;
2161
2162 auto CreatePlatformFromSDKName =
2163 [&](StringRef SDK) -> std::optional<DarwinPlatform> {
2164 if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
2165 return DarwinPlatform::createFromSDK(
2166 isysroot, Darwin::IPhoneOS, Version,
2167 /*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
2168 else if (SDK.starts_with("MacOSX"))
2169 return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,
2171 else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
2172 return DarwinPlatform::createFromSDK(
2173 isysroot, Darwin::WatchOS, Version,
2174 /*IsSimulator=*/SDK.starts_with("WatchSimulator"));
2175 else if (SDK.starts_with("AppleTVOS") ||
2176 SDK.starts_with("AppleTVSimulator"))
2177 return DarwinPlatform::createFromSDK(
2178 isysroot, Darwin::TvOS, Version,
2179 /*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
2180 else if (SDK.starts_with("XR"))
2181 return DarwinPlatform::createFromSDK(
2182 isysroot, Darwin::XROS, Version,
2183 /*IsSimulator=*/SDK.contains("Simulator"));
2184 else if (SDK.starts_with("DriverKit"))
2185 return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit,
2186 Version);
2187 return std::nullopt;
2188 };
2189 if (auto Result = CreatePlatformFromSDKName(SDK))
2190 return Result;
2191 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
2192 return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK));
2193}
2194// Compute & get the OS Version when the target triple omitted one.
2195VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,
2196 const llvm::Triple &Triple,
2197 const Driver &TheDriver) {
2198 VersionTuple OsVersion;
2199 llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
2200 switch (OS) {
2201 case llvm::Triple::Darwin:
2202 case llvm::Triple::MacOSX:
2203 // If there is no version specified on triple, and both host and target are
2204 // macos, use the host triple to infer OS version.
2205 if (Triple.isMacOSX() && SystemTriple.isMacOSX() &&
2206 !Triple.getOSMajorVersion())
2207 SystemTriple.getMacOSXVersion(OsVersion);
2208 else if (!Triple.getMacOSXVersion(OsVersion))
2209 TheDriver.Diag(diag::err_drv_invalid_darwin_version)
2210 << Triple.getOSName();
2211 break;
2212 case llvm::Triple::IOS:
2213 if (Triple.isMacCatalystEnvironment() && !Triple.getOSMajorVersion()) {
2214 OsVersion = VersionTuple(13, 1);
2215 } else
2216 OsVersion = Triple.getiOSVersion();
2217 break;
2218 case llvm::Triple::TvOS:
2219 OsVersion = Triple.getOSVersion();
2220 break;
2221 case llvm::Triple::WatchOS:
2222 OsVersion = Triple.getWatchOSVersion();
2223 break;
2224 case llvm::Triple::XROS:
2225 OsVersion = Triple.getOSVersion();
2226 if (!OsVersion.getMajor())
2227 OsVersion = OsVersion.withMajorReplaced(1);
2228 break;
2229 case llvm::Triple::DriverKit:
2230 OsVersion = Triple.getDriverKitVersion();
2231 break;
2232 default:
2233 llvm_unreachable("Unexpected OS type");
2234 break;
2235 }
2236 return OsVersion;
2237}
2238
2239/// Tries to infer the target OS from the -arch.
2240std::optional<DarwinPlatform>
2241inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
2242 const llvm::Triple &Triple,
2243 const Driver &TheDriver) {
2244 llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
2245
2246 StringRef MachOArchName = Toolchain.getMachOArchName(Args);
2247 if (MachOArchName == "arm64" || MachOArchName == "arm64e")
2248 OSTy = llvm::Triple::MacOSX;
2249 else if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
2250 MachOArchName == "armv6")
2251 OSTy = llvm::Triple::IOS;
2252 else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32")
2253 OSTy = llvm::Triple::WatchOS;
2254 else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
2255 MachOArchName != "armv7em")
2256 OSTy = llvm::Triple::MacOSX;
2257 if (OSTy == llvm::Triple::UnknownOS)
2258 return std::nullopt;
2259 return DarwinPlatform::createFromArch(
2260 MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
2261}
2262
2263/// Returns the deployment target that's specified using the -target option.
2264std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2265 DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver,
2266 const std::optional<DarwinSDKInfo> &SDKInfo) {
2267 if (!Args.hasArg(options::OPT_target))
2268 return std::nullopt;
2269 if (Triple.getOS() == llvm::Triple::Darwin ||
2270 Triple.getOS() == llvm::Triple::UnknownOS)
2271 return std::nullopt;
2272 std::optional<llvm::Triple> TargetVariantTriple;
2273 for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
2274 llvm::Triple TVT(A->getValue());
2275 // Find a matching <arch>-<vendor> target variant triple that can be used.
2276 if ((Triple.getArch() == llvm::Triple::aarch64 ||
2277 TVT.getArchName() == Triple.getArchName()) &&
2278 TVT.getArch() == Triple.getArch() &&
2279 TVT.getSubArch() == Triple.getSubArch() &&
2280 TVT.getVendor() == Triple.getVendor()) {
2281 if (TargetVariantTriple)
2282 continue;
2283 A->claim();
2284 // Accept a -target-variant triple when compiling code that may run on
2285 // macOS or Mac Catalyst.
2286 if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS &&
2287 TVT.isMacCatalystEnvironment()) ||
2288 (TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS &&
2289 Triple.isMacCatalystEnvironment())) {
2290 TargetVariantTriple = TVT;
2291 continue;
2292 }
2293 TheDriver.Diag(diag::err_drv_target_variant_invalid)
2294 << A->getSpelling() << A->getValue();
2295 }
2296 }
2297 DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget(
2298 Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
2299 SDKInfo);
2300
2301 return PlatformAndVersion;
2302}
2303
2304/// Returns the deployment target that's specified using the -mtargetos option.
2305std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg(
2306 DerivedArgList &Args, const Driver &TheDriver,
2307 const std::optional<DarwinSDKInfo> &SDKInfo) {
2308 auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
2309 if (!A)
2310 return std::nullopt;
2311 llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
2312 switch (TT.getOS()) {
2313 case llvm::Triple::MacOSX:
2314 case llvm::Triple::IOS:
2315 case llvm::Triple::TvOS:
2316 case llvm::Triple::WatchOS:
2317 case llvm::Triple::XROS:
2318 break;
2319 default:
2320 TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
2321 << TT.getOSName() << A->getAsString(Args);
2322 return std::nullopt;
2323 }
2324
2325 VersionTuple Version = TT.getOSVersion();
2326 if (!Version.getMajor()) {
2327 TheDriver.Diag(diag::err_drv_invalid_version_number)
2328 << A->getAsString(Args);
2329 return std::nullopt;
2330 }
2331 return DarwinPlatform::createFromMTargetOS(TT.getOS(), Version,
2332 TT.getEnvironment(), A, SDKInfo);
2333}
2334
2335std::optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
2336 const ArgList &Args,
2337 const Driver &TheDriver) {
2338 const Arg *A = Args.getLastArg(options::OPT_isysroot);
2339 if (!A)
2340 return std::nullopt;
2341 StringRef isysroot = A->getValue();
2342 auto SDKInfoOrErr = parseDarwinSDKInfo(VFS, isysroot);
2343 if (!SDKInfoOrErr) {
2344 llvm::consumeError(SDKInfoOrErr.takeError());
2345 TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);
2346 return std::nullopt;
2347 }
2348 return *SDKInfoOrErr;
2349}
2350
2351} // namespace
2352
2353void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2354 const OptTable &Opts = getDriver().getOpts();
2355
2356 // Support allowing the SDKROOT environment variable used by xcrun and other
2357 // Xcode tools to define the default sysroot, by making it the default for
2358 // isysroot.
2359 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2360 // Warn if the path does not exist.
2361 if (!getVFS().exists(A->getValue()))
2362 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
2363 } else {
2364 if (char *env = ::getenv("SDKROOT")) {
2365 // We only use this value as the default if it is an absolute path,
2366 // exists, and it is not the root path.
2367 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
2368 StringRef(env) != "/") {
2369 Args.append(Args.MakeSeparateArg(
2370 nullptr, Opts.getOption(options::OPT_isysroot), env));
2371 }
2372 }
2373 }
2374
2375 // Read the SDKSettings.json file for more information, like the SDK version
2376 // that we can pass down to the compiler.
2377 SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
2378
2379 // The OS and the version can be specified using the -target argument.
2380 std::optional<DarwinPlatform> PlatformAndVersion =
2381 getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
2382 if (PlatformAndVersion) {
2383 // Disallow mixing -target and -mtargetos=.
2384 if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
2385 std::string TargetArgStr = PlatformAndVersion->getAsString(Args, Opts);
2386 std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
2387 getDriver().Diag(diag::err_drv_cannot_mix_options)
2388 << TargetArgStr << MTargetOSArgStr;
2389 }
2390 // Implicitly allow resolving the OS version when it wasn't explicitly set.
2391 bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion();
2392 if (!TripleProvidedOSVersion)
2393 PlatformAndVersion->setOSVersion(
2394 getInferredOSVersion(getTriple().getOS(), getTriple(), getDriver()));
2395
2396 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2397 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2398 if (PlatformAndVersionFromOSVersionArg) {
2399 unsigned TargetMajor, TargetMinor, TargetMicro;
2400 bool TargetExtra;
2401 unsigned ArgMajor, ArgMinor, ArgMicro;
2402 bool ArgExtra;
2403 if (PlatformAndVersion->getPlatform() !=
2404 PlatformAndVersionFromOSVersionArg->getPlatform() ||
2406 PlatformAndVersion->getOSVersion().getAsString(), TargetMajor,
2407 TargetMinor, TargetMicro, TargetExtra) &&
2409 PlatformAndVersionFromOSVersionArg->getOSVersion().getAsString(),
2410 ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
2411 (VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
2412 VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
2413 TargetExtra != ArgExtra))) {
2414 // Select the OS version from the -m<os>-version-min argument when
2415 // the -target does not include an OS version.
2416 if (PlatformAndVersion->getPlatform() ==
2417 PlatformAndVersionFromOSVersionArg->getPlatform() &&
2418 !TripleProvidedOSVersion) {
2419 PlatformAndVersion->setOSVersion(
2420 PlatformAndVersionFromOSVersionArg->getOSVersion());
2421 } else {
2422 // Warn about -m<os>-version-min that doesn't match the OS version
2423 // that's specified in the target.
2424 std::string OSVersionArg =
2425 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2426 std::string TargetArg = PlatformAndVersion->getAsString(Args, Opts);
2427 getDriver().Diag(clang::diag::warn_drv_overriding_option)
2428 << OSVersionArg << TargetArg;
2429 }
2430 }
2431 }
2432 } else if ((PlatformAndVersion = getDeploymentTargetFromMTargetOSArg(
2433 Args, getDriver(), SDKInfo))) {
2434 // The OS target can be specified using the -mtargetos= argument.
2435 // Disallow mixing -mtargetos= and -m<os>version-min=.
2436 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2437 getDeploymentTargetFromOSVersionArg(Args, getDriver());
2438 if (PlatformAndVersionFromOSVersionArg) {
2439 std::string MTargetOSArgStr = PlatformAndVersion->getAsString(Args, Opts);
2440 std::string OSVersionArgStr =
2441 PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
2442 getDriver().Diag(diag::err_drv_cannot_mix_options)
2443 << MTargetOSArgStr << OSVersionArgStr;
2444 }
2445 } else {
2446 // The OS target can be specified using the -m<os>version-min argument.
2447 PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver());
2448 // If no deployment target was specified on the command line, check for
2449 // environment defines.
2450 if (!PlatformAndVersion) {
2451 PlatformAndVersion =
2452 getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
2453 if (PlatformAndVersion) {
2454 // Don't infer simulator from the arch when the SDK is also specified.
2455 std::optional<DarwinPlatform> SDKTarget =
2456 inferDeploymentTargetFromSDK(Args, SDKInfo);
2457 if (SDKTarget)
2458 PlatformAndVersion->setEnvironment(SDKTarget->getEnvironment());
2459 }
2460 }
2461 // If there is no command-line argument to specify the Target version and
2462 // no environment variable defined, see if we can set the default based
2463 // on -isysroot using SDKSettings.json if it exists.
2464 if (!PlatformAndVersion) {
2465 PlatformAndVersion = inferDeploymentTargetFromSDK(Args, SDKInfo);
2466 /// If the target was successfully constructed from the SDK path, try to
2467 /// infer the SDK info if the SDK doesn't have it.
2468 if (PlatformAndVersion && !SDKInfo)
2469 SDKInfo = PlatformAndVersion->inferSDKInfo();
2470 }
2471 // If no OS targets have been specified, try to guess platform from -target
2472 // or arch name and compute the version from the triple.
2473 if (!PlatformAndVersion)
2474 PlatformAndVersion =
2475 inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
2476 }
2477
2478 assert(PlatformAndVersion && "Unable to infer Darwin variant");
2479 if (!PlatformAndVersion->isValidOSVersion()) {
2480 if (PlatformAndVersion->isExplicitlySpecified())
2481 getDriver().Diag(diag::err_drv_invalid_version_number)
2482 << PlatformAndVersion->getAsString(Args, Opts);
2483 else
2484 getDriver().Diag(diag::err_drv_invalid_version_number_inferred)
2485 << PlatformAndVersion->getOSVersion().getAsString()
2486 << PlatformAndVersion->getInferredSource();
2487 }
2488 // After the deployment OS version has been resolved, set it to the canonical
2489 // version before further error detection and converting to a proper target
2490 // triple.
2491 VersionTuple CanonicalVersion = PlatformAndVersion->getCanonicalOSVersion();
2492 if (CanonicalVersion != PlatformAndVersion->getOSVersion()) {
2493 getDriver().Diag(diag::warn_drv_overriding_deployment_version)
2494 << PlatformAndVersion->getOSVersion().getAsString()
2495 << CanonicalVersion.getAsString();
2496 PlatformAndVersion->setOSVersion(CanonicalVersion);
2497 }
2498
2499 PlatformAndVersion->addOSVersionMinArgument(Args, Opts);
2500 DarwinPlatformKind Platform = PlatformAndVersion->getPlatform();
2501
2502 unsigned Major, Minor, Micro;
2503 bool HadExtra;
2504 // The major version should not be over this number.
2505 const unsigned MajorVersionLimit = 1000;
2506 const VersionTuple OSVersion = PlatformAndVersion->takeOSVersion();
2507 const std::string OSVersionStr = OSVersion.getAsString();
2508 // Set the tool chain target information.
2509 if (Platform == MacOS) {
2510 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2511 HadExtra) ||
2512 HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||
2513 Micro >= 100)
2514 getDriver().Diag(diag::err_drv_invalid_version_number)
2515 << PlatformAndVersion->getAsString(Args, Opts);
2516 } else if (Platform == IPhoneOS) {
2517 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2518 HadExtra) ||
2519 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2520 getDriver().Diag(diag::err_drv_invalid_version_number)
2521 << PlatformAndVersion->getAsString(Args, Opts);
2522 ;
2523 if (PlatformAndVersion->getEnvironment() == MacCatalyst &&
2524 (Major < 13 || (Major == 13 && Minor < 1))) {
2525 getDriver().Diag(diag::err_drv_invalid_version_number)
2526 << PlatformAndVersion->getAsString(Args, Opts);
2527 Major = 13;
2528 Minor = 1;
2529 Micro = 0;
2530 }
2531 // For 32-bit targets, the deployment target for iOS has to be earlier than
2532 // iOS 11.
2533 if (getTriple().isArch32Bit() && Major >= 11) {
2534 // If the deployment target is explicitly specified, print a diagnostic.
2535 if (PlatformAndVersion->isExplicitlySpecified()) {
2536 if (PlatformAndVersion->getEnvironment() == MacCatalyst)
2537 getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
2538 else
2539 getDriver().Diag(diag::warn_invalid_ios_deployment_target)
2540 << PlatformAndVersion->getAsString(Args, Opts);
2541 // Otherwise, set it to 10.99.99.
2542 } else {
2543 Major = 10;
2544 Minor = 99;
2545 Micro = 99;
2546 }
2547 }
2548 } else if (Platform == TvOS) {
2549 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2550 HadExtra) ||
2551 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2552 getDriver().Diag(diag::err_drv_invalid_version_number)
2553 << PlatformAndVersion->getAsString(Args, Opts);
2554 } else if (Platform == WatchOS) {
2555 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2556 HadExtra) ||
2557 HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
2558 getDriver().Diag(diag::err_drv_invalid_version_number)
2559 << PlatformAndVersion->getAsString(Args, Opts);
2560 } else if (Platform == DriverKit) {
2561 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2562 HadExtra) ||
2563 HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||
2564 Micro >= 100)
2565 getDriver().Diag(diag::err_drv_invalid_version_number)
2566 << PlatformAndVersion->getAsString(Args, Opts);
2567 } else if (Platform == XROS) {
2568 if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
2569 HadExtra) ||
2570 HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||
2571 Micro >= 100)
2572 getDriver().Diag(diag::err_drv_invalid_version_number)
2573 << PlatformAndVersion->getAsString(Args, Opts);
2574 } else
2575 llvm_unreachable("unknown kind of Darwin platform");
2576
2577 DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();
2578 // Recognize iOS targets with an x86 architecture as the iOS simulator.
2579 if (Environment == NativeEnvironment && Platform != MacOS &&
2580 Platform != DriverKit &&
2581 PlatformAndVersion->canInferSimulatorFromArch() && getTriple().isX86())
2582 Environment = Simulator;
2583
2584 VersionTuple ZipperedOSVersion;
2585 if (Environment == MacCatalyst)
2586 ZipperedOSVersion = PlatformAndVersion->getZipperedOSVersion();
2587 setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);
2588 TargetVariantTriple = PlatformAndVersion->getTargetVariantTriple();
2589 if (TargetVariantTriple &&
2590 !llvm::Triple::isValidVersionForOS(TargetVariantTriple->getOS(),
2591 TargetVariantTriple->getOSVersion())) {
2592 getDriver().Diag(diag::err_drv_invalid_version_number)
2593 << TargetVariantTriple->str();
2594 }
2595
2596 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2597 StringRef SDK = getSDKName(A->getValue());
2598 if (SDK.size() > 0) {
2599 size_t StartVer = SDK.find_first_of("0123456789");
2600 StringRef SDKName = SDK.slice(0, StartVer);
2601 if (!SDKName.starts_with(getPlatformFamily()) &&
2602 !dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily()))
2603 getDriver().Diag(diag::warn_incompatible_sysroot)
2604 << SDKName << getPlatformFamily();
2605 }
2606 }
2607}
2608
2609// For certain platforms/environments almost all resources (e.g., headers) are
2610// located in sub-directories, e.g., for DriverKit they live in
2611// <SYSROOT>/System/DriverKit/usr/include (instead of <SYSROOT>/usr/include).
2613 const llvm::Triple &T) {
2614 if (T.isDriverKit()) {
2615 llvm::sys::path::append(Path, "System", "DriverKit");
2616 }
2617}
2618
2619// Returns the effective sysroot from either -isysroot or --sysroot, plus the
2620// platform prefix (if any).
2621llvm::SmallString<128>
2622AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
2623 llvm::SmallString<128> Path("/");
2624 if (DriverArgs.hasArg(options::OPT_isysroot))
2625 Path = DriverArgs.getLastArgValue(options::OPT_isysroot);
2626 else if (!getDriver().SysRoot.empty())
2627 Path = getDriver().SysRoot;
2628
2629 if (hasEffectiveTriple()) {
2631 }
2632 return Path;
2633}
2634
2636 const llvm::opt::ArgList &DriverArgs,
2637 llvm::opt::ArgStringList &CC1Args) const {
2638 const Driver &D = getDriver();
2639
2640 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2641
2642 bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);
2643 bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);
2644 bool NoBuiltinInc = DriverArgs.hasFlag(
2645 options::OPT_nobuiltininc, options::OPT_ibuiltininc, /*Default=*/false);
2646 bool ForceBuiltinInc = DriverArgs.hasFlag(
2647 options::OPT_ibuiltininc, options::OPT_nobuiltininc, /*Default=*/false);
2648
2649 // Add <sysroot>/usr/local/include
2650 if (!NoStdInc && !NoStdlibInc) {
2651 SmallString<128> P(Sysroot);
2652 llvm::sys::path::append(P, "usr", "local", "include");
2653 addSystemInclude(DriverArgs, CC1Args, P);
2654 }
2655
2656 // Add the Clang builtin headers (<resource>/include)
2657 if (!(NoStdInc && !ForceBuiltinInc) && !NoBuiltinInc) {
2658 SmallString<128> P(D.ResourceDir);
2659 llvm::sys::path::append(P, "include");
2660 addSystemInclude(DriverArgs, CC1Args, P);
2661 }
2662
2663 if (NoStdInc || NoStdlibInc)
2664 return;
2665
2666 // Check for configure-time C include directories.
2667 llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
2668 if (!CIncludeDirs.empty()) {
2670 CIncludeDirs.split(dirs, ":");
2671 for (llvm::StringRef dir : dirs) {
2672 llvm::StringRef Prefix =
2673 llvm::sys::path::is_absolute(dir) ? "" : llvm::StringRef(Sysroot);
2674 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
2675 }
2676 } else {
2677 // Otherwise, add <sysroot>/usr/include.
2678 SmallString<128> P(Sysroot);
2679 llvm::sys::path::append(P, "usr", "include");
2680 addExternCSystemInclude(DriverArgs, CC1Args, P.str());
2681 }
2682}
2683
2685 const llvm::opt::ArgList &DriverArgs,
2686 llvm::opt::ArgStringList &CC1Args) const {
2687 AppleMachO::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
2688
2689 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc))
2690 return;
2691
2692 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2693
2694 // Add <sysroot>/System/Library/Frameworks
2695 // Add <sysroot>/System/Library/SubFrameworks
2696 // Add <sysroot>/Library/Frameworks
2697 SmallString<128> P1(Sysroot), P2(Sysroot), P3(Sysroot);
2698 llvm::sys::path::append(P1, "System", "Library", "Frameworks");
2699 llvm::sys::path::append(P2, "System", "Library", "SubFrameworks");
2700 llvm::sys::path::append(P3, "Library", "Frameworks");
2701 addSystemFrameworkIncludes(DriverArgs, CC1Args, {P1, P2, P3});
2702}
2703
2704bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
2705 llvm::opt::ArgStringList &CC1Args,
2707 llvm::StringRef Version,
2708 llvm::StringRef ArchDir,
2709 llvm::StringRef BitDir) const {
2710 llvm::sys::path::append(Base, Version);
2711
2712 // Add the base dir
2713 addSystemInclude(DriverArgs, CC1Args, Base);
2714
2715 // Add the multilib dirs
2716 {
2718 if (!ArchDir.empty())
2719 llvm::sys::path::append(P, ArchDir);
2720 if (!BitDir.empty())
2721 llvm::sys::path::append(P, BitDir);
2722 addSystemInclude(DriverArgs, CC1Args, P);
2723 }
2724
2725 // Add the backward dir
2726 {
2728 llvm::sys::path::append(P, "backward");
2729 addSystemInclude(DriverArgs, CC1Args, P);
2730 }
2731
2732 return getVFS().exists(Base);
2733}
2734
2736 const llvm::opt::ArgList &DriverArgs,
2737 llvm::opt::ArgStringList &CC1Args) const {
2738 // The implementation from a base class will pass through the -stdlib to
2739 // CC1Args.
2740 // FIXME: this should not be necessary, remove usages in the frontend
2741 // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
2742 // Also check whether this is used for setting library search paths.
2743 ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
2744
2745 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
2746 options::OPT_nostdincxx))
2747 return;
2748
2749 llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
2750
2751 switch (GetCXXStdlibType(DriverArgs)) {
2752 case ToolChain::CST_Libcxx: {
2753 // On Darwin, libc++ can be installed in one of the following places:
2754 // 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
2755 // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
2756 //
2757 // The precedence of paths is as listed above, i.e. we take the first path
2758 // that exists. Note that we never include libc++ twice -- we take the first
2759 // path that exists and don't send the other paths to CC1 (otherwise
2760 // include_next could break).
2761
2762 // Check for (1)
2763 // Get from '<install>/bin' to '<install>/include/c++/v1'.
2764 // Note that InstallBin can be relative, so we use '..' instead of
2765 // parent_path.
2766 llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin
2767 llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
2768 if (getVFS().exists(InstallBin)) {
2769 addSystemInclude(DriverArgs, CC1Args, InstallBin);
2770 return;
2771 } else if (DriverArgs.hasArg(options::OPT_v)) {
2772 llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
2773 << "\"\n";
2774 }
2775
2776 // Otherwise, check for (2)
2777 llvm::SmallString<128> SysrootUsr = Sysroot;
2778 llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
2779 if (getVFS().exists(SysrootUsr)) {
2780 addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
2781 return;
2782 } else if (DriverArgs.hasArg(options::OPT_v)) {
2783 llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
2784 << "\"\n";
2785 }
2786
2787 // Otherwise, don't add any path.
2788 break;
2789 }
2790
2792 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
2793 break;
2794 }
2795}
2796
2797void AppleMachO::AddGnuCPlusPlusIncludePaths(
2798 const llvm::opt::ArgList &DriverArgs,
2799 llvm::opt::ArgStringList &CC1Args) const {}
2800
2801void DarwinClang::AddGnuCPlusPlusIncludePaths(
2802 const llvm::opt::ArgList &DriverArgs,
2803 llvm::opt::ArgStringList &CC1Args) const {
2804 llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);
2805 llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");
2806
2807 llvm::Triple::ArchType arch = getTriple().getArch();
2808 bool IsBaseFound = true;
2809 switch (arch) {
2810 default:
2811 break;
2812
2813 case llvm::Triple::x86:
2814 case llvm::Triple::x86_64:
2815 IsBaseFound = AddGnuCPlusPlusIncludePaths(
2816 DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",
2817 arch == llvm::Triple::x86_64 ? "x86_64" : "");
2818 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
2819 DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");
2820 break;
2821
2822 case llvm::Triple::arm:
2823 case llvm::Triple::thumb:
2824 IsBaseFound =
2825 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2826 "arm-apple-darwin10", "v7");
2827 IsBaseFound |=
2828 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2829 "arm-apple-darwin10", "v6");
2830 break;
2831
2832 case llvm::Triple::aarch64:
2833 IsBaseFound =
2834 AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
2835 "arm64-apple-darwin10", "");
2836 break;
2837 }
2838
2839 if (!IsBaseFound) {
2840 getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
2841 }
2842}
2843
2844void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
2845 ArgStringList &CmdArgs) const {
2847
2848 switch (Type) {
2850 CmdArgs.push_back("-lc++");
2851 if (Args.hasArg(options::OPT_fexperimental_library))
2852 CmdArgs.push_back("-lc++experimental");
2853 break;
2854
2856 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
2857 // it was previously found in the gcc lib dir. However, for all the Darwin
2858 // platforms we care about it was -lstdc++.6, so we search for that
2859 // explicitly if we can't see an obvious -lstdc++ candidate.
2860
2861 // Check in the sysroot first.
2862 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
2863 SmallString<128> P(A->getValue());
2864 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
2865
2866 if (!getVFS().exists(P)) {
2867 llvm::sys::path::remove_filename(P);
2868 llvm::sys::path::append(P, "libstdc++.6.dylib");
2869 if (getVFS().exists(P)) {
2870 CmdArgs.push_back(Args.MakeArgString(P));
2871 return;
2872 }
2873 }
2874 }
2875
2876 // Otherwise, look in the root.
2877 // FIXME: This should be removed someday when we don't have to care about
2878 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
2879 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
2880 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
2881 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
2882 return;
2883 }
2884
2885 // Otherwise, let the linker search.
2886 CmdArgs.push_back("-lstdc++");
2887 break;
2888 }
2889}
2890
2891void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
2892 ArgStringList &CmdArgs) const {
2893 // For Darwin platforms, use the compiler-rt-based support library
2894 // instead of the gcc-provided one (which is also incidentally
2895 // only present in the gcc lib dir, which makes it hard to find).
2896
2897 SmallString<128> P(getDriver().ResourceDir);
2898 llvm::sys::path::append(P, "lib", "darwin");
2899
2900 // Use the newer cc_kext for iOS ARM after 6.0.
2901 if (isTargetWatchOS()) {
2902 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
2903 } else if (isTargetTvOS()) {
2904 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
2905 } else if (isTargetIPhoneOS()) {
2906 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
2907 } else if (isTargetDriverKit()) {
2908 // DriverKit doesn't want extra runtime support.
2909 } else if (isTargetXROSDevice()) {
2910 llvm::sys::path::append(
2911 P, llvm::Twine("libclang_rt.cc_kext_") +
2912 llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a");
2913 } else {
2914 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
2915 }
2916
2917 // For now, allow missing resource libraries to support developers who may
2918 // not have compiler-rt checked out or integrated into their build.
2919 if (getVFS().exists(P))
2920 CmdArgs.push_back(Args.MakeArgString(P));
2921}
2922
2923DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
2924 StringRef BoundArch,
2925 Action::OffloadKind) const {
2926 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
2927 const OptTable &Opts = getDriver().getOpts();
2928
2929 // FIXME: We really want to get out of the tool chain level argument
2930 // translation business, as it makes the driver functionality much
2931 // more opaque. For now, we follow gcc closely solely for the
2932 // purpose of easily achieving feature parity & testability. Once we
2933 // have something that works, we should reevaluate each translation
2934 // and try to push it down into tool specific logic.
2935
2936 for (Arg *A : Args) {
2937 // Sob. These is strictly gcc compatible for the time being. Apple
2938 // gcc translates options twice, which means that self-expanding
2939 // options add duplicates.
2940 switch ((options::ID)A->getOption().getID()) {
2941 default:
2942 DAL->append(A);
2943 break;
2944
2945 case options::OPT_mkernel:
2946 case options::OPT_fapple_kext:
2947 DAL->append(A);
2948 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
2949 break;
2950
2951 case options::OPT_dependency_file:
2952 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
2953 break;
2954
2955 case options::OPT_gfull:
2956 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2957 DAL->AddFlagArg(
2958 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
2959 break;
2960
2961 case options::OPT_gused:
2962 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
2963 DAL->AddFlagArg(
2964 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
2965 break;
2966
2967 case options::OPT_shared:
2968 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
2969 break;
2970
2971 case options::OPT_fconstant_cfstrings:
2972 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
2973 break;
2974
2975 case options::OPT_fno_constant_cfstrings:
2976 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
2977 break;
2978
2979 case options::OPT_Wnonportable_cfstrings:
2980 DAL->AddFlagArg(A,
2981 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
2982 break;
2983
2984 case options::OPT_Wno_nonportable_cfstrings:
2985 DAL->AddFlagArg(
2986 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
2987 break;
2988 }
2989 }
2990
2991 // Add the arch options based on the particular spelling of -arch, to match
2992 // how the driver works.
2993 if (!BoundArch.empty()) {
2994 StringRef Name = BoundArch;
2995 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
2996 const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ);
2997
2998 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
2999 // which defines the list of which architectures we accept.
3000 if (Name == "ppc")
3001 ;
3002 else if (Name == "ppc601")
3003 DAL->AddJoinedArg(nullptr, MCpu, "601");
3004 else if (Name == "ppc603")
3005 DAL->AddJoinedArg(nullptr, MCpu, "603");
3006 else if (Name == "ppc604")
3007 DAL->AddJoinedArg(nullptr, MCpu, "604");
3008 else if (Name == "ppc604e")
3009 DAL->AddJoinedArg(nullptr, MCpu, "604e");
3010 else if (Name == "ppc750")
3011 DAL->AddJoinedArg(nullptr, MCpu, "750");
3012 else if (Name == "ppc7400")
3013 DAL->AddJoinedArg(nullptr, MCpu, "7400");
3014 else if (Name == "ppc7450")
3015 DAL->AddJoinedArg(nullptr, MCpu, "7450");
3016 else if (Name == "ppc970")
3017 DAL->AddJoinedArg(nullptr, MCpu, "970");
3018
3019 else if (Name == "ppc64" || Name == "ppc64le")
3020 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3021
3022 else if (Name == "i386")
3023 ;
3024 else if (Name == "i486")
3025 DAL->AddJoinedArg(nullptr, MArch, "i486");
3026 else if (Name == "i586")
3027 DAL->AddJoinedArg(nullptr, MArch, "i586");
3028 else if (Name == "i686")
3029 DAL->AddJoinedArg(nullptr, MArch, "i686");
3030 else if (Name == "pentium")
3031 DAL->AddJoinedArg(nullptr, MArch, "pentium");
3032 else if (Name == "pentium2")
3033 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3034 else if (Name == "pentpro")
3035 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
3036 else if (Name == "pentIIm3")
3037 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
3038
3039 else if (Name == "x86_64" || Name == "x86_64h")
3040 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
3041
3042 else if (Name == "arm")
3043 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3044 else if (Name == "armv4t")
3045 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
3046 else if (Name == "armv5")
3047 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
3048 else if (Name == "xscale")
3049 DAL->AddJoinedArg(nullptr, MArch, "xscale");
3050 else if (Name == "armv6")
3051 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
3052 else if (Name == "armv6m")
3053 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
3054 else if (Name == "armv7")
3055 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
3056 else if (Name == "armv7em")
3057 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
3058 else if (Name == "armv7k")
3059 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
3060 else if (Name == "armv7m")
3061 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
3062 else if (Name == "armv7s")
3063 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
3064 }
3065
3066 return DAL;
3067}
3068
3069void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
3070 ArgStringList &CmdArgs,
3071 bool ForceLinkBuiltinRT) const {
3072 // Embedded targets are simple at the moment, not supporting sanitizers and
3073 // with different libraries for each member of the product { static, PIC } x
3074 // { hard-float, soft-float }
3075 llvm::SmallString<32> CompilerRT = StringRef("");
3076 CompilerRT +=
3078 ? "hard"
3079 : "soft";
3080 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static";
3081
3082 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);
3083}
3084
3086 llvm::Triple::OSType OS;
3087
3088 if (isTargetMacCatalyst())
3089 return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX);
3090 switch (TargetPlatform) {
3091 case MacOS: // Earlier than 10.13.
3092 OS = llvm::Triple::MacOSX;
3093 break;
3094 case IPhoneOS:
3095 OS = llvm::Triple::IOS;
3096 break;
3097 case TvOS: // Earlier than 11.0.
3098 OS = llvm::Triple::TvOS;
3099 break;
3100 case WatchOS: // Earlier than 4.0.
3101 OS = llvm::Triple::WatchOS;
3102 break;
3103 case XROS: // Always available.
3104 return false;
3105 case DriverKit: // Always available.
3106 return false;
3107 }
3108
3110}
3111
3112static bool
3113sdkSupportsBuiltinModules(const std::optional<DarwinSDKInfo> &SDKInfo) {
3114 if (!SDKInfo)
3115 // If there is no SDK info, assume this is building against a
3116 // pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those
3117 // don't support modules anyway, but the headers definitely
3118 // don't support builtin modules either. It might also be some
3119 // kind of degenerate build environment, err on the side of
3120 // the old behavior which is to not use builtin modules.
3121 return false;
3122
3123 VersionTuple SDKVersion = SDKInfo->getVersion();
3124 switch (SDKInfo->getOS()) {
3125 // Existing SDKs added support for builtin modules in the fall
3126 // 2024 major releases.
3127 case llvm::Triple::MacOSX:
3128 return SDKVersion >= VersionTuple(15U);
3129 case llvm::Triple::IOS:
3130 return SDKVersion >= VersionTuple(18U);
3131 case llvm::Triple::TvOS:
3132 return SDKVersion >= VersionTuple(18U);
3133 case llvm::Triple::WatchOS:
3134 return SDKVersion >= VersionTuple(11U);
3135 case llvm::Triple::XROS:
3136 return SDKVersion >= VersionTuple(2U);
3137
3138 // New SDKs support builtin modules from the start.
3139 default:
3140 return true;
3141 }
3142}
3143
3144static inline llvm::VersionTuple
3145sizedDeallocMinVersion(llvm::Triple::OSType OS) {
3146 switch (OS) {
3147 default:
3148 break;
3149 case llvm::Triple::Darwin:
3150 case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.
3151 return llvm::VersionTuple(10U, 12U);
3152 case llvm::Triple::IOS:
3153 case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0.
3154 return llvm::VersionTuple(10U);
3155 case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0.
3156 return llvm::VersionTuple(3U);
3157 }
3158
3159 llvm_unreachable("Unexpected OS");
3160}
3161
3163 llvm::Triple::OSType OS;
3164
3165 if (isTargetMacCatalyst())
3166 return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX);
3167 switch (TargetPlatform) {
3168 case MacOS: // Earlier than 10.12.
3169 OS = llvm::Triple::MacOSX;
3170 break;
3171 case IPhoneOS:
3172 OS = llvm::Triple::IOS;
3173 break;
3174 case TvOS: // Earlier than 10.0.
3175 OS = llvm::Triple::TvOS;
3176 break;
3177 case WatchOS: // Earlier than 3.0.
3178 OS = llvm::Triple::WatchOS;
3179 break;
3180 case DriverKit:
3181 case XROS:
3182 // Always available.
3183 return false;
3184 }
3185
3187}
3188
3189void MachO::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
3190 llvm::opt::ArgStringList &CC1Args,
3191 Action::OffloadKind DeviceOffloadKind) const {
3192
3193 ToolChain::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3194
3195 // On arm64e, we enable all the features required for the Darwin userspace
3196 // ABI
3197 if (getTriple().isArm64e()) {
3198 // Core platform ABI
3199 if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
3200 options::OPT_fno_ptrauth_calls))
3201 CC1Args.push_back("-fptrauth-calls");
3202 if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
3203 options::OPT_fno_ptrauth_returns))
3204 CC1Args.push_back("-fptrauth-returns");
3205 if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
3206 options::OPT_fno_ptrauth_intrinsics))
3207 CC1Args.push_back("-fptrauth-intrinsics");
3208 if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos,
3209 options::OPT_fno_ptrauth_indirect_gotos))
3210 CC1Args.push_back("-fptrauth-indirect-gotos");
3211 if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
3212 options::OPT_fno_ptrauth_auth_traps))
3213 CC1Args.push_back("-fptrauth-auth-traps");
3214
3215 // C++ v-table ABI
3216 if (!DriverArgs.hasArg(
3217 options::OPT_fptrauth_vtable_pointer_address_discrimination,
3218 options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
3219 CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
3220 if (!DriverArgs.hasArg(
3221 options::OPT_fptrauth_vtable_pointer_type_discrimination,
3222 options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
3223 CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
3224
3225 // Objective-C ABI
3226 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_isa,
3227 options::OPT_fno_ptrauth_objc_isa))
3228 CC1Args.push_back("-fptrauth-objc-isa");
3229 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_class_ro,
3230 options::OPT_fno_ptrauth_objc_class_ro))
3231 CC1Args.push_back("-fptrauth-objc-class-ro");
3232 if (!DriverArgs.hasArg(options::OPT_fptrauth_objc_interface_sel,
3233 options::OPT_fno_ptrauth_objc_interface_sel))
3234 CC1Args.push_back("-fptrauth-objc-interface-sel");
3235 }
3236}
3237
3239 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
3240 Action::OffloadKind DeviceOffloadKind) const {
3241
3242 MachO::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind);
3243
3244 // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
3245 // enabled or disabled aligned allocations.
3246 if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
3247 options::OPT_fno_aligned_allocation) &&
3249 CC1Args.push_back("-faligned-alloc-unavailable");
3250
3251 // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
3252 // or disabled sized deallocations.
3253 if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,
3254 options::OPT_fno_sized_deallocation) &&
3256 CC1Args.push_back("-fno-sized-deallocation");
3257
3258 addClangCC1ASTargetOptions(DriverArgs, CC1Args);
3259
3260 // Enable compatibility mode for NSItemProviderCompletionHandler in
3261 // Foundation/NSItemProvider.h.
3262 CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking");
3263
3264 // Give static local variables in inline functions hidden visibility when
3265 // -fvisibility-inlines-hidden is enabled.
3266 if (!DriverArgs.getLastArgNoClaim(
3267 options::OPT_fvisibility_inlines_hidden_static_local_var,
3268 options::OPT_fno_visibility_inlines_hidden_static_local_var))
3269 CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");
3270
3271 // Earlier versions of the darwin SDK have the C standard library headers
3272 // all together in the Darwin module. That leads to module cycles with
3273 // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.
3274 // The builtin <stdint.h> include-nexts <stdint.h>. When both of those
3275 // darwin headers are in the Darwin module, there's a module cycle Darwin ->
3276 // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->
3277 // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,
3278 // but until then, the builtin headers need to join the system modules.
3279 // i.e. when the builtin stdint.h is in the Darwin module too, the cycle
3280 // goes away. Note that -fbuiltin-headers-in-system-modules does nothing
3281 // to fix the same problem with C++ headers, and is generally fragile.
3283 CC1Args.push_back("-fbuiltin-headers-in-system-modules");
3284
3285 if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros,
3286 options::OPT_fno_define_target_os_macros))
3287 CC1Args.push_back("-fdefine-target-os-macros");
3288
3289 // Disable subdirectory modulemap search on sufficiently recent SDKs.
3290 if (SDKInfo &&
3291 !DriverArgs.hasFlag(options::OPT_fmodulemap_allow_subdirectory_search,
3292 options::OPT_fno_modulemap_allow_subdirectory_search,
3293 false)) {
3294 bool RequiresSubdirectorySearch;
3295 VersionTuple SDKVersion = SDKInfo->getVersion();
3296 switch (TargetPlatform) {
3297 default:
3298 RequiresSubdirectorySearch = true;
3299 break;
3300 case MacOS:
3301 RequiresSubdirectorySearch = SDKVersion < VersionTuple(15, 0);
3302 break;
3303 case IPhoneOS:
3304 case TvOS:
3305 RequiresSubdirectorySearch = SDKVersion < VersionTuple(18, 0);
3306 break;
3307 case WatchOS:
3308 RequiresSubdirectorySearch = SDKVersion < VersionTuple(11, 0);
3309 break;
3310 case XROS:
3311 RequiresSubdirectorySearch = SDKVersion < VersionTuple(2, 0);
3312 break;
3313 }
3314 if (!RequiresSubdirectorySearch)
3315 CC1Args.push_back("-fno-modulemap-allow-subdirectory-search");
3316 }
3317}
3318
3320 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const {
3321 if (TargetVariantTriple) {
3322 CC1ASArgs.push_back("-darwin-target-variant-triple");
3323 CC1ASArgs.push_back(Args.MakeArgString(TargetVariantTriple->getTriple()));
3324 }
3325
3326 if (SDKInfo) {
3327 /// Pass the SDK version to the compiler when the SDK information is
3328 /// available.
3329 auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) {
3330 std::string Arg;
3331 llvm::raw_string_ostream OS(Arg);
3332 OS << "-target-sdk-version=" << V;
3333 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3334 };
3335
3336 if (isTargetMacCatalyst()) {
3337 if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
3339 std::optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(
3341 std::nullopt);
3342 EmitTargetSDKVersionArg(
3343 SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget());
3344 }
3345 } else {
3346 EmitTargetSDKVersionArg(SDKInfo->getVersion());
3347 }
3348
3349 /// Pass the target variant SDK version to the compiler when the SDK
3350 /// information is available and is required for target variant.
3351 if (TargetVariantTriple) {
3352 if (isTargetMacCatalyst()) {
3353 std::string Arg;
3354 llvm::raw_string_ostream OS(Arg);
3355 OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();
3356 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3357 } else if (const auto *MacOStoMacCatalystMapping =
3358 SDKInfo->getVersionMapping(
3360 if (std::optional<VersionTuple> SDKVersion =
3361 MacOStoMacCatalystMapping->map(
3363 std::nullopt)) {
3364 std::string Arg;
3365 llvm::raw_string_ostream OS(Arg);
3366 OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;
3367 CC1ASArgs.push_back(Args.MakeArgString(Arg));
3368 }
3369 }
3370 }
3371 }
3372}
3373
3374DerivedArgList *
3375Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
3376 Action::OffloadKind DeviceOffloadKind) const {
3377 // First get the generic Apple args, before moving onto Darwin-specific ones.
3378 DerivedArgList *DAL =
3379 MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
3380
3381 // If no architecture is bound, none of the translations here are relevant.
3382 if (BoundArch.empty())
3383 return DAL;
3384
3385 // Add an explicit version min argument for the deployment target. We do this
3386 // after argument translation because -Xarch_ arguments may add a version min
3387 // argument.
3388 AddDeploymentTarget(*DAL);
3389
3390 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
3391 // FIXME: It would be far better to avoid inserting those -static arguments,
3392 // but we can't check the deployment target in the translation code until
3393 // it is set here.
3395 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
3396 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
3397 Arg *A = *it;
3398 ++it;
3399 if (A->getOption().getID() != options::OPT_mkernel &&
3400 A->getOption().getID() != options::OPT_fapple_kext)
3401 continue;
3402 assert(it != ie && "unexpected argument translation");
3403 A = *it;
3404 assert(A->getOption().getID() == options::OPT_static &&
3405 "missing expected -static argument");
3406 *it = nullptr;
3407 ++it;
3408 }
3409 }
3410
3412 if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {
3413 if (Args.hasFlag(options::OPT_fomit_frame_pointer,
3414 options::OPT_fno_omit_frame_pointer, false))
3415 getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
3416 << "-fomit-frame-pointer" << BoundArch;
3417 }
3418
3419 return DAL;
3420}
3421
3423 // Unwind tables are not emitted if -fno-exceptions is supplied (except when
3424 // targeting x86_64).
3425 if (getArch() == llvm::Triple::x86_64 ||
3426 (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&
3427 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
3428 true)))
3429 return (getArch() == llvm::Triple::aarch64 ||
3430 getArch() == llvm::Triple::aarch64_32)
3433
3435}
3436
3438 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
3439 return S[0] != '\0';
3440 return false;
3441}
3442
3444 if (const char *S = ::getenv("RC_DEBUG_PREFIX_MAP"))
3445 return S;
3446 return {};
3447}
3448
3449llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {
3450 // Darwin uses SjLj exceptions on ARM.
3451 if (getTriple().getArch() != llvm::Triple::arm &&
3452 getTriple().getArch() != llvm::Triple::thumb)
3453 return llvm::ExceptionHandling::None;
3454
3455 // Only watchOS uses the new DWARF/Compact unwinding method.
3456 llvm::Triple Triple(ComputeLLVMTriple(Args));
3457 if (Triple.isWatchABI())
3458 return llvm::ExceptionHandling::DwarfCFI;
3459
3460 return llvm::ExceptionHandling::SjLj;
3461}
3462
3464 assert(TargetInitialized && "Target not initialized!");
3466 return false;
3467 return true;
3468}
3469
3470bool MachO::isPICDefault() const { return true; }
3471
3472bool MachO::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; }
3473
3475 return (getArch() == llvm::Triple::x86_64 ||
3476 getArch() == llvm::Triple::aarch64);
3477}
3478
3480 // Profiling instrumentation is only supported on x86.
3481 return getTriple().isX86();
3482}
3483
3484void Darwin::addMinVersionArgs(const ArgList &Args,
3485 ArgStringList &CmdArgs) const {
3486 VersionTuple TargetVersion = getTripleTargetVersion();
3487
3488 assert(!isTargetXROS() && "xrOS always uses -platform-version");
3489
3490 if (isTargetWatchOS())
3491 CmdArgs.push_back("-watchos_version_min");
3492 else if (isTargetWatchOSSimulator())
3493 CmdArgs.push_back("-watchos_simulator_version_min");
3494 else if (isTargetTvOS())
3495 CmdArgs.push_back("-tvos_version_min");
3496 else if (isTargetTvOSSimulator())
3497 CmdArgs.push_back("-tvos_simulator_version_min");
3498 else if (isTargetDriverKit())
3499 CmdArgs.push_back("-driverkit_version_min");
3500 else if (isTargetIOSSimulator())
3501 CmdArgs.push_back("-ios_simulator_version_min");
3502 else if (isTargetIOSBased())
3503 CmdArgs.push_back("-iphoneos_version_min");
3504 else if (isTargetMacCatalyst())
3505 CmdArgs.push_back("-maccatalyst_version_min");
3506 else {
3507 assert(isTargetMacOS() && "unexpected target");
3508 CmdArgs.push_back("-macosx_version_min");
3509 }
3510
3511 VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
3512 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3513 TargetVersion = MinTgtVers;
3514 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3515 if (TargetVariantTriple) {
3516 assert(isTargetMacOSBased() && "unexpected target");
3517 VersionTuple VariantTargetVersion;
3518 if (TargetVariantTriple->isMacOSX()) {
3519 CmdArgs.push_back("-macosx_version_min");
3520 TargetVariantTriple->getMacOSXVersion(VariantTargetVersion);
3521 } else {
3522 assert(TargetVariantTriple->isiOS() &&
3523 TargetVariantTriple->isMacCatalystEnvironment() &&
3524 "unexpected target variant triple");
3525 CmdArgs.push_back("-maccatalyst_version_min");
3526 VariantTargetVersion = TargetVariantTriple->getiOSVersion();
3527 }
3528 VersionTuple MinTgtVers =
3529 TargetVariantTriple->getMinimumSupportedOSVersion();
3530 if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion)
3531 VariantTargetVersion = MinTgtVers;
3532 CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString()));
3533 }
3534}
3535
3537 Darwin::DarwinEnvironmentKind Environment) {
3538 switch (Platform) {
3539 case Darwin::MacOS:
3540 return "macos";
3541 case Darwin::IPhoneOS:
3542 if (Environment == Darwin::MacCatalyst)
3543 return "mac catalyst";
3544 return "ios";
3545 case Darwin::TvOS:
3546 return "tvos";
3547 case Darwin::WatchOS:
3548 return "watchos";
3549 case Darwin::XROS:
3550 return "xros";
3551 case Darwin::DriverKit:
3552 return "driverkit";
3553 }
3554 llvm_unreachable("invalid platform");
3555}
3556
3557void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
3558 llvm::opt::ArgStringList &CmdArgs) const {
3559 auto EmitPlatformVersionArg =
3560 [&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,
3562 const llvm::Triple &TT) {
3563 // -platform_version <platform> <target_version> <sdk_version>
3564 // Both the target and SDK version support only up to 3 components.
3565 CmdArgs.push_back("-platform_version");
3566 std::string PlatformName =
3569 PlatformName += "-simulator";
3570 CmdArgs.push_back(Args.MakeArgString(PlatformName));
3571 VersionTuple TargetVersion = TV.withoutBuild();
3574 getTriple().getArchName() == "arm64e" &&
3575 TargetVersion.getMajor() < 14) {
3576 // arm64e slice is supported on iOS/tvOS 14+ only.
3577 TargetVersion = VersionTuple(14, 0);
3578 }
3579 VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion();
3580 if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
3581 TargetVersion = MinTgtVers;
3582 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3583
3585 // Mac Catalyst programs must use the appropriate iOS SDK version
3586 // that corresponds to the macOS SDK version used for the compilation.
3587 std::optional<VersionTuple> iOSSDKVersion;
3588 if (SDKInfo) {
3589 if (const auto *MacOStoMacCatalystMapping =
3590 SDKInfo->getVersionMapping(
3592 iOSSDKVersion = MacOStoMacCatalystMapping->map(
3593 SDKInfo->getVersion().withoutBuild(),
3594 minimumMacCatalystDeploymentTarget(), std::nullopt);
3595 }
3596 }
3597 CmdArgs.push_back(Args.MakeArgString(
3598 (iOSSDKVersion ? *iOSSDKVersion
3600 .getAsString()));
3601 return;
3602 }
3603
3604 if (SDKInfo) {
3605 VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
3606 if (!SDKVersion.getMinor())
3607 SDKVersion = VersionTuple(SDKVersion.getMajor(), 0);
3608 CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
3609 } else {
3610 // Use an SDK version that's matching the deployment target if the SDK
3611 // version is missing. This is preferred over an empty SDK version
3612 // (0.0.0) as the system's runtime might expect the linked binary to
3613 // contain a valid SDK version in order for the binary to work
3614 // correctly. It's reasonable to use the deployment target version as
3615 // a proxy for the SDK version because older SDKs don't guarantee
3616 // support for deployment targets newer than the SDK versions, so that
3617 // rules out using some predetermined older SDK version, which leaves
3618 // the deployment target version as the only reasonable choice.
3619 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
3620 }
3621 };
3622 EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform,
3625 return;
3628 VersionTuple TargetVariantVersion;
3629 if (TargetVariantTriple->isMacOSX()) {
3630 TargetVariantTriple->getMacOSXVersion(TargetVariantVersion);
3631 Platform = Darwin::MacOS;
3632 Environment = Darwin::NativeEnvironment;
3633 } else {
3634 assert(TargetVariantTriple->isiOS() &&
3635 TargetVariantTriple->isMacCatalystEnvironment() &&
3636 "unexpected target variant triple");
3637 TargetVariantVersion = TargetVariantTriple->getiOSVersion();
3638 Platform = Darwin::IPhoneOS;
3639 Environment = Darwin::MacCatalyst;
3640 }
3641 EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment,
3643}
3644
3645// Add additional link args for the -dynamiclib option.
3646static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args,
3647 ArgStringList &CmdArgs) {
3648 // Derived from darwin_dylib1 spec.
3649 if (D.isTargetIPhoneOS()) {
3650 if (D.isIPhoneOSVersionLT(3, 1))
3651 CmdArgs.push_back("-ldylib1.o");
3652 return;
3653 }
3654
3655 if (!D.isTargetMacOS())
3656 return;
3657 if (D.isMacosxVersionLT(10, 5))
3658 CmdArgs.push_back("-ldylib1.o");
3659 else if (D.isMacosxVersionLT(10, 6))
3660 CmdArgs.push_back("-ldylib1.10.5.o");
3661}
3662
3663// Add additional link args for the -bundle option.
3664static void addBundleLinkArgs(const Darwin &D, const ArgList &Args,
3665 ArgStringList &CmdArgs) {
3666 if (Args.hasArg(options::OPT_static))
3667 return;
3668 // Derived from darwin_bundle1 spec.
3669 if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) ||
3670 (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6)))
3671 CmdArgs.push_back("-lbundle1.o");
3672}
3673
3674// Add additional link args for the -pg option.
3675static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,
3676 ArgStringList &CmdArgs) {
3677 if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) {
3678 if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) ||
3679 Args.hasArg(options::OPT_preload)) {
3680 CmdArgs.push_back("-lgcrt0.o");
3681 } else {
3682 CmdArgs.push_back("-lgcrt1.o");
3683
3684 // darwin_crt2 spec is empty.
3685 }
3686 // By default on OS X 10.8 and later, we don't link with a crt1.o
3687 // file and the linker knows to use _main as the entry point. But,
3688 // when compiling with -pg, we need to link with the gcrt1.o file,
3689 // so pass the -no_new_main option to tell the linker to use the
3690 // "start" symbol as the entry point.
3691 if (!D.isMacosxVersionLT(10, 8))
3692 CmdArgs.push_back("-no_new_main");
3693 } else {
3694 D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
3695 << D.isTargetMacOSBased();
3696 }
3697}
3698
3699static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args,
3700 ArgStringList &CmdArgs) {
3701 // Derived from darwin_crt1 spec.
3702 if (D.isTargetIPhoneOS()) {
3703 if (D.getArch() == llvm::Triple::aarch64)
3704 ; // iOS does not need any crt1 files for arm64
3705 else if (D.isIPhoneOSVersionLT(3, 1))
3706 CmdArgs.push_back("-lcrt1.o");
3707 else if (D.isIPhoneOSVersionLT(6, 0))
3708 CmdArgs.push_back("-lcrt1.3.1.o");
3709 return;
3710 }
3711
3712 if (!D.isTargetMacOS())
3713 return;
3714 if (D.isMacosxVersionLT(10, 5))
3715 CmdArgs.push_back("-lcrt1.o");
3716 else if (D.isMacosxVersionLT(10, 6))
3717 CmdArgs.push_back("-lcrt1.10.5.o");
3718 else if (D.isMacosxVersionLT(10, 8))
3719 CmdArgs.push_back("-lcrt1.10.6.o");
3720 // darwin_crt2 spec is empty.
3721}
3722
3723void Darwin::addStartObjectFileArgs(const ArgList &Args,
3724 ArgStringList &CmdArgs) const {
3725 // Derived from startfile spec.
3726 if (Args.hasArg(options::OPT_dynamiclib))
3727 addDynamicLibLinkArgs(*this, Args, CmdArgs);
3728 else if (Args.hasArg(options::OPT_bundle))
3729 addBundleLinkArgs(*this, Args, CmdArgs);
3730 else if (Args.hasArg(options::OPT_pg) && SupportsProfiling())
3731 addPgProfilingLinkArgs(*this, Args, CmdArgs);
3732 else if (Args.hasArg(options::OPT_static) ||
3733 Args.hasArg(options::OPT_object) ||
3734 Args.hasArg(options::OPT_preload))
3735 CmdArgs.push_back("-lcrt0.o");
3736 else
3737 addDefaultCRTLinkArgs(*this, Args, CmdArgs);
3738
3739 if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) &&
3740 isMacosxVersionLT(10, 5)) {
3741 const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
3742 CmdArgs.push_back(Str);
3743 }
3744}
3745
3749 return;
3750 getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
3751}
3752
3754 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3755 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
3757 Res |= SanitizerKind::Address;
3758 Res |= SanitizerKind::PointerCompare;
3759 Res |= SanitizerKind::PointerSubtract;
3760 Res |= SanitizerKind::Realtime;
3761 Res |= SanitizerKind::Leak;
3762 Res |= SanitizerKind::Fuzzer;
3763 Res |= SanitizerKind::FuzzerNoLink;
3764 Res |= SanitizerKind::ObjCCast;
3765
3766 // Prior to 10.9, macOS shipped a version of the C++ standard library without
3767 // C++11 support. The same is true of iOS prior to version 5. These OS'es are
3768 // incompatible with -fsanitize=vptr.
3769 if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
3771 Res |= SanitizerKind::Vptr;
3772
3773 if ((IsX86_64 || IsAArch64) &&
3776 Res |= SanitizerKind::Thread;
3777 }
3778
3779 if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
3780 Res |= SanitizerKind::Type;
3781 }
3782
3783 if (IsX86_64)
3784 Res |= SanitizerKind::NumericalStability;
3785
3786 return Res;
3787}
3788
3789void AppleMachO::printVerboseInfo(raw_ostream &OS) const {
3790 CudaInstallation->print(OS);
3791 RocmInstallation->print(OS);
3792}
#define V(N, I)
Defines a function that returns the minimum OS versions supporting C++17's aligned allocation functio...
static bool hasMultipleInvocations(const llvm::Triple &Triple, const ArgList &Args)
Definition Clang.cpp:1205
static bool checkRemarksOptions(const Driver &D, const ArgList &Args, const llvm::Triple &Triple)
Definition Clang.cpp:1216
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple, const InputInfo &Input, const InputInfo &Output, const JobAction &JA)
Definition Clang.cpp:1232
static bool sdkSupportsBuiltinModules(const std::optional< DarwinSDKInfo > &SDKInfo)
Definition Darwin.cpp:3113
static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3675
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:3699
static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3664
static llvm::VersionTuple sizedDeallocMinVersion(llvm::Triple::OSType OS)
Definition Darwin.cpp:3145
static VersionTuple minimumMacCatalystDeploymentTarget()
Definition Darwin.cpp:36
static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion)
Returns the most appropriate macOS target version for the current process.
Definition Darwin.cpp:1667
static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, ArgStringList &CmdArgs)
Definition Darwin.cpp:3646
static void AppendPlatformPrefix(SmallString< 128 > &Path, const llvm::Triple &T)
Definition Darwin.cpp:2612
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:3536
static const char * ArmMachOArchNameCPU(StringRef CPU)
Definition Darwin.cpp:1047
static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol)
Add an export directive for Symbol to the link command.
Definition Darwin.cpp:1457
static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode)
Take a path that speculatively points into Xcode and return the XCODE/Contents/Developer path if it i...
Definition Darwin.cpp:1211
static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs, StringRef Segment, StringRef Section)
Add a sectalign directive for Segment and Section to the maximum expected page size for Darwin.
Definition Darwin.cpp:1468
Defines types useful for describing an Objective-C runtime.
The basic abstraction for the target Objective-C runtime.
Definition ObjCRuntime.h:28
bool hasNativeARC() const
Does this runtime natively provide the ARC entrypoints?
bool hasSubscripting() const
Does this runtime directly support the subscripting methods?
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
Definition ObjCRuntime.h:35
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Definition ObjCRuntime.h:40
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Definition ObjCRuntime.h:45
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
Definition ObjCRuntime.h:49
The base class of the type hierarchy.
Definition TypeBase.h:1833
Action - Represent an abstract compilation step to perform.
Definition Action.h:47
types::ID getType() const
Definition Action.h:150
ActionClass getKind() const
Definition Action.h:149
ActionList & getInputs()
Definition Action.h:152
Compilation - A set of tasks to perform for a single driver invocation.
Definition Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:99
std::string SysRoot
sysroot, if present
Definition Driver.h:205
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
Definition Driver.cpp:6686
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:7031
const llvm::opt::OptTable & getOpts() const
Definition Driver.h:428
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
Definition Driver.cpp:6675
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition Driver.h:180
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Definition Driver.h:755
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
Definition Driver.h:758
InputInfo - Wrapper for information about an input source.
Definition InputInfo.h:22
const char * getFilename() const
Definition InputInfo.h:83
bool isFilename() const
Definition InputInfo.h:75
types::ID getType() const
Definition InputInfo.h:77
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
static void addSystemFrameworkIncludes(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, ArrayRef< StringRef > Paths)
Utility function to add a list of system framework directories to CC1.
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
std::string GetFilePath(const char *Name) const
static bool needsProfileRT(const llvm::opt::ArgList &Args)
needsProfileRT - returns true if instrumentation profile is on.
StringRef getOS() const
Definition ToolChain.h:272
llvm::Triple::ArchType getArch() const
Definition ToolChain.h:269
const Driver & getDriver() const
Definition ToolChain.h:253
llvm::vfs::FileSystem & getVFS() const
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args)
Returns true if gcov instrumentation (-fprofile-arcs or –coverage) is on.
virtual std::string ComputeLLVMTriple(const llvm::opt::ArgList &Args, types::ID InputType=types::TY_INVALID) const
ComputeLLVMTriple - Return the LLVM target triple to use, after taking command line arguments into ac...
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition ToolChain.cpp:89
virtual bool SupportsEmbeddedBitcode() const
SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
Definition ToolChain.h:638
path_list & getProgramPaths()
Definition ToolChain.h:298
bool hasEffectiveTriple() const
Definition ToolChain.h:288
const llvm::Triple & getEffectiveTriple() const
Get the toolchain's effective clang triple.
Definition ToolChain.h:283
const llvm::Triple & getTriple() const
Definition ToolChain.h:255
virtual types::ID LookupTypeForExtension(StringRef Ext) const
LookupTypeForExtension - Return the default language type to use for the given extension.
const XRayArgs getXRayArgs(const llvm::opt::ArgList &) const
virtual void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const
Add options that need to be passed to cc1 for this target.
virtual Tool * getTool(Action::ActionClass AC) const
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
StringRef getArchName() const
Definition ToolChain.h:270
Tool - Information on a specific compilation tool.
Definition Tool.h:32
const ToolChain & getToolChain() const
Definition Tool.h:52
bool needsXRayRt() const
Definition XRayArgs.h:38
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition Darwin.cpp:2844
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:3789
llvm::SmallString< 128 > GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const
Definition Darwin.cpp:2622
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:2635
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:2735
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:2684
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:2891
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:3557
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:3463
void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass a suitable profile runtime ...
Definition Darwin.cpp:1475
Darwin(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Darwin - Darwin tool chain for i386 and x86_64.
Definition Darwin.cpp:961
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition Darwin.cpp:3753
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:3238
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:3746
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition Darwin.cpp:3449
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:3162
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 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:3375
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:3319
void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, unsigned Major, unsigned Minor, unsigned Micro, VersionTuple NativeTargetVersion) const
Definition Darwin.h:426
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:3484
void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
Definition Darwin.cpp:3723
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:3085
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:3470
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
Definition Darwin.cpp:3474
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:3189
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:3422
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:3443
bool SupportsProfiling() const override
SupportsProfiling - Does this tool chain support -pg.
Definition Darwin.cpp:3479
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:3069
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:3472
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:2923
bool UseDwarfDebugFlags() const override
UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf compile unit information.
Definition Darwin.cpp:3437
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
SmallVector< InputInfo, 4 > InputInfoList
Definition Driver.h:50
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.
Definition TypeBase.h:905
const FunctionProtoType * T
llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS)
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:60
bool(*)(llvm::ArrayRef< const char * >, llvm::raw_ostream &, llvm::raw_ostream &, bool, bool) Driver
Definition Wasm.cpp:35
#define false
Definition stdbool.h:26
static constexpr OSEnvPair macCatalystToMacOSPair()
Returns the os-environment mapping pair that's used to represent the Mac Catalyst -> macOS version ma...
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
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