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