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