xref: /openbsd-src/gnu/llvm/clang/lib/Driver/ToolChains/Darwin.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
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, VersionTuple Version,
67                    bool LinkerIsLLD) 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 StaticLibTool : public MachOTool {
82 public:
StaticLibTool(const ToolChain & TC)83   StaticLibTool(const ToolChain &TC)
84       : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {}
85 
hasIntegratedCPP()86   bool hasIntegratedCPP() const override { return false; }
isLinkJob()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:
Lipo(const ToolChain & TC)97   Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
98 
hasIntegratedCPP()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:
Dsymutil(const ToolChain & TC)109   Dsymutil(const ToolChain &TC)
110       : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
111 
hasIntegratedCPP()112   bool hasIntegratedCPP() const override { return false; }
isDsymutilJob()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:
VerifyDebug(const ToolChain & TC)123   VerifyDebug(const ToolChain &TC)
124       : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
125 
hasIntegratedCPP()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.
AddLinkARCArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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 
addStartObjectFileArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)181   virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
182                                       llvm::opt::ArgStringList &CmdArgs) const {
183   }
184 
addMinVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)185   virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
186                                  llvm::opt::ArgStringList &CmdArgs) const {}
187 
addPlatformVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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?
isKernelStatic()194   virtual bool isKernelStatic() const { return false; }
195 
196   /// Is the target either iOS or an iOS simulator?
isTargetIOSBased()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.
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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 
IsBlocksDefault()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   }
IsIntegratedAssemblerDefault()241   bool IsIntegratedAssemblerDefault() const override {
242     // Default integrated assembler to on for Apple's MachO targets.
243     return true;
244   }
245 
IsMathErrnoDefault()246   bool IsMathErrnoDefault() const override { return false; }
247 
IsEncodeExtendedBlockSignatureDefault()248   bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
249 
IsObjCNonFragileABIDefault()250   bool IsObjCNonFragileABIDefault() const override {
251     // Non-fragile ABI is default for everything but i386.
252     return getTriple().getArch() != llvm::Triple::x86;
253   }
254 
UseObjCMixedDispatch()255   bool UseObjCMixedDispatch() const override { return true; }
256 
257   UnwindTableLevel
258   getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;
259 
GetDefaultRuntimeLibType()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
GetExceptionModel(const llvm::opt::ArgList & Args)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.
canSplitThinLTOUnit()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 
isKernelStatic()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.
setTarget(DarwinPlatformKind Platform,DarwinEnvironmentKind Environment,unsigned Major,unsigned Minor,unsigned Micro,VersionTuple NativeTargetVersion)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:
isTargetIPhoneOS()393   bool isTargetIPhoneOS() const {
394     assert(TargetInitialized && "Target not initialized!");
395     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
396            TargetEnvironment == NativeEnvironment;
397   }
398 
isTargetIOSSimulator()399   bool isTargetIOSSimulator() const {
400     assert(TargetInitialized && "Target not initialized!");
401     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
402            TargetEnvironment == Simulator;
403   }
404 
isTargetIOSBased()405   bool isTargetIOSBased() const {
406     assert(TargetInitialized && "Target not initialized!");
407     return isTargetIPhoneOS() || isTargetIOSSimulator();
408   }
409 
isTargetTvOS()410   bool isTargetTvOS() const {
411     assert(TargetInitialized && "Target not initialized!");
412     return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
413   }
414 
isTargetTvOSSimulator()415   bool isTargetTvOSSimulator() const {
416     assert(TargetInitialized && "Target not initialized!");
417     return TargetPlatform == TvOS && TargetEnvironment == Simulator;
418   }
419 
isTargetTvOSBased()420   bool isTargetTvOSBased() const {
421     assert(TargetInitialized && "Target not initialized!");
422     return TargetPlatform == TvOS;
423   }
424 
isTargetWatchOS()425   bool isTargetWatchOS() const {
426     assert(TargetInitialized && "Target not initialized!");
427     return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
428   }
429 
isTargetWatchOSSimulator()430   bool isTargetWatchOSSimulator() const {
431     assert(TargetInitialized && "Target not initialized!");
432     return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
433   }
434 
isTargetWatchOSBased()435   bool isTargetWatchOSBased() const {
436     assert(TargetInitialized && "Target not initialized!");
437     return TargetPlatform == WatchOS;
438   }
439 
isTargetDriverKit()440   bool isTargetDriverKit() const {
441     assert(TargetInitialized && "Target not initialized!");
442     return TargetPlatform == DriverKit;
443   }
444 
isTargetMacCatalyst()445   bool isTargetMacCatalyst() const {
446     return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
447   }
448 
isTargetMacOS()449   bool isTargetMacOS() const {
450     assert(TargetInitialized && "Target not initialized!");
451     return TargetPlatform == MacOS;
452   }
453 
isTargetMacOSBased()454   bool isTargetMacOSBased() const {
455     assert(TargetInitialized && "Target not initialized!");
456     return TargetPlatform == MacOS || isTargetMacCatalyst();
457   }
458 
isTargetAppleSiliconMac()459   bool isTargetAppleSiliconMac() const {
460     assert(TargetInitialized && "Target not initialized!");
461     return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64;
462   }
463 
isTargetInitialized()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.
getTripleTargetVersion()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.
isCrossCompiling()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 
UseObjCMixedDispatch()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
GetDefaultStackProtectorLevel(bool KernelOrKext)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.
GetDefaultStandaloneDebug()610   bool GetDefaultStandaloneDebug() const override { return true; }
getDefaultDebuggerTuning()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