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