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/DarwinSDKInfo.h"
15 #include "clang/Basic/LangOptions.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 
189   /// Add a runtime library to the list of items to link.
190   void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
191                          llvm::opt::ArgStringList &CmdArgs, StringRef Component,
192                          RuntimeLinkOptions Opts = RuntimeLinkOptions(),
193                          bool IsShared = false) const;
194 
195   /// Add any profiling runtime libraries that are needed. This is essentially a
196   /// MachO specific version of addProfileRT in Tools.cpp.
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)197   void addProfileRTLibs(const llvm::opt::ArgList &Args,
198                         llvm::opt::ArgStringList &CmdArgs) const override {
199     // There aren't any profiling libs for embedded targets currently.
200   }
201 
202   /// }
203   /// @name ToolChain Implementation
204   /// {
205 
206   types::ID LookupTypeForExtension(StringRef Ext) const override;
207 
208   bool HasNativeLLVMSupport() const override;
209 
210   llvm::opt::DerivedArgList *
211   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
212                 Action::OffloadKind DeviceOffloadKind) const override;
213 
IsBlocksDefault()214   bool IsBlocksDefault() const override {
215     // Always allow blocks on Apple; users interested in versioning are
216     // expected to use /usr/include/Block.h.
217     return true;
218   }
IsIntegratedAssemblerDefault()219   bool IsIntegratedAssemblerDefault() const override {
220     // Default integrated assembler to on for Apple's MachO targets.
221     return true;
222   }
223 
IsMathErrnoDefault()224   bool IsMathErrnoDefault() const override { return false; }
225 
IsEncodeExtendedBlockSignatureDefault()226   bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
227 
IsObjCNonFragileABIDefault()228   bool IsObjCNonFragileABIDefault() const override {
229     // Non-fragile ABI is default for everything but i386.
230     return getTriple().getArch() != llvm::Triple::x86;
231   }
232 
UseObjCMixedDispatch()233   bool UseObjCMixedDispatch() const override { return true; }
234 
235   bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
236 
GetDefaultRuntimeLibType()237   RuntimeLibType GetDefaultRuntimeLibType() const override {
238     return ToolChain::RLT_CompilerRT;
239   }
240 
241   bool isPICDefault() const override;
242   bool isPIEDefault() const override;
243   bool isPICDefaultForced() const override;
244 
245   bool SupportsProfiling() const override;
246 
247   bool UseDwarfDebugFlags() const override;
248 
249   llvm::ExceptionHandling
GetExceptionModel(const llvm::opt::ArgList & Args)250   GetExceptionModel(const llvm::opt::ArgList &Args) const override {
251     return llvm::ExceptionHandling::None;
252   }
253 
254   virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
255     return "";
256   }
257 
258   // Darwin toolchain uses legacy thin LTO API, which is not
259   // capable of unit splitting.
canSplitThinLTOUnit()260   bool canSplitThinLTOUnit() const override { return false; }
261   /// }
262 };
263 
264 /// Darwin - The base Darwin tool chain.
265 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
266 public:
267   /// Whether the information on the target has been initialized.
268   //
269   // FIXME: This should be eliminated. What we want to do is make this part of
270   // the "default target for arguments" selection process, once we get out of
271   // the argument translation business.
272   mutable bool TargetInitialized;
273 
274   enum DarwinPlatformKind {
275     MacOS,
276     IPhoneOS,
277     TvOS,
278     WatchOS,
279     LastDarwinPlatform = WatchOS
280   };
281   enum DarwinEnvironmentKind {
282     NativeEnvironment,
283     Simulator,
284     MacCatalyst,
285   };
286 
287   mutable DarwinPlatformKind TargetPlatform;
288   mutable DarwinEnvironmentKind TargetEnvironment;
289 
290   /// The native OS version we are targeting.
291   mutable VersionTuple TargetVersion;
292   /// The OS version we are targeting as specified in the triple.
293   mutable VersionTuple OSTargetVersion;
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,VersionTuple NativeTargetVersion)339   void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
340                  unsigned Major, unsigned Minor, unsigned Micro,
341                  VersionTuple NativeTargetVersion) const {
342     // FIXME: For now, allow reinitialization as long as values don't
343     // change. This will go away when we move away from argument translation.
344     if (TargetInitialized && TargetPlatform == Platform &&
345         TargetEnvironment == Environment &&
346         (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) ==
347             VersionTuple(Major, Minor, Micro))
348       return;
349 
350     assert(!TargetInitialized && "Target already initialized!");
351     TargetInitialized = true;
352     TargetPlatform = Platform;
353     TargetEnvironment = Environment;
354     TargetVersion = VersionTuple(Major, Minor, Micro);
355     if (Environment == Simulator)
356       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
357     else if (Environment == MacCatalyst) {
358       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI);
359       TargetVersion = NativeTargetVersion;
360       OSTargetVersion = VersionTuple(Major, Minor, Micro);
361     }
362   }
363 
364 public:
isTargetIPhoneOS()365   bool isTargetIPhoneOS() const {
366     assert(TargetInitialized && "Target not initialized!");
367     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
368            TargetEnvironment == NativeEnvironment;
369   }
370 
isTargetIOSSimulator()371   bool isTargetIOSSimulator() const {
372     assert(TargetInitialized && "Target not initialized!");
373     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
374            TargetEnvironment == Simulator;
375   }
376 
isTargetIOSBased()377   bool isTargetIOSBased() const {
378     assert(TargetInitialized && "Target not initialized!");
379     return isTargetIPhoneOS() || isTargetIOSSimulator();
380   }
381 
isTargetTvOS()382   bool isTargetTvOS() const {
383     assert(TargetInitialized && "Target not initialized!");
384     return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
385   }
386 
isTargetTvOSSimulator()387   bool isTargetTvOSSimulator() const {
388     assert(TargetInitialized && "Target not initialized!");
389     return TargetPlatform == TvOS && TargetEnvironment == Simulator;
390   }
391 
isTargetTvOSBased()392   bool isTargetTvOSBased() const {
393     assert(TargetInitialized && "Target not initialized!");
394     return TargetPlatform == TvOS;
395   }
396 
isTargetWatchOS()397   bool isTargetWatchOS() const {
398     assert(TargetInitialized && "Target not initialized!");
399     return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
400   }
401 
isTargetWatchOSSimulator()402   bool isTargetWatchOSSimulator() const {
403     assert(TargetInitialized && "Target not initialized!");
404     return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
405   }
406 
isTargetWatchOSBased()407   bool isTargetWatchOSBased() const {
408     assert(TargetInitialized && "Target not initialized!");
409     return TargetPlatform == WatchOS;
410   }
411 
isTargetMacCatalyst()412   bool isTargetMacCatalyst() const {
413     return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
414   }
415 
isTargetMacOS()416   bool isTargetMacOS() const {
417     assert(TargetInitialized && "Target not initialized!");
418     return TargetPlatform == MacOS;
419   }
420 
isTargetMacOSBased()421   bool isTargetMacOSBased() const {
422     assert(TargetInitialized && "Target not initialized!");
423     return TargetPlatform == MacOS || isTargetMacCatalyst();
424   }
425 
isTargetAppleSiliconMac()426   bool isTargetAppleSiliconMac() const {
427     assert(TargetInitialized && "Target not initialized!");
428     return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64;
429   }
430 
isTargetInitialized()431   bool isTargetInitialized() const { return TargetInitialized; }
432 
433   /// The version of the OS that's used by the OS specified in the target
434   /// triple. It might be different from the actual target OS on which the
435   /// program will run, e.g. MacCatalyst code runs on a macOS target, but its
436   /// target triple is iOS.
getTripleTargetVersion()437   VersionTuple getTripleTargetVersion() const {
438     assert(TargetInitialized && "Target not initialized!");
439     return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion;
440   }
441 
442   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
443                            unsigned V2 = 0) const {
444     assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
445     return TargetVersion < VersionTuple(V0, V1, V2);
446   }
447 
448   /// Returns true if the minimum supported macOS version for the slice that's
449   /// being built is less than the specified version. If there's no minimum
450   /// supported macOS version, the deployment target version is compared to the
451   /// specifed version instead.
452   bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
453     assert(isTargetMacOSBased() &&
454            (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) &&
455            "Unexpected call for non OS X target!");
456     // The effective triple might not be initialized yet, so construct a
457     // pseudo-effective triple to get the minimum supported OS version.
458     VersionTuple MinVers =
459         llvm::Triple(getTriple().getArchName(), "apple", "macos")
460             .getMinimumSupportedOSVersion();
461     return (!MinVers.empty() && MinVers > TargetVersion
462                 ? MinVers
463                 : TargetVersion) < VersionTuple(V0, V1, V2);
464   }
465 
466 protected:
467   /// Return true if c++17 aligned allocation/deallocation functions are not
468   /// implemented in the c++ standard library of the deployment target we are
469   /// targeting.
470   bool isAlignedAllocationUnavailable() const;
471 
472   void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
473                              llvm::opt::ArgStringList &CC1Args,
474                              Action::OffloadKind DeviceOffloadKind) const override;
475 
476   StringRef getPlatformFamily() const;
477   StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
478 
479 public:
480   static StringRef getSDKName(StringRef isysroot);
481 
482   /// }
483   /// @name ToolChain Implementation
484   /// {
485 
486   // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
487   // most development is done against SDKs, so compiling for a different
488   // architecture should not get any special treatment.
isCrossCompiling()489   bool isCrossCompiling() const override { return false; }
490 
491   llvm::opt::DerivedArgList *
492   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
493                 Action::OffloadKind DeviceOffloadKind) const override;
494 
495   CXXStdlibType GetDefaultCXXStdlibType() const override;
496   ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
497   bool hasBlocksRuntime() const override;
498 
499   void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
500                           llvm::opt::ArgStringList &CC1Args) const override;
501   void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
502                          llvm::opt::ArgStringList &CC1Args) const override;
503 
UseObjCMixedDispatch()504   bool UseObjCMixedDispatch() const override {
505     // This is only used with the non-fragile ABI and non-legacy dispatch.
506 
507     // Mixed dispatch is used everywhere except OS X before 10.6.
508     return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6));
509   }
510 
511   LangOptions::StackProtectorMode
GetDefaultStackProtectorLevel(bool KernelOrKext)512   GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
513     // Stack protectors default to on for user code on 10.5,
514     // and for everything in 10.6 and beyond
515     if (isTargetIOSBased() || isTargetWatchOSBased())
516       return LangOptions::SSPOn;
517     else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))
518       return LangOptions::SSPOn;
519     else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
520       return LangOptions::SSPOn;
521 
522     return LangOptions::SSPOff;
523   }
524 
525   void CheckObjCARC() const override;
526 
527   llvm::ExceptionHandling GetExceptionModel(
528       const llvm::opt::ArgList &Args) const override;
529 
530   bool SupportsEmbeddedBitcode() const override;
531 
532   SanitizerMask getSupportedSanitizers() const override;
533 
534   void printVerboseInfo(raw_ostream &OS) const override;
535 };
536 
537 /// DarwinClang - The Darwin toolchain used by Clang.
538 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
539 public:
540   DarwinClang(const Driver &D, const llvm::Triple &Triple,
541               const llvm::opt::ArgList &Args);
542 
543   /// @name Apple ToolChain Implementation
544   /// {
545 
546   RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
547 
548   void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
549                              llvm::opt::ArgStringList &CmdArgs,
550                              bool ForceLinkBuiltinRT = false) const override;
551 
552   void AddClangCXXStdlibIncludeArgs(
553       const llvm::opt::ArgList &DriverArgs,
554       llvm::opt::ArgStringList &CC1Args) const override;
555 
556   void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
557                                  llvm::opt::ArgStringList &CC1Args) const override;
558 
559   void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
560                            llvm::opt::ArgStringList &CmdArgs) const override;
561 
562   void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
563                         llvm::opt::ArgStringList &CmdArgs) const override;
564 
565   void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
566 
567   void AddLinkARCArgs(const llvm::opt::ArgList &Args,
568                       llvm::opt::ArgStringList &CmdArgs) const override;
569 
570   unsigned GetDefaultDwarfVersion() const override;
571   // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
572   // Darwin defaults to standalone/full debug info.
GetDefaultStandaloneDebug()573   bool GetDefaultStandaloneDebug() const override { return true; }
getDefaultDebuggerTuning()574   llvm::DebuggerKind getDefaultDebuggerTuning() const override {
575     return llvm::DebuggerKind::LLDB;
576   }
577 
578   /// }
579 
580 private:
581   void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
582                                llvm::opt::ArgStringList &CmdArgs,
583                                StringRef Sanitizer,
584                                bool shared = true) const;
585 
586   bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
587                                    llvm::opt::ArgStringList &CC1Args,
588                                    llvm::SmallString<128> Base,
589                                    llvm::StringRef Version,
590                                    llvm::StringRef ArchDir,
591                                    llvm::StringRef BitDir) const;
592 
593   llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const;
594 };
595 
596 } // end namespace toolchains
597 } // end namespace driver
598 } // end namespace clang
599 
600 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
601