1 //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
11 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
14 #include "clang/Driver/Tool.h"
15 #include "clang/Driver/ToolChain.h"
20 namespace toolchains {
22 } // end namespace toolchains
27 llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
28 void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
30 class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
31 virtual void anchor();
34 void AddMachOArch(const llvm::opt::ArgList &Args,
35 llvm::opt::ArgStringList &CmdArgs) const;
37 const toolchains::MachO &getMachOToolChain() const {
38 return reinterpret_cast<const toolchains::MachO &>(getToolChain());
43 const char *Name, const char *ShortName, const ToolChain &TC,
44 ResponseFileSupport ResponseSupport = RF_None,
45 llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
46 const char *ResponseFlag = "@")
47 : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
51 class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
53 Assembler(const ToolChain &TC)
54 : MachOTool("darwin::Assembler", "assembler", TC) {}
56 bool hasIntegratedCPP() const override { return false; }
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;
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) const;
71 Linker(const ToolChain &TC)
72 : MachOTool("darwin::Linker", "linker", TC, RF_FileList,
73 llvm::sys::WEM_UTF8, "-filelist") {}
75 bool hasIntegratedCPP() const override { return false; }
76 bool isLinkJob() const override { return true; }
78 void ConstructJob(Compilation &C, const JobAction &JA,
79 const InputInfo &Output, const InputInfoList &Inputs,
80 const llvm::opt::ArgList &TCArgs,
81 const char *LinkingOutput) const override;
84 class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
86 Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
88 bool hasIntegratedCPP() const override { return false; }
90 void ConstructJob(Compilation &C, const JobAction &JA,
91 const InputInfo &Output, const InputInfoList &Inputs,
92 const llvm::opt::ArgList &TCArgs,
93 const char *LinkingOutput) const override;
96 class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
98 Dsymutil(const ToolChain &TC)
99 : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
101 bool hasIntegratedCPP() const override { return false; }
102 bool isDsymutilJob() const override { return true; }
104 void ConstructJob(Compilation &C, const JobAction &JA,
105 const InputInfo &Output, const InputInfoList &Inputs,
106 const llvm::opt::ArgList &TCArgs,
107 const char *LinkingOutput) const override;
110 class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
112 VerifyDebug(const ToolChain &TC)
113 : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
115 bool hasIntegratedCPP() const override { return false; }
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;
122 } // end namespace darwin
123 } // end namespace tools
125 namespace toolchains {
127 class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
129 Tool *buildAssembler() const override;
130 Tool *buildLinker() const override;
131 Tool *getTool(Action::ActionClass AC) const override;
134 mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
135 mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
136 mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
139 MachO(const Driver &D, const llvm::Triple &Triple,
140 const llvm::opt::ArgList &Args);
143 /// @name MachO specific toolchain API
146 /// Get the "MachO" arch name for a particular compiler invocation. For
147 /// example, Apple treats different ARM variations as distinct architectures.
148 StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
150 /// Add the linker arguments to link the ARC runtime library.
151 virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
152 llvm::opt::ArgStringList &CmdArgs) const {}
154 /// Add the linker arguments to link the compiler runtime library.
155 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
156 llvm::opt::ArgStringList &CmdArgs) const;
158 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
159 llvm::opt::ArgStringList &CmdArgs) const {
162 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
163 llvm::opt::ArgStringList &CmdArgs) const {}
165 /// On some iOS platforms, kernel and kernel modules were built statically. Is
166 /// this such a target?
167 virtual bool isKernelStatic() const { return false; }
169 /// Is the target either iOS or an iOS simulator?
170 bool isTargetIOSBased() const { return false; }
172 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
173 llvm::opt::ArgStringList &CmdArgs,
174 StringRef DarwinLibName, bool AlwaysLink = false,
175 bool IsEmbedded = false, bool AddRPath = false) const;
177 /// Add any profiling runtime libraries that are needed. This is essentially a
178 /// MachO specific version of addProfileRT in Tools.cpp.
179 void addProfileRTLibs(const llvm::opt::ArgList &Args,
180 llvm::opt::ArgStringList &CmdArgs) const override {
181 // There aren't any profiling libs for embedded targets currently.
185 /// @name ToolChain Implementation
188 types::ID LookupTypeForExtension(StringRef Ext) const override;
190 bool HasNativeLLVMSupport() const override;
192 llvm::opt::DerivedArgList *
193 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
194 Action::OffloadKind DeviceOffloadKind) const override;
196 bool IsBlocksDefault() const override {
197 // Always allow blocks on Apple; users interested in versioning are
198 // expected to use /usr/include/Block.h.
201 bool IsIntegratedAssemblerDefault() const override {
202 // Default integrated assembler to on for Apple's MachO targets.
206 bool IsMathErrnoDefault() const override { return false; }
208 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
210 bool IsObjCNonFragileABIDefault() const override {
211 // Non-fragile ABI is default for everything but i386.
212 return getTriple().getArch() != llvm::Triple::x86;
215 bool UseObjCMixedDispatch() const override { return true; }
217 bool IsUnwindTablesDefault() const override;
219 RuntimeLibType GetDefaultRuntimeLibType() const override {
220 return ToolChain::RLT_CompilerRT;
223 bool isPICDefault() const override;
224 bool isPIEDefault() const override;
225 bool isPICDefaultForced() const override;
227 bool SupportsProfiling() const override;
229 bool SupportsObjCGC() const override { return false; }
231 bool UseDwarfDebugFlags() const override;
233 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override {
240 /// Darwin - The base Darwin tool chain.
241 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
243 /// Whether the information on the target has been initialized.
245 // FIXME: This should be eliminated. What we want to do is make this part of
246 // the "default target for arguments" selection process, once we get out of
247 // the argument translation business.
248 mutable bool TargetInitialized;
250 enum DarwinPlatformKind {
260 mutable DarwinPlatformKind TargetPlatform;
262 /// The OS version we are targeting.
263 mutable VersionTuple TargetVersion;
265 CudaInstallationDetector CudaInstallation;
268 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
271 Darwin(const Driver &D, const llvm::Triple &Triple,
272 const llvm::opt::ArgList &Args);
275 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
276 types::ID InputType) const override;
278 /// @name Apple Specific Toolchain Implementation
281 void addMinVersionArgs(const llvm::opt::ArgList &Args,
282 llvm::opt::ArgStringList &CmdArgs) const override;
284 void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
285 llvm::opt::ArgStringList &CmdArgs) const override;
287 bool isKernelStatic() const override {
288 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
292 void addProfileRTLibs(const llvm::opt::ArgList &Args,
293 llvm::opt::ArgStringList &CmdArgs) const override;
297 /// @name Darwin specific Toolchain functions
300 // FIXME: Eliminate these ...Target functions and derive separate tool chains
301 // for these targets and put version in constructor.
302 void setTarget(DarwinPlatformKind Platform, unsigned Major, unsigned Minor,
303 unsigned Micro) const {
304 // FIXME: For now, allow reinitialization as long as values don't
305 // change. This will go away when we move away from argument translation.
306 if (TargetInitialized && TargetPlatform == Platform &&
307 TargetVersion == VersionTuple(Major, Minor, Micro))
310 assert(!TargetInitialized && "Target already initialized!");
311 TargetInitialized = true;
312 TargetPlatform = Platform;
313 TargetVersion = VersionTuple(Major, Minor, Micro);
316 bool isTargetIPhoneOS() const {
317 assert(TargetInitialized && "Target not initialized!");
318 return TargetPlatform == IPhoneOS || TargetPlatform == TvOS;
321 bool isTargetIOSSimulator() const {
322 assert(TargetInitialized && "Target not initialized!");
323 return TargetPlatform == IPhoneOSSimulator ||
324 TargetPlatform == TvOSSimulator;
327 bool isTargetIOSBased() const {
328 assert(TargetInitialized && "Target not initialized!");
329 return isTargetIPhoneOS() || isTargetIOSSimulator();
332 bool isTargetTvOS() const {
333 assert(TargetInitialized && "Target not initialized!");
334 return TargetPlatform == TvOS;
337 bool isTargetTvOSSimulator() const {
338 assert(TargetInitialized && "Target not initialized!");
339 return TargetPlatform == TvOSSimulator;
342 bool isTargetTvOSBased() const {
343 assert(TargetInitialized && "Target not initialized!");
344 return TargetPlatform == TvOS || TargetPlatform == TvOSSimulator;
347 bool isTargetWatchOS() const {
348 assert(TargetInitialized && "Target not initialized!");
349 return TargetPlatform == WatchOS;
352 bool isTargetWatchOSSimulator() const {
353 assert(TargetInitialized && "Target not initialized!");
354 return TargetPlatform == WatchOSSimulator;
357 bool isTargetWatchOSBased() const {
358 assert(TargetInitialized && "Target not initialized!");
359 return TargetPlatform == WatchOS || TargetPlatform == WatchOSSimulator;
362 bool isTargetMacOS() const {
363 assert(TargetInitialized && "Target not initialized!");
364 return TargetPlatform == MacOS;
367 bool isTargetInitialized() const { return TargetInitialized; }
369 VersionTuple getTargetVersion() const {
370 assert(TargetInitialized && "Target not initialized!");
371 return TargetVersion;
374 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
375 unsigned V2 = 0) const {
376 assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
377 return TargetVersion < VersionTuple(V0, V1, V2);
380 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
381 assert(isTargetMacOS() && "Unexpected call for non OS X target!");
382 return TargetVersion < VersionTuple(V0, V1, V2);
385 StringRef getPlatformFamily() const;
386 static StringRef getSDKName(StringRef isysroot);
387 StringRef getOSLibraryNameSuffix() const;
391 /// @name ToolChain Implementation
394 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
395 // most development is done against SDKs, so compiling for a different
396 // architecture should not get any special treatment.
397 bool isCrossCompiling() const override { return false; }
399 llvm::opt::DerivedArgList *
400 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
401 Action::OffloadKind DeviceOffloadKind) const override;
403 CXXStdlibType GetDefaultCXXStdlibType() const override;
404 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
405 bool hasBlocksRuntime() const override;
407 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
408 llvm::opt::ArgStringList &CC1Args) const override;
410 bool UseObjCMixedDispatch() const override {
411 // This is only used with the non-fragile ABI and non-legacy dispatch.
413 // Mixed dispatch is used everywhere except OS X before 10.6.
414 return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
417 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
418 // Stack protectors default to on for user code on 10.5,
419 // and for everything in 10.6 and beyond
420 if (isTargetIOSBased() || isTargetWatchOSBased())
422 else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
424 else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
430 bool SupportsObjCGC() const override;
432 void CheckObjCARC() const override;
434 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
436 bool SupportsEmbeddedBitcode() const override;
438 SanitizerMask getSupportedSanitizers() const override;
440 void printVerboseInfo(raw_ostream &OS) const override;
443 /// DarwinClang - The Darwin toolchain used by Clang.
444 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
446 DarwinClang(const Driver &D, const llvm::Triple &Triple,
447 const llvm::opt::ArgList &Args);
449 /// @name Apple ToolChain Implementation
452 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
454 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
455 llvm::opt::ArgStringList &CmdArgs) const override;
457 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
458 llvm::opt::ArgStringList &CmdArgs) const override;
460 void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
461 llvm::opt::ArgStringList &CmdArgs) const override;
463 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
465 void AddLinkARCArgs(const llvm::opt::ArgList &Args,
466 llvm::opt::ArgStringList &CmdArgs) const override;
468 unsigned GetDefaultDwarfVersion() const override;
469 // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
470 // Darwin defaults to standalone/full debug info.
471 bool GetDefaultStandaloneDebug() const override { return true; }
472 llvm::DebuggerKind getDefaultDebuggerTuning() const override {
473 return llvm::DebuggerKind::LLDB;
479 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
480 llvm::opt::ArgStringList &CmdArgs,
481 StringRef Sanitizer) const;
484 } // end namespace toolchains
485 } // end namespace driver
486 } // end namespace clang
488 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H