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