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;
157 virtual void AddFuzzerLinkArgs(const llvm::opt::ArgList &Args,
158 llvm::opt::ArgStringList &CmdArgs) const;
160 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
161 llvm::opt::ArgStringList &CmdArgs) const {
164 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
165 llvm::opt::ArgStringList &CmdArgs) const {}
167 /// On some iOS platforms, kernel and kernel modules were built statically. Is
168 /// this such a target?
169 virtual bool isKernelStatic() const { return false; }
171 /// Is the target either iOS or an iOS simulator?
172 bool isTargetIOSBased() const { return false; }
174 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
175 llvm::opt::ArgStringList &CmdArgs,
176 StringRef DarwinLibName, bool AlwaysLink = false,
177 bool IsEmbedded = false, bool AddRPath = false) const;
179 /// Add any profiling runtime libraries that are needed. This is essentially a
180 /// MachO specific version of addProfileRT in Tools.cpp.
181 void addProfileRTLibs(const llvm::opt::ArgList &Args,
182 llvm::opt::ArgStringList &CmdArgs) const override {
183 // There aren't any profiling libs for embedded targets currently.
187 /// @name ToolChain Implementation
190 types::ID LookupTypeForExtension(StringRef Ext) const override;
192 bool HasNativeLLVMSupport() const override;
194 llvm::opt::DerivedArgList *
195 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
196 Action::OffloadKind DeviceOffloadKind) const override;
198 bool IsBlocksDefault() const override {
199 // Always allow blocks on Apple; users interested in versioning are
200 // expected to use /usr/include/Block.h.
203 bool IsIntegratedAssemblerDefault() const override {
204 // Default integrated assembler to on for Apple's MachO targets.
208 bool IsMathErrnoDefault() const override { return false; }
210 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
212 bool IsObjCNonFragileABIDefault() const override {
213 // Non-fragile ABI is default for everything but i386.
214 return getTriple().getArch() != llvm::Triple::x86;
217 bool UseObjCMixedDispatch() const override { return true; }
219 bool IsUnwindTablesDefault() const override;
221 RuntimeLibType GetDefaultRuntimeLibType() const override {
222 return ToolChain::RLT_CompilerRT;
225 bool isPICDefault() const override;
226 bool isPIEDefault() const override;
227 bool isPICDefaultForced() const override;
229 bool SupportsProfiling() const override;
231 bool SupportsObjCGC() const override { return false; }
233 bool UseDwarfDebugFlags() const override;
235 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override {
242 /// Darwin - The base Darwin tool chain.
243 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
245 /// Whether the information on the target has been initialized.
247 // FIXME: This should be eliminated. What we want to do is make this part of
248 // the "default target for arguments" selection process, once we get out of
249 // the argument translation business.
250 mutable bool TargetInitialized;
252 enum DarwinPlatformKind {
262 mutable DarwinPlatformKind TargetPlatform;
264 /// The OS version we are targeting.
265 mutable VersionTuple TargetVersion;
267 CudaInstallationDetector CudaInstallation;
270 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
273 Darwin(const Driver &D, const llvm::Triple &Triple,
274 const llvm::opt::ArgList &Args);
277 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
278 types::ID InputType) const override;
280 /// @name Apple Specific Toolchain Implementation
283 void addMinVersionArgs(const llvm::opt::ArgList &Args,
284 llvm::opt::ArgStringList &CmdArgs) const override;
286 void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
287 llvm::opt::ArgStringList &CmdArgs) const override;
289 bool isKernelStatic() const override {
290 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
294 void addProfileRTLibs(const llvm::opt::ArgList &Args,
295 llvm::opt::ArgStringList &CmdArgs) const override;
299 /// @name Darwin specific Toolchain functions
302 // FIXME: Eliminate these ...Target functions and derive separate tool chains
303 // for these targets and put version in constructor.
304 void setTarget(DarwinPlatformKind Platform, unsigned Major, unsigned Minor,
305 unsigned Micro) const {
306 // FIXME: For now, allow reinitialization as long as values don't
307 // change. This will go away when we move away from argument translation.
308 if (TargetInitialized && TargetPlatform == Platform &&
309 TargetVersion == VersionTuple(Major, Minor, Micro))
312 assert(!TargetInitialized && "Target already initialized!");
313 TargetInitialized = true;
314 TargetPlatform = Platform;
315 TargetVersion = VersionTuple(Major, Minor, Micro);
318 bool isTargetIPhoneOS() const {
319 assert(TargetInitialized && "Target not initialized!");
320 return TargetPlatform == IPhoneOS || TargetPlatform == TvOS;
323 bool isTargetIOSSimulator() const {
324 assert(TargetInitialized && "Target not initialized!");
325 return TargetPlatform == IPhoneOSSimulator ||
326 TargetPlatform == TvOSSimulator;
329 bool isTargetIOSBased() const {
330 assert(TargetInitialized && "Target not initialized!");
331 return isTargetIPhoneOS() || isTargetIOSSimulator();
334 bool isTargetTvOS() const {
335 assert(TargetInitialized && "Target not initialized!");
336 return TargetPlatform == TvOS;
339 bool isTargetTvOSSimulator() const {
340 assert(TargetInitialized && "Target not initialized!");
341 return TargetPlatform == TvOSSimulator;
344 bool isTargetTvOSBased() const {
345 assert(TargetInitialized && "Target not initialized!");
346 return TargetPlatform == TvOS || TargetPlatform == TvOSSimulator;
349 bool isTargetWatchOS() const {
350 assert(TargetInitialized && "Target not initialized!");
351 return TargetPlatform == WatchOS;
354 bool isTargetWatchOSSimulator() const {
355 assert(TargetInitialized && "Target not initialized!");
356 return TargetPlatform == WatchOSSimulator;
359 bool isTargetWatchOSBased() const {
360 assert(TargetInitialized && "Target not initialized!");
361 return TargetPlatform == WatchOS || TargetPlatform == WatchOSSimulator;
364 bool isTargetMacOS() const {
365 assert(TargetInitialized && "Target not initialized!");
366 return TargetPlatform == MacOS;
369 bool isTargetInitialized() const { return TargetInitialized; }
371 VersionTuple getTargetVersion() const {
372 assert(TargetInitialized && "Target not initialized!");
373 return TargetVersion;
376 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
377 unsigned V2 = 0) const {
378 assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
379 return TargetVersion < VersionTuple(V0, V1, V2);
382 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
383 assert(isTargetMacOS() && "Unexpected call for non OS X target!");
384 return TargetVersion < VersionTuple(V0, V1, V2);
387 StringRef getPlatformFamily() const;
388 static StringRef getSDKName(StringRef isysroot);
389 StringRef getOSLibraryNameSuffix() const;
393 /// @name ToolChain Implementation
396 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
397 // most development is done against SDKs, so compiling for a different
398 // architecture should not get any special treatment.
399 bool isCrossCompiling() const override { return false; }
401 llvm::opt::DerivedArgList *
402 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
403 Action::OffloadKind DeviceOffloadKind) const override;
405 CXXStdlibType GetDefaultCXXStdlibType() const override;
406 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
407 bool hasBlocksRuntime() const override;
409 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
410 llvm::opt::ArgStringList &CC1Args) const override;
412 bool UseObjCMixedDispatch() const override {
413 // This is only used with the non-fragile ABI and non-legacy dispatch.
415 // Mixed dispatch is used everywhere except OS X before 10.6.
416 return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
419 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
420 // Stack protectors default to on for user code on 10.5,
421 // and for everything in 10.6 and beyond
422 if (isTargetIOSBased() || isTargetWatchOSBased())
424 else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
426 else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
432 bool SupportsObjCGC() const override;
434 void CheckObjCARC() const override;
436 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
438 bool SupportsEmbeddedBitcode() const override;
440 SanitizerMask getSupportedSanitizers() const override;
442 void printVerboseInfo(raw_ostream &OS) const override;
445 /// DarwinClang - The Darwin toolchain used by Clang.
446 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
448 DarwinClang(const Driver &D, const llvm::Triple &Triple,
449 const llvm::opt::ArgList &Args);
451 /// @name Apple ToolChain Implementation
454 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
456 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
457 llvm::opt::ArgStringList &CmdArgs) const override;
459 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
460 llvm::opt::ArgStringList &CmdArgs) const override;
462 void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
463 llvm::opt::ArgStringList &CmdArgs) const override;
465 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
467 void AddLinkARCArgs(const llvm::opt::ArgList &Args,
468 llvm::opt::ArgStringList &CmdArgs) const override;
470 unsigned GetDefaultDwarfVersion() const override;
471 // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
472 // Darwin defaults to standalone/full debug info.
473 bool GetDefaultStandaloneDebug() const override { return true; }
474 llvm::DebuggerKind getDefaultDebuggerTuning() const override {
475 return llvm::DebuggerKind::LLDB;
481 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
482 llvm::opt::ArgStringList &CmdArgs,
483 StringRef Sanitizer) const;
486 } // end namespace toolchains
487 } // end namespace driver
488 } // end namespace clang
490 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H