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