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