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