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