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 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   bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
258 
GetDefaultRuntimeLibType()259   RuntimeLibType GetDefaultRuntimeLibType() const override {
260     return ToolChain::RLT_CompilerRT;
261   }
262 
263   bool isPICDefault() const override;
264   bool isPIEDefault(const llvm::opt::ArgList &Args) const override;
265   bool isPICDefaultForced() const override;
266 
267   bool SupportsProfiling() const override;
268 
269   bool UseDwarfDebugFlags() const override;
270   std::string GetGlobalDebugPathRemapping() const override;
271 
272   llvm::ExceptionHandling
GetExceptionModel(const llvm::opt::ArgList & Args)273   GetExceptionModel(const llvm::opt::ArgList &Args) const override {
274     return llvm::ExceptionHandling::None;
275   }
276 
277   virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
278     return "";
279   }
280 
281   // Darwin toolchain uses legacy thin LTO API, which is not
282   // capable of unit splitting.
canSplitThinLTOUnit()283   bool canSplitThinLTOUnit() const override { return false; }
284   /// }
285 };
286 
287 /// Darwin - The base Darwin tool chain.
288 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
289 public:
290   /// Whether the information on the target has been initialized.
291   //
292   // FIXME: This should be eliminated. What we want to do is make this part of
293   // the "default target for arguments" selection process, once we get out of
294   // the argument translation business.
295   mutable bool TargetInitialized;
296 
297   enum DarwinPlatformKind {
298     MacOS,
299     IPhoneOS,
300     TvOS,
301     WatchOS,
302     DriverKit,
303     LastDarwinPlatform = DriverKit
304   };
305   enum DarwinEnvironmentKind {
306     NativeEnvironment,
307     Simulator,
308     MacCatalyst,
309   };
310 
311   mutable DarwinPlatformKind TargetPlatform;
312   mutable DarwinEnvironmentKind TargetEnvironment;
313 
314   /// The native OS version we are targeting.
315   mutable VersionTuple TargetVersion;
316   /// The OS version we are targeting as specified in the triple.
317   mutable VersionTuple OSTargetVersion;
318 
319   /// The information about the darwin SDK that was used.
320   mutable Optional<DarwinSDKInfo> SDKInfo;
321 
322   /// The target variant triple that was specified (if any).
323   mutable Optional<llvm::Triple> TargetVariantTriple;
324 
325   CudaInstallationDetector CudaInstallation;
326   RocmInstallationDetector RocmInstallation;
327 
328 private:
329   void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
330 
331 public:
332   Darwin(const Driver &D, const llvm::Triple &Triple,
333          const llvm::opt::ArgList &Args);
334   ~Darwin() override;
335 
336   std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
337                                           types::ID InputType) const override;
338 
339   /// @name Apple Specific Toolchain Implementation
340   /// {
341 
342   void addMinVersionArgs(const llvm::opt::ArgList &Args,
343                          llvm::opt::ArgStringList &CmdArgs) const override;
344 
345   void addPlatformVersionArgs(const llvm::opt::ArgList &Args,
346                               llvm::opt::ArgStringList &CmdArgs) const override;
347 
348   void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
349                               llvm::opt::ArgStringList &CmdArgs) const override;
350 
isKernelStatic()351   bool isKernelStatic() const override {
352     return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
353             !isTargetWatchOS() && !isTargetDriverKit());
354   }
355 
356   void addProfileRTLibs(const llvm::opt::ArgList &Args,
357                         llvm::opt::ArgStringList &CmdArgs) const override;
358 
359 protected:
360   /// }
361   /// @name Darwin specific Toolchain functions
362   /// {
363 
364   // FIXME: Eliminate these ...Target functions and derive separate tool chains
365   // for these targets and put version in constructor.
setTarget(DarwinPlatformKind Platform,DarwinEnvironmentKind Environment,unsigned Major,unsigned Minor,unsigned Micro,VersionTuple NativeTargetVersion)366   void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
367                  unsigned Major, unsigned Minor, unsigned Micro,
368                  VersionTuple NativeTargetVersion) const {
369     // FIXME: For now, allow reinitialization as long as values don't
370     // change. This will go away when we move away from argument translation.
371     if (TargetInitialized && TargetPlatform == Platform &&
372         TargetEnvironment == Environment &&
373         (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) ==
374             VersionTuple(Major, Minor, Micro))
375       return;
376 
377     assert(!TargetInitialized && "Target already initialized!");
378     TargetInitialized = true;
379     TargetPlatform = Platform;
380     TargetEnvironment = Environment;
381     TargetVersion = VersionTuple(Major, Minor, Micro);
382     if (Environment == Simulator)
383       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
384     else if (Environment == MacCatalyst) {
385       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI);
386       TargetVersion = NativeTargetVersion;
387       OSTargetVersion = VersionTuple(Major, Minor, Micro);
388     }
389   }
390 
391 public:
isTargetIPhoneOS()392   bool isTargetIPhoneOS() const {
393     assert(TargetInitialized && "Target not initialized!");
394     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
395            TargetEnvironment == NativeEnvironment;
396   }
397 
isTargetIOSSimulator()398   bool isTargetIOSSimulator() const {
399     assert(TargetInitialized && "Target not initialized!");
400     return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
401            TargetEnvironment == Simulator;
402   }
403 
isTargetIOSBased()404   bool isTargetIOSBased() const {
405     assert(TargetInitialized && "Target not initialized!");
406     return isTargetIPhoneOS() || isTargetIOSSimulator();
407   }
408 
isTargetTvOS()409   bool isTargetTvOS() const {
410     assert(TargetInitialized && "Target not initialized!");
411     return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
412   }
413 
isTargetTvOSSimulator()414   bool isTargetTvOSSimulator() const {
415     assert(TargetInitialized && "Target not initialized!");
416     return TargetPlatform == TvOS && TargetEnvironment == Simulator;
417   }
418 
isTargetTvOSBased()419   bool isTargetTvOSBased() const {
420     assert(TargetInitialized && "Target not initialized!");
421     return TargetPlatform == TvOS;
422   }
423 
isTargetWatchOS()424   bool isTargetWatchOS() const {
425     assert(TargetInitialized && "Target not initialized!");
426     return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
427   }
428 
isTargetWatchOSSimulator()429   bool isTargetWatchOSSimulator() const {
430     assert(TargetInitialized && "Target not initialized!");
431     return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
432   }
433 
isTargetWatchOSBased()434   bool isTargetWatchOSBased() const {
435     assert(TargetInitialized && "Target not initialized!");
436     return TargetPlatform == WatchOS;
437   }
438 
isTargetDriverKit()439   bool isTargetDriverKit() const {
440     assert(TargetInitialized && "Target not initialized!");
441     return TargetPlatform == DriverKit;
442   }
443 
isTargetMacCatalyst()444   bool isTargetMacCatalyst() const {
445     return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
446   }
447 
isTargetMacOS()448   bool isTargetMacOS() const {
449     assert(TargetInitialized && "Target not initialized!");
450     return TargetPlatform == MacOS;
451   }
452 
isTargetMacOSBased()453   bool isTargetMacOSBased() const {
454     assert(TargetInitialized && "Target not initialized!");
455     return TargetPlatform == MacOS || isTargetMacCatalyst();
456   }
457 
isTargetAppleSiliconMac()458   bool isTargetAppleSiliconMac() const {
459     assert(TargetInitialized && "Target not initialized!");
460     return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64;
461   }
462 
isTargetInitialized()463   bool isTargetInitialized() const { return TargetInitialized; }
464 
465   /// The version of the OS that's used by the OS specified in the target
466   /// triple. It might be different from the actual target OS on which the
467   /// program will run, e.g. MacCatalyst code runs on a macOS target, but its
468   /// target triple is iOS.
getTripleTargetVersion()469   VersionTuple getTripleTargetVersion() const {
470     assert(TargetInitialized && "Target not initialized!");
471     return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion;
472   }
473 
474   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
475                            unsigned V2 = 0) const {
476     assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
477     return TargetVersion < VersionTuple(V0, V1, V2);
478   }
479 
480   /// Returns true if the minimum supported macOS version for the slice that's
481   /// being built is less than the specified version. If there's no minimum
482   /// supported macOS version, the deployment target version is compared to the
483   /// specifed version instead.
484   bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
485     assert(isTargetMacOSBased() &&
486            (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) &&
487            "Unexpected call for non OS X target!");
488     // The effective triple might not be initialized yet, so construct a
489     // pseudo-effective triple to get the minimum supported OS version.
490     VersionTuple MinVers =
491         llvm::Triple(getTriple().getArchName(), "apple", "macos")
492             .getMinimumSupportedOSVersion();
493     return (!MinVers.empty() && MinVers > TargetVersion
494                 ? MinVers
495                 : TargetVersion) < VersionTuple(V0, V1, V2);
496   }
497 
498   /// Returns the darwin target variant triple, the variant of the deployment
499   /// target for which the code is being compiled.
getTargetVariantTriple()500   Optional<llvm::Triple> getTargetVariantTriple() const override {
501     return TargetVariantTriple;
502   }
503 
504 protected:
505   /// Return true if c++17 aligned allocation/deallocation functions are not
506   /// implemented in the c++ standard library of the deployment target we are
507   /// targeting.
508   bool isAlignedAllocationUnavailable() const;
509 
510   void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
511                              llvm::opt::ArgStringList &CC1Args,
512                              Action::OffloadKind DeviceOffloadKind) const override;
513 
514   StringRef getPlatformFamily() const;
515   StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
516 
517 public:
518   static StringRef getSDKName(StringRef isysroot);
519 
520   /// }
521   /// @name ToolChain Implementation
522   /// {
523 
524   // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
525   // most development is done against SDKs, so compiling for a different
526   // architecture should not get any special treatment.
isCrossCompiling()527   bool isCrossCompiling() const override { return false; }
528 
529   llvm::opt::DerivedArgList *
530   TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
531                 Action::OffloadKind DeviceOffloadKind) const override;
532 
533   CXXStdlibType GetDefaultCXXStdlibType() const override;
534   ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
535   bool hasBlocksRuntime() const override;
536 
537   void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
538                           llvm::opt::ArgStringList &CC1Args) const override;
539   void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
540                          llvm::opt::ArgStringList &CC1Args) const override;
541 
UseObjCMixedDispatch()542   bool UseObjCMixedDispatch() const override {
543     // This is only used with the non-fragile ABI and non-legacy dispatch.
544 
545     // Mixed dispatch is used everywhere except OS X before 10.6.
546     return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6));
547   }
548 
549   LangOptions::StackProtectorMode
GetDefaultStackProtectorLevel(bool KernelOrKext)550   GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
551     // Stack protectors default to on for user code on 10.5,
552     // and for everything in 10.6 and beyond
553     if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit())
554       return LangOptions::SSPOn;
555     else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))
556       return LangOptions::SSPOn;
557     else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
558       return LangOptions::SSPOn;
559 
560     return LangOptions::SSPOff;
561   }
562 
563   void CheckObjCARC() const override;
564 
565   llvm::ExceptionHandling GetExceptionModel(
566       const llvm::opt::ArgList &Args) const override;
567 
568   bool SupportsEmbeddedBitcode() const override;
569 
570   SanitizerMask getSupportedSanitizers() const override;
571 
572   void printVerboseInfo(raw_ostream &OS) const override;
573 };
574 
575 /// DarwinClang - The Darwin toolchain used by Clang.
576 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
577 public:
578   DarwinClang(const Driver &D, const llvm::Triple &Triple,
579               const llvm::opt::ArgList &Args);
580 
581   /// @name Apple ToolChain Implementation
582   /// {
583 
584   RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
585 
586   void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
587                              llvm::opt::ArgStringList &CmdArgs,
588                              bool ForceLinkBuiltinRT = false) const override;
589 
590   void AddClangCXXStdlibIncludeArgs(
591       const llvm::opt::ArgList &DriverArgs,
592       llvm::opt::ArgStringList &CC1Args) const override;
593 
594   void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
595                                  llvm::opt::ArgStringList &CC1Args) const override;
596 
597   void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
598                            llvm::opt::ArgStringList &CmdArgs) const override;
599 
600   void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
601                         llvm::opt::ArgStringList &CmdArgs) const override;
602 
603   void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
604 
605   void AddLinkARCArgs(const llvm::opt::ArgList &Args,
606                       llvm::opt::ArgStringList &CmdArgs) const override;
607 
608   unsigned GetDefaultDwarfVersion() const override;
609   // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
610   // Darwin defaults to standalone/full debug info.
GetDefaultStandaloneDebug()611   bool GetDefaultStandaloneDebug() const override { return true; }
getDefaultDebuggerTuning()612   llvm::DebuggerKind getDefaultDebuggerTuning() const override {
613     return llvm::DebuggerKind::LLDB;
614   }
615 
616   /// }
617 
618 private:
619   void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
620                                llvm::opt::ArgStringList &CmdArgs,
621                                StringRef Sanitizer,
622                                bool shared = true) const;
623 
624   bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
625                                    llvm::opt::ArgStringList &CC1Args,
626                                    llvm::SmallString<128> Base,
627                                    llvm::StringRef Version,
628                                    llvm::StringRef ArchDir,
629                                    llvm::StringRef BitDir) const;
630 
631   llvm::StringRef GetHeaderSysroot(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