xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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  
getMachOToolChain()42    const toolchains::MachO &getMachOToolChain() const {
43      return reinterpret_cast<const toolchains::MachO &>(getToolChain());
44    }
45  
46  public:
MachOTool(const char * Name,const char * ShortName,const ToolChain & TC)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:
Assembler(const ToolChain & TC)53    Assembler(const ToolChain &TC)
54        : MachOTool("darwin::Assembler", "assembler", TC) {}
55  
hasIntegratedCPP()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:
Linker(const ToolChain & TC)72    Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {}
73  
hasIntegratedCPP()74    bool hasIntegratedCPP() const override { return false; }
isLinkJob()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:
StaticLibTool(const ToolChain & TC)85    StaticLibTool(const ToolChain &TC)
86        : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {}
87  
hasIntegratedCPP()88    bool hasIntegratedCPP() const override { return false; }
isLinkJob()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:
Lipo(const ToolChain & TC)99    Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
100  
hasIntegratedCPP()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:
Dsymutil(const ToolChain & TC)111    Dsymutil(const ToolChain &TC)
112        : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
113  
hasIntegratedCPP()114    bool hasIntegratedCPP() const override { return false; }
isDsymutilJob()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:
VerifyDebug(const ToolChain & TC)125    VerifyDebug(const ToolChain &TC)
126        : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
127  
hasIntegratedCPP()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.
AddLinkARCArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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  
addStartObjectFileArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)183    virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
184                                        llvm::opt::ArgStringList &CmdArgs) const {
185    }
186  
addMinVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)187    virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
188                                   llvm::opt::ArgStringList &CmdArgs) const {}
189  
addPlatformVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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?
isKernelStatic()196    virtual bool isKernelStatic() const { return false; }
197  
198    /// Is the target either iOS or an iOS simulator?
isTargetIOSBased()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.
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)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  
IsBlocksDefault()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  
IsMathErrnoDefault()251    bool IsMathErrnoDefault() const override { return false; }
252  
IsEncodeExtendedBlockSignatureDefault()253    bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
254  
IsObjCNonFragileABIDefault()255    bool IsObjCNonFragileABIDefault() const override {
256      // Non-fragile ABI is default for everything but i386.
257      return getTriple().getArch() != llvm::Triple::x86;
258    }
259  
UseObjCMixedDispatch()260    bool UseObjCMixedDispatch() const override { return true; }
261  
262    UnwindTableLevel
263    getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;
264  
GetDefaultRuntimeLibType()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
GetExceptionModel(const llvm::opt::ArgList & Args)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.
canSplitThinLTOUnit()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  
isKernelStatic()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.
setTarget(DarwinPlatformKind Platform,DarwinEnvironmentKind Environment,unsigned Major,unsigned Minor,unsigned Micro,VersionTuple NativeTargetVersion)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:
isTargetIPhoneOS()405    bool isTargetIPhoneOS() const {
406      assert(TargetInitialized && "Target not initialized!");
407      return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
408             TargetEnvironment == NativeEnvironment;
409    }
410  
isTargetIOSSimulator()411    bool isTargetIOSSimulator() const {
412      assert(TargetInitialized && "Target not initialized!");
413      return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
414             TargetEnvironment == Simulator;
415    }
416  
isTargetIOSBased()417    bool isTargetIOSBased() const {
418      assert(TargetInitialized && "Target not initialized!");
419      return isTargetIPhoneOS() || isTargetIOSSimulator();
420    }
421  
isTargetXROSDevice()422    bool isTargetXROSDevice() const {
423      return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment;
424    }
425  
isTargetXROSSimulator()426    bool isTargetXROSSimulator() const {
427      return TargetPlatform == XROS && TargetEnvironment == Simulator;
428    }
429  
isTargetXROS()430    bool isTargetXROS() const { return TargetPlatform == XROS; }
431  
isTargetTvOS()432    bool isTargetTvOS() const {
433      assert(TargetInitialized && "Target not initialized!");
434      return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
435    }
436  
isTargetTvOSSimulator()437    bool isTargetTvOSSimulator() const {
438      assert(TargetInitialized && "Target not initialized!");
439      return TargetPlatform == TvOS && TargetEnvironment == Simulator;
440    }
441  
isTargetTvOSBased()442    bool isTargetTvOSBased() const {
443      assert(TargetInitialized && "Target not initialized!");
444      return TargetPlatform == TvOS;
445    }
446  
isTargetWatchOS()447    bool isTargetWatchOS() const {
448      assert(TargetInitialized && "Target not initialized!");
449      return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
450    }
451  
isTargetWatchOSSimulator()452    bool isTargetWatchOSSimulator() const {
453      assert(TargetInitialized && "Target not initialized!");
454      return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
455    }
456  
isTargetWatchOSBased()457    bool isTargetWatchOSBased() const {
458      assert(TargetInitialized && "Target not initialized!");
459      return TargetPlatform == WatchOS;
460    }
461  
isTargetDriverKit()462    bool isTargetDriverKit() const {
463      assert(TargetInitialized && "Target not initialized!");
464      return TargetPlatform == DriverKit;
465    }
466  
isTargetMacCatalyst()467    bool isTargetMacCatalyst() const {
468      return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
469    }
470  
isTargetMacOS()471    bool isTargetMacOS() const {
472      assert(TargetInitialized && "Target not initialized!");
473      return TargetPlatform == MacOS;
474    }
475  
isTargetMacOSBased()476    bool isTargetMacOSBased() const {
477      assert(TargetInitialized && "Target not initialized!");
478      return TargetPlatform == MacOS || isTargetMacCatalyst();
479    }
480  
isTargetAppleSiliconMac()481    bool isTargetAppleSiliconMac() const {
482      assert(TargetInitialized && "Target not initialized!");
483      return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64;
484    }
485  
isTargetInitialized()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.
getTripleTargetVersion()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.
isCrossCompiling()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  
UseObjCMixedDispatch()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
GetDefaultStackProtectorLevel(bool KernelOrKext)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.
GetDefaultStandaloneDebug()637    bool GetDefaultStandaloneDebug() const override { return true; }
getDefaultDebuggerTuning()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