1//===--- Darwin.h - Darwin 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#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
10#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
11
12#include "clang/Basic/DarwinSDKInfo.h"
13#include "clang/Basic/LangOptions.h"
14#include "clang/Driver/CudaInstallationDetector.h"
15#include "clang/Driver/LazyDetector.h"
16#include "clang/Driver/RocmInstallationDetector.h"
17#include "clang/Driver/SyclInstallationDetector.h"
18#include "clang/Driver/Tool.h"
19#include "clang/Driver/ToolChain.h"
20#include "clang/Driver/XRayArgs.h"
21
22namespace clang {
23namespace driver {
24
25namespace toolchains {
26class MachO;
27} // end namespace toolchains
28
29namespace tools {
30
31namespace darwin {
32llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
33void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str,
34 const llvm::opt::ArgList &Args);
35
36class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
37 virtual void anchor();
38
39protected:
40 void AddMachOArch(const llvm::opt::ArgList &Args,
41 llvm::opt::ArgStringList &CmdArgs) const;
42
43 const toolchains::MachO &getMachOToolChain() const {
44 return reinterpret_cast<const toolchains::MachO &>(getToolChain());
45 }
46
47public:
48 MachOTool(const char *Name, const char *ShortName, const ToolChain &TC)
49 : Tool(Name, ShortName, TC) {}
50};
51
52class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
53public:
54 Assembler(const ToolChain &TC)
55 : MachOTool("darwin::Assembler", "assembler", TC) {}
56
57 bool hasIntegratedCPP() const override { return false; }
58
59 void ConstructJob(Compilation &C, const JobAction &JA,
60 const InputInfo &Output, const InputInfoList &Inputs,
61 const llvm::opt::ArgList &TCArgs,
62 const char *LinkingOutput) const override;
63};
64
65class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
66 bool NeedsTempPath(const InputInfoList &Inputs) const;
67 void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
68 llvm::opt::ArgStringList &CmdArgs,
69 const InputInfoList &Inputs, VersionTuple Version,
70 bool LinkerIsLLD, bool UsePlatformVersion) const;
71
72public:
73 Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {}
74
75 bool hasIntegratedCPP() const override { return false; }
76 bool isLinkJob() const override { return true; }
77
78 void ConstructJob(Compilation &C, const JobAction &JA,
79 const InputInfo &Output, const InputInfoList &Inputs,
80 const llvm::opt::ArgList &TCArgs,
81 const char *LinkingOutput) const override;
82};
83
84class LLVM_LIBRARY_VISIBILITY StaticLibTool : public MachOTool {
85public:
86 StaticLibTool(const ToolChain &TC)
87 : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {}
88
89 bool hasIntegratedCPP() const override { return false; }
90 bool isLinkJob() const override { return true; }
91
92 void ConstructJob(Compilation &C, const JobAction &JA,
93 const InputInfo &Output, const InputInfoList &Inputs,
94 const llvm::opt::ArgList &TCArgs,
95 const char *LinkingOutput) const override;
96};
97
98class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
99public:
100 Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
101
102 bool hasIntegratedCPP() const override { return false; }
103
104 void ConstructJob(Compilation &C, const JobAction &JA,
105 const InputInfo &Output, const InputInfoList &Inputs,
106 const llvm::opt::ArgList &TCArgs,
107 const char *LinkingOutput) const override;
108};
109
110class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
111public:
112 Dsymutil(const ToolChain &TC)
113 : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
114
115 bool hasIntegratedCPP() const override { return false; }
116 bool isDsymutilJob() const override { return true; }
117
118 void ConstructJob(Compilation &C, const JobAction &JA,
119 const InputInfo &Output, const InputInfoList &Inputs,
120 const llvm::opt::ArgList &TCArgs,
121 const char *LinkingOutput) const override;
122};
123
124class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
125public:
126 VerifyDebug(const ToolChain &TC)
127 : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
128
129 bool hasIntegratedCPP() const override { return false; }
130
131 void ConstructJob(Compilation &C, const JobAction &JA,
132 const InputInfo &Output, const InputInfoList &Inputs,
133 const llvm::opt::ArgList &TCArgs,
134 const char *LinkingOutput) const override;
135};
136} // end namespace darwin
137} // end namespace tools
138
139namespace toolchains {
140
141class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
142protected:
143 Tool *buildAssembler() const override;
144 Tool *buildLinker() const override;
145 Tool *buildStaticLibTool() const override;
146 Tool *getTool(Action::ActionClass AC) const override;
147
148 void
149 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
150 llvm::opt::ArgStringList &CC1Args, BoundArch BA,
151 Action::OffloadKind DeviceOffloadKind) const override;
152
153private:
154 mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
155 mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
156 mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
157
158 /// The version of the linker known to be available in the tool chain.
159 mutable std::optional<VersionTuple> LinkerVersion;
160
161public:
162 MachO(const Driver &D, const llvm::Triple &Triple,
163 const llvm::opt::ArgList &Args);
164 ~MachO() override;
165
166 /// @name MachO specific toolchain API
167 /// {
168
169 /// Get the "MachO" arch name for a particular compiler invocation. For
170 /// example, Apple treats different ARM variations as distinct architectures.
171 StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
172
173 /// Get the version of the linker known to be available for a particular
174 /// compiler invocation (via the `-mlinker-version=` arg).
175 VersionTuple getLinkerVersion(const llvm::opt::ArgList &Args) const;
176
177 /// Add the linker arguments to link the ARC runtime library.
178 virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
179 llvm::opt::ArgStringList &CmdArgs) const {}
180
181 /// Add the linker arguments to link the compiler runtime library.
182 ///
183 /// FIXME: This API is intended for use with embedded libraries only, and is
184 /// misleadingly named.
185 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
186 llvm::opt::ArgStringList &CmdArgs,
187 bool ForceLinkBuiltinRT = false) const;
188
189 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
190 llvm::opt::ArgStringList &CmdArgs) const {
191 }
192
193 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
194 llvm::opt::ArgStringList &CmdArgs) const {}
195
196 virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args,
197 llvm::opt::ArgStringList &CmdArgs) const {
198 }
199
200 virtual bool HasPlatformPrefix(const llvm::Triple &T) const { return false; }
201
202 virtual void AppendPlatformPrefix(SmallString<128> &Path,
203 const llvm::Triple &T) const {}
204
205 /// On some iOS platforms, kernel and kernel modules were built statically. Is
206 /// this such a target?
207 virtual bool isKernelStatic() const { return false; }
208
209 /// Is the target either iOS or an iOS simulator?
210 bool isTargetIOSBased() const { return false; }
211
212 /// Options to control how a runtime library is linked.
213 enum RuntimeLinkOptions : unsigned {
214 /// Link the library in even if it can't be found in the VFS.
215 RLO_AlwaysLink = 1 << 0,
216
217 /// Use the embedded runtime from the macho_embedded directory.
218 RLO_IsEmbedded = 1 << 1,
219
220 /// Emit rpaths for @executable_path as well as the resource directory.
221 RLO_AddRPath = 1 << 2,
222 };
223
224 /// Add a runtime library to the list of items to link.
225 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
226 llvm::opt::ArgStringList &CmdArgs, StringRef Component,
227 RuntimeLinkOptions Opts = RuntimeLinkOptions(),
228 bool IsShared = false) const;
229
230 /// Add any profiling runtime libraries that are needed. This is essentially a
231 /// MachO specific version of addProfileRT in Tools.cpp.
232 void addProfileRTLibs(const llvm::opt::ArgList &Args,
233 llvm::opt::ArgStringList &CmdArgs) const override {
234 // There aren't any profiling libs for embedded targets currently.
235 }
236
237 // Return the full path of the compiler-rt library on a non-Darwin MachO
238 // system. Those are under
239 // <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a).
240 std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
241 FileType Type = ToolChain::FT_Static,
242 bool IsFortran = false) const override;
243
244 /// }
245 /// @name ToolChain Implementation
246 /// {
247
248 types::ID LookupTypeForExtension(StringRef Ext) const override;
249
250 bool HasNativeLLVMSupport() const override;
251
252 llvm::opt::DerivedArgList *
253 TranslateArgs(const llvm::opt::DerivedArgList &Args, BoundArch BA,
254 Action::OffloadKind DeviceOffloadKind) const override;
255
256 bool IsBlocksDefault() const override {
257 // Always allow blocks on Apple; users interested in versioning are
258 // expected to use /usr/include/Block.h.
259 return true;
260 }
261
262 bool IsMathErrnoDefault() const override { return false; }
263
264 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
265
266 bool IsObjCNonFragileABIDefault() const override {
267 // Non-fragile ABI is default for everything but i386.
268 return getTriple().getArch() != llvm::Triple::x86;
269 }
270
271 bool UseObjCMixedDispatch() const override { return true; }
272
273 UnwindTableLevel
274 getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;
275
276 RuntimeLibType GetDefaultRuntimeLibType() const override {
277 return ToolChain::RLT_CompilerRT;
278 }
279
280 bool isPICDefault() const override;
281 bool isPIEDefault(const llvm::opt::ArgList &Args) const override;
282 bool isPICDefaultForced() const override;
283
284 bool SupportsProfiling() const override;
285
286 bool UseDwarfDebugFlags() const override;
287 std::string GetGlobalDebugPathRemapping() const override;
288
289 llvm::ExceptionHandling
290 GetExceptionModel(const llvm::opt::ArgList &Args) const override {
291 return llvm::ExceptionHandling::None;
292 }
293
294 virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
295 return "";
296 }
297
298 // Darwin toolchain uses legacy thin LTO API, which is not
299 // capable of unit splitting.
300 bool canSplitThinLTOUnit() const override { return false; }
301 /// }
302};
303
304/// Apple specific MachO extensions
305class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO {
306public:
307 AppleMachO(const Driver &D, const llvm::Triple &Triple,
308 const llvm::opt::ArgList &Args);
309 ~AppleMachO() override;
310
311 /// }
312 /// @name Apple Specific ToolChain Implementation
313 /// {
314 void
315 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
316 llvm::opt::ArgStringList &CC1Args) const override;
317
318 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
319 llvm::opt::ArgStringList &CC1Args) const override;
320 void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
321 llvm::opt::ArgStringList &CC1Args) const override;
322 void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
323 llvm::opt::ArgStringList &CC1Args) const override;
324
325 void AddClangCXXStdlibIncludeArgs(
326 const llvm::opt::ArgList &DriverArgs,
327 llvm::opt::ArgStringList &CC1Args) const override;
328 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
329 llvm::opt::ArgStringList &CmdArgs) const override;
330
331 void printVerboseInfo(raw_ostream &OS) const override;
332 /// }
333
334 LazyDetector<CudaInstallationDetector> CudaInstallation;
335 LazyDetector<RocmInstallationDetector> RocmInstallation;
336 LazyDetector<SYCLInstallationDetector> SYCLInstallation;
337
338protected:
339 llvm::SmallString<128>
340 GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const;
341
342private:
343 virtual void
344 AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
345 llvm::opt::ArgStringList &CC1Args) const;
346};
347
348/// Darwin - The base Darwin tool chain.
349class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
350public:
351 /// Whether the information on the target has been initialized.
352 //
353 // FIXME: This should be eliminated. What we want to do is make this part of
354 // the "default target for arguments" selection process, once we get out of
355 // the argument translation business.
356 mutable bool TargetInitialized;
357
358 // TODO: Are these useful? Can we use Triple::OSType/EnvironmentType instead?
359 enum DarwinPlatformKind {
360 MacOS,
361 IPhoneOS,
362 TvOS,
363 WatchOS,
364 DriverKit,
365 XROS,
366 Firmware,
367 };
368 enum DarwinEnvironmentKind {
369 NativeEnvironment,
370 Simulator,
371 MacCatalyst,
372 };
373
374 mutable DarwinPlatformKind TargetPlatform;
375 mutable DarwinEnvironmentKind TargetEnvironment;
376
377 /// The native OS version we are targeting.
378 mutable VersionTuple TargetVersion;
379 /// The OS version we are targeting as specified in the triple.
380 mutable VersionTuple OSTargetVersion;
381
382 /// The information about the darwin SDK that was used.
383 mutable std::optional<DarwinSDKInfo> SDKInfo;
384
385 /// The target variant triple that was specified (if any).
386 mutable std::optional<llvm::Triple> TargetVariantTriple;
387
388private:
389 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
390
391 void VerifyTripleForSDK(const llvm::opt::ArgList &Args,
392 const llvm::Triple &Triple) const;
393
394protected:
395 /// Lazily initialize the target platform from the triple when
396 /// AddDeploymentTarget has not run yet (e.g. when Darwin is used as
397 /// a host toolchain for device offloading).
398 void ensureTargetInitialized() const;
399
400public:
401 Darwin(const Driver &D, const llvm::Triple &Triple,
402 const llvm::opt::ArgList &Args);
403 ~Darwin() override;
404
405 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
406 BoundArch BA,
407 types::ID InputType) const override;
408
409 /// @name Darwin Specific Toolchain Implementation
410 /// {
411
412 void addMinVersionArgs(const llvm::opt::ArgList &Args,
413 llvm::opt::ArgStringList &CmdArgs) const override;
414
415 void addPlatformVersionArgs(const llvm::opt::ArgList &Args,
416 llvm::opt::ArgStringList &CmdArgs) const override;
417
418 void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
419 llvm::opt::ArgStringList &CmdArgs) const override;
420
421 bool isKernelStatic() const override {
422 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(V0: 6, V1: 0)) &&
423 !isTargetWatchOS() && !isTargetDriverKit());
424 }
425
426 void addProfileRTLibs(const llvm::opt::ArgList &Args,
427 llvm::opt::ArgStringList &CmdArgs) const override;
428
429 // Return the full path of the compiler-rt library on a Darwin MachO system.
430 // Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a).
431 std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
432 FileType Type = ToolChain::FT_Static,
433 bool IsFortran = false) const override;
434
435protected:
436 /// }
437 /// @name Darwin specific Toolchain functions
438 /// {
439
440 // FIXME: Eliminate these ...Target functions and derive separate tool chains
441 // for these targets and put version in constructor.
442 void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
443 unsigned Major, unsigned Minor, unsigned Micro,
444 VersionTuple NativeTargetVersion) const {
445 // FIXME: For now, allow reinitialization as long as values don't
446 // change. This will go away when we move away from argument translation.
447 if (TargetInitialized && TargetPlatform == Platform &&
448 TargetEnvironment == Environment &&
449 (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) ==
450 VersionTuple(Major, Minor, Micro))
451 return;
452
453 assert(!TargetInitialized && "Target already initialized!");
454 TargetInitialized = true;
455 TargetPlatform = Platform;
456 TargetEnvironment = Environment;
457 TargetVersion = VersionTuple(Major, Minor, Micro);
458 if (Environment == Simulator)
459 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
460 else if (Environment == MacCatalyst) {
461 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI);
462 TargetVersion = NativeTargetVersion;
463 OSTargetVersion = VersionTuple(Major, Minor, Micro);
464 }
465 }
466
467public:
468 bool isTargetIPhoneOS() const {
469 assert(TargetInitialized && "Target not initialized!");
470 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
471 TargetEnvironment == NativeEnvironment;
472 }
473
474 bool isTargetIOSSimulator() const {
475 assert(TargetInitialized && "Target not initialized!");
476 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
477 TargetEnvironment == Simulator;
478 }
479
480 bool isTargetIOSBased() const {
481 assert(TargetInitialized && "Target not initialized!");
482 return isTargetIPhoneOS() || isTargetIOSSimulator();
483 }
484
485 bool isTargetXROSDevice() const {
486 return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment;
487 }
488
489 bool isTargetXROSSimulator() const {
490 return TargetPlatform == XROS && TargetEnvironment == Simulator;
491 }
492
493 bool isTargetXROS() const { return TargetPlatform == XROS; }
494
495 bool isTargetTvOS() const {
496 assert(TargetInitialized && "Target not initialized!");
497 return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
498 }
499
500 bool isTargetTvOSSimulator() const {
501 assert(TargetInitialized && "Target not initialized!");
502 return TargetPlatform == TvOS && TargetEnvironment == Simulator;
503 }
504
505 bool isTargetTvOSBased() const {
506 assert(TargetInitialized && "Target not initialized!");
507 return TargetPlatform == TvOS;
508 }
509
510 bool isTargetWatchOS() const {
511 assert(TargetInitialized && "Target not initialized!");
512 return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
513 }
514
515 bool isTargetWatchOSSimulator() const {
516 assert(TargetInitialized && "Target not initialized!");
517 return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
518 }
519
520 bool isTargetWatchOSBased() const {
521 assert(TargetInitialized && "Target not initialized!");
522 return TargetPlatform == WatchOS;
523 }
524
525 bool isTargetDriverKit() const {
526 assert(TargetInitialized && "Target not initialized!");
527 return TargetPlatform == DriverKit;
528 }
529
530 bool isTargetFirmware() const { return TargetPlatform == Firmware; }
531
532 bool isTargetMacCatalyst() const {
533 return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
534 }
535
536 bool isTargetMacOS() const {
537 assert(TargetInitialized && "Target not initialized!");
538 return TargetPlatform == MacOS;
539 }
540
541 bool isTargetMacOSBased() const {
542 assert(TargetInitialized && "Target not initialized!");
543 return TargetPlatform == MacOS || isTargetMacCatalyst();
544 }
545
546 bool isTargetAppleSiliconMac() const {
547 assert(TargetInitialized && "Target not initialized!");
548 return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64;
549 }
550
551 bool isTargetInitialized() const { return TargetInitialized; }
552
553 /// The version of the OS that's used by the OS specified in the target
554 /// triple. It might be different from the actual target OS on which the
555 /// program will run, e.g. MacCatalyst code runs on a macOS target, but its
556 /// target triple is iOS.
557 VersionTuple getTripleTargetVersion() const {
558 assert(TargetInitialized && "Target not initialized!");
559 return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion;
560 }
561
562 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
563 unsigned V2 = 0) const {
564 assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
565 return TargetVersion < VersionTuple(V0, V1, V2);
566 }
567
568 /// Returns true if the minimum supported macOS version for the slice that's
569 /// being built is less than the specified version. If there's no minimum
570 /// supported macOS version, the deployment target version is compared to the
571 /// specifed version instead.
572 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
573 assert(isTargetMacOSBased() &&
574 (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) &&
575 "Unexpected call for non OS X target!");
576 // The effective triple might not be initialized yet, so construct a
577 // pseudo-effective triple to get the minimum supported OS version.
578 VersionTuple MinVers =
579 llvm::Triple(getTriple().getArchName(), "apple", "macos")
580 .getMinimumSupportedOSVersion();
581 return (!MinVers.empty() && MinVers > TargetVersion
582 ? MinVers
583 : TargetVersion) < VersionTuple(V0, V1, V2);
584 }
585
586protected:
587 /// Return true if c++17 aligned allocation/deallocation functions are not
588 /// implemented in the c++ standard library of the deployment target we are
589 /// targeting.
590 bool isAlignedAllocationUnavailable() const;
591
592 /// Return true if c++14 sized deallocation functions are not implemented in
593 /// the c++ standard library of the deployment target we are targeting.
594 bool isSizedDeallocationUnavailable() const;
595
596 void
597 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
598 llvm::opt::ArgStringList &CC1Args, BoundArch BA,
599 Action::OffloadKind DeviceOffloadKind) const override;
600
601 void addClangCC1ASTargetOptions(
602 const llvm::opt::ArgList &Args,
603 llvm::opt::ArgStringList &CC1ASArgs) const override;
604
605 StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
606
607public:
608 static StringRef getSDKName(StringRef isysroot);
609
610 /// }
611 /// @name ToolChain Implementation
612 /// {
613
614 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
615 // most development is done against SDKs, so compiling for a different
616 // architecture should not get any special treatment.
617 bool isCrossCompiling() const override { return false; }
618
619 llvm::opt::DerivedArgList *
620 TranslateArgs(const llvm::opt::DerivedArgList &Args, BoundArch BA,
621 Action::OffloadKind DeviceOffloadKind) const override;
622
623 CXXStdlibType GetDefaultCXXStdlibType() const override;
624 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
625 bool hasBlocksRuntime() const override;
626
627 bool UseObjCMixedDispatch() const override {
628 // This is only used with the non-fragile ABI and non-legacy dispatch.
629
630 // Mixed dispatch is used everywhere except OS X before 10.6.
631 return !(isTargetMacOSBased() && isMacosxVersionLT(V0: 10, V1: 6));
632 }
633
634 LangOptions::StackProtectorMode
635 GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
636 // Stack protectors default to on for user code on 10.5,
637 // and for everything in 10.6 and beyond
638 if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() ||
639 isTargetXROS())
640 return LangOptions::SSPOn;
641 else if (isTargetMacOSBased() && !isMacosxVersionLT(V0: 10, V1: 6))
642 return LangOptions::SSPOn;
643 else if (isTargetMacOSBased() && !isMacosxVersionLT(V0: 10, V1: 5) && !KernelOrKext)
644 return LangOptions::SSPOn;
645
646 return LangOptions::SSPOff;
647 }
648
649 void CheckObjCARC() const override;
650
651 llvm::ExceptionHandling GetExceptionModel(
652 const llvm::opt::ArgList &Args) const override;
653
654 bool SupportsEmbeddedBitcode() const override;
655
656 SanitizerMask
657 getSupportedSanitizers(BoundArch BA,
658 Action::OffloadKind DeviceOffloadKind) const override;
659};
660
661/// DarwinClang - The Darwin toolchain used by Clang.
662class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
663public:
664 DarwinClang(const Driver &D, const llvm::Triple &Triple,
665 const llvm::opt::ArgList &Args);
666
667 /// @name Apple ToolChain Implementation
668 /// {
669
670 void
671 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
672 llvm::opt::ArgStringList &CC1Args) const override;
673
674 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
675
676 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
677 llvm::opt::ArgStringList &CmdArgs,
678 bool ForceLinkBuiltinRT = false) const override;
679
680 void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
681 llvm::opt::ArgStringList &CmdArgs) const override;
682
683 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
684
685 void
686 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
687 llvm::opt::ArgStringList &CC1Args, BoundArch BA,
688 Action::OffloadKind DeviceOffloadKind) const override;
689
690 void AddLinkARCArgs(const llvm::opt::ArgList &Args,
691 llvm::opt::ArgStringList &CmdArgs) const override;
692
693 bool HasPlatformPrefix(const llvm::Triple &T) const override;
694
695 void AppendPlatformPrefix(SmallString<128> &Path,
696 const llvm::Triple &T) const override;
697
698 unsigned GetDefaultDwarfVersion() const override;
699 // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
700 // Darwin defaults to standalone/full debug info.
701 bool GetDefaultStandaloneDebug() const override { return true; }
702 llvm::DebuggerKind getDefaultDebuggerTuning() const override {
703 return llvm::DebuggerKind::LLDB;
704 }
705
706 bool getDefaultDebugSimpleTemplateNames() const override;
707
708 /// }
709
710private:
711 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
712 llvm::opt::ArgStringList &CmdArgs,
713 StringRef Sanitizer,
714 bool shared = true) const;
715
716 void
717 AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
718 llvm::opt::ArgStringList &CC1Args) const override;
719
720 bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
721 llvm::opt::ArgStringList &CC1Args,
722 llvm::SmallString<128> Base,
723 llvm::StringRef Version,
724 llvm::StringRef ArchDir,
725 llvm::StringRef BitDir) const;
726};
727
728} // end namespace toolchains
729} // end namespace driver
730} // end namespace clang
731
732#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
733