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