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.
156 /// FIXME: This API is intended for use with embedded libraries only, and is
157 /// misleadingly named.
158 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
159 llvm::opt::ArgStringList &CmdArgs) const;
161 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
162 llvm::opt::ArgStringList &CmdArgs) const {
165 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
166 llvm::opt::ArgStringList &CmdArgs) const {}
168 /// On some iOS platforms, kernel and kernel modules were built statically. Is
169 /// this such a target?
170 virtual bool isKernelStatic() const { return false; }
172 /// Is the target either iOS or an iOS simulator?
173 bool isTargetIOSBased() const { return false; }
175 /// Options to control how a runtime library is linked.
176 enum RuntimeLinkOptions : unsigned {
177 /// Link the library in even if it can't be found in the VFS.
178 RLO_AlwaysLink = 1 << 0,
180 /// Use the embedded runtime from the macho_embedded directory.
181 RLO_IsEmbedded = 1 << 1,
183 /// Emit rpaths for @executable_path as well as the resource directory.
184 RLO_AddRPath = 1 << 2,
186 /// Link the library in before any others.
187 RLO_FirstLink = 1 << 3,
190 /// Add a runtime library to the list of items to link.
191 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
192 llvm::opt::ArgStringList &CmdArgs,
193 StringRef DarwinLibName,
194 RuntimeLinkOptions Opts = RuntimeLinkOptions()) const;
196 /// Add any profiling runtime libraries that are needed. This is essentially a
197 /// MachO specific version of addProfileRT in Tools.cpp.
198 void addProfileRTLibs(const llvm::opt::ArgList &Args,
199 llvm::opt::ArgStringList &CmdArgs) const override {
200 // There aren't any profiling libs for embedded targets currently.
204 /// @name ToolChain Implementation
207 types::ID LookupTypeForExtension(StringRef Ext) const override;
209 bool HasNativeLLVMSupport() const override;
211 llvm::opt::DerivedArgList *
212 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
213 Action::OffloadKind DeviceOffloadKind) const override;
215 bool IsBlocksDefault() const override {
216 // Always allow blocks on Apple; users interested in versioning are
217 // expected to use /usr/include/Block.h.
220 bool IsIntegratedAssemblerDefault() const override {
221 // Default integrated assembler to on for Apple's MachO targets.
225 bool IsMathErrnoDefault() const override { return false; }
227 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
229 bool IsObjCNonFragileABIDefault() const override {
230 // Non-fragile ABI is default for everything but i386.
231 return getTriple().getArch() != llvm::Triple::x86;
234 bool UseObjCMixedDispatch() const override { return true; }
236 bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
238 RuntimeLibType GetDefaultRuntimeLibType() const override {
239 return ToolChain::RLT_CompilerRT;
242 bool isPICDefault() const override;
243 bool isPIEDefault() const override;
244 bool isPICDefaultForced() const override;
246 bool SupportsProfiling() const override;
248 bool UseDwarfDebugFlags() const override;
250 llvm::ExceptionHandling
251 GetExceptionModel(const llvm::opt::ArgList &Args) const override {
252 return llvm::ExceptionHandling::None;
258 /// Darwin - The base Darwin tool chain.
259 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
261 /// Whether the information on the target has been initialized.
263 // FIXME: This should be eliminated. What we want to do is make this part of
264 // the "default target for arguments" selection process, once we get out of
265 // the argument translation business.
266 mutable bool TargetInitialized;
268 enum DarwinPlatformKind {
273 LastDarwinPlatform = WatchOS
275 enum DarwinEnvironmentKind {
280 mutable DarwinPlatformKind TargetPlatform;
281 mutable DarwinEnvironmentKind TargetEnvironment;
283 /// The OS version we are targeting.
284 mutable VersionTuple TargetVersion;
286 CudaInstallationDetector CudaInstallation;
289 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
292 Darwin(const Driver &D, const llvm::Triple &Triple,
293 const llvm::opt::ArgList &Args);
296 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
297 types::ID InputType) const override;
299 /// @name Apple Specific Toolchain Implementation
302 void addMinVersionArgs(const llvm::opt::ArgList &Args,
303 llvm::opt::ArgStringList &CmdArgs) const override;
305 void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
306 llvm::opt::ArgStringList &CmdArgs) const override;
308 bool isKernelStatic() const override {
309 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
313 void addProfileRTLibs(const llvm::opt::ArgList &Args,
314 llvm::opt::ArgStringList &CmdArgs) const override;
318 /// @name Darwin specific Toolchain functions
321 // FIXME: Eliminate these ...Target functions and derive separate tool chains
322 // for these targets and put version in constructor.
323 void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
324 unsigned Major, unsigned Minor, unsigned Micro) const {
325 // FIXME: For now, allow reinitialization as long as values don't
326 // change. This will go away when we move away from argument translation.
327 if (TargetInitialized && TargetPlatform == Platform &&
328 TargetEnvironment == Environment &&
329 TargetVersion == VersionTuple(Major, Minor, Micro))
332 assert(!TargetInitialized && "Target already initialized!");
333 TargetInitialized = true;
334 TargetPlatform = Platform;
335 TargetEnvironment = Environment;
336 TargetVersion = VersionTuple(Major, Minor, Micro);
337 if (Environment == Simulator)
338 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
341 bool isTargetIPhoneOS() const {
342 assert(TargetInitialized && "Target not initialized!");
343 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
344 TargetEnvironment == NativeEnvironment;
347 bool isTargetIOSSimulator() const {
348 assert(TargetInitialized && "Target not initialized!");
349 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
350 TargetEnvironment == Simulator;
353 bool isTargetIOSBased() const {
354 assert(TargetInitialized && "Target not initialized!");
355 return isTargetIPhoneOS() || isTargetIOSSimulator();
358 bool isTargetTvOS() const {
359 assert(TargetInitialized && "Target not initialized!");
360 return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
363 bool isTargetTvOSSimulator() const {
364 assert(TargetInitialized && "Target not initialized!");
365 return TargetPlatform == TvOS && TargetEnvironment == Simulator;
368 bool isTargetTvOSBased() const {
369 assert(TargetInitialized && "Target not initialized!");
370 return TargetPlatform == TvOS;
373 bool isTargetWatchOS() const {
374 assert(TargetInitialized && "Target not initialized!");
375 return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
378 bool isTargetWatchOSSimulator() const {
379 assert(TargetInitialized && "Target not initialized!");
380 return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
383 bool isTargetWatchOSBased() const {
384 assert(TargetInitialized && "Target not initialized!");
385 return TargetPlatform == WatchOS;
388 bool isTargetMacOS() const {
389 assert(TargetInitialized && "Target not initialized!");
390 return TargetPlatform == MacOS;
393 bool isTargetInitialized() const { return TargetInitialized; }
395 VersionTuple getTargetVersion() const {
396 assert(TargetInitialized && "Target not initialized!");
397 return TargetVersion;
400 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
401 unsigned V2 = 0) const {
402 assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
403 return TargetVersion < VersionTuple(V0, V1, V2);
406 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
407 assert(isTargetMacOS() && "Unexpected call for non OS X target!");
408 return TargetVersion < VersionTuple(V0, V1, V2);
411 /// Return true if c++17 aligned allocation/deallocation functions are not
412 /// implemented in the c++ standard library of the deployment target we are
414 bool isAlignedAllocationUnavailable() const;
416 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
417 llvm::opt::ArgStringList &CC1Args,
418 Action::OffloadKind DeviceOffloadKind) const override;
420 StringRef getPlatformFamily() const;
421 StringRef getOSLibraryNameSuffix() const;
424 static StringRef getSDKName(StringRef isysroot);
427 /// @name ToolChain Implementation
430 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
431 // most development is done against SDKs, so compiling for a different
432 // architecture should not get any special treatment.
433 bool isCrossCompiling() const override { return false; }
435 llvm::opt::DerivedArgList *
436 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
437 Action::OffloadKind DeviceOffloadKind) const override;
439 CXXStdlibType GetDefaultCXXStdlibType() const override;
440 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
441 bool hasBlocksRuntime() const override;
443 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
444 llvm::opt::ArgStringList &CC1Args) const override;
446 bool UseObjCMixedDispatch() const override {
447 // This is only used with the non-fragile ABI and non-legacy dispatch.
449 // Mixed dispatch is used everywhere except OS X before 10.6.
450 return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
453 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
454 // Stack protectors default to on for user code on 10.5,
455 // and for everything in 10.6 and beyond
456 if (isTargetIOSBased() || isTargetWatchOSBased())
458 else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
460 else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
466 void CheckObjCARC() const override;
468 llvm::ExceptionHandling GetExceptionModel(
469 const llvm::opt::ArgList &Args) const override;
471 bool SupportsEmbeddedBitcode() const override;
473 SanitizerMask getSupportedSanitizers() const override;
475 void printVerboseInfo(raw_ostream &OS) const override;
478 /// DarwinClang - The Darwin toolchain used by Clang.
479 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
481 DarwinClang(const Driver &D, const llvm::Triple &Triple,
482 const llvm::opt::ArgList &Args);
484 /// @name Apple ToolChain Implementation
487 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
489 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
490 llvm::opt::ArgStringList &CmdArgs) const override;
492 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
493 llvm::opt::ArgStringList &CmdArgs) const override;
495 void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
496 llvm::opt::ArgStringList &CmdArgs) const override;
498 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
500 void AddLinkARCArgs(const llvm::opt::ArgList &Args,
501 llvm::opt::ArgStringList &CmdArgs) const override;
503 unsigned GetDefaultDwarfVersion() const override;
504 // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
505 // Darwin defaults to standalone/full debug info.
506 bool GetDefaultStandaloneDebug() const override { return true; }
507 llvm::DebuggerKind getDefaultDebuggerTuning() const override {
508 return llvm::DebuggerKind::LLDB;
514 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
515 llvm::opt::ArgStringList &CmdArgs,
517 bool shared = true) const;
520 } // end namespace toolchains
521 } // end namespace driver
522 } // end namespace clang
524 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H