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