1 //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
13 #include "clang/Driver/DarwinSDKInfo.h"
14 #include "clang/Driver/Tool.h"
15 #include "clang/Driver/ToolChain.h"
16 #include "clang/Driver/XRayArgs.h"
21 namespace toolchains {
23 } // end namespace toolchains
28 llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
29 void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
31 class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
32 virtual void anchor();
35 void AddMachOArch(const llvm::opt::ArgList &Args,
36 llvm::opt::ArgStringList &CmdArgs) const;
38 const toolchains::MachO &getMachOToolChain() const {
39 return reinterpret_cast<const toolchains::MachO &>(getToolChain());
44 const char *Name, const char *ShortName, const ToolChain &TC,
45 ResponseFileSupport ResponseSupport = RF_None,
46 llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
47 const char *ResponseFlag = "@")
48 : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
52 class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
54 Assembler(const ToolChain &TC)
55 : MachOTool("darwin::Assembler", "assembler", TC) {}
57 bool hasIntegratedCPP() const override { return false; }
59 void ConstructJob(Compilation &C, const JobAction &JA,
60 const InputInfo &Output, const InputInfoList &Inputs,
61 const llvm::opt::ArgList &TCArgs,
62 const char *LinkingOutput) const override;
65 class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
66 bool NeedsTempPath(const InputInfoList &Inputs) const;
67 void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
68 llvm::opt::ArgStringList &CmdArgs,
69 const InputInfoList &Inputs) const;
72 Linker(const ToolChain &TC)
73 : MachOTool("darwin::Linker", "linker", TC, RF_FileList,
74 llvm::sys::WEM_UTF8, "-filelist") {}
76 bool hasIntegratedCPP() const override { return false; }
77 bool isLinkJob() const override { return true; }
79 void ConstructJob(Compilation &C, const JobAction &JA,
80 const InputInfo &Output, const InputInfoList &Inputs,
81 const llvm::opt::ArgList &TCArgs,
82 const char *LinkingOutput) const override;
85 class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
87 Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
89 bool hasIntegratedCPP() const override { return false; }
91 void ConstructJob(Compilation &C, const JobAction &JA,
92 const InputInfo &Output, const InputInfoList &Inputs,
93 const llvm::opt::ArgList &TCArgs,
94 const char *LinkingOutput) const override;
97 class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
99 Dsymutil(const ToolChain &TC)
100 : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
102 bool hasIntegratedCPP() const override { return false; }
103 bool isDsymutilJob() const override { return true; }
105 void ConstructJob(Compilation &C, const JobAction &JA,
106 const InputInfo &Output, const InputInfoList &Inputs,
107 const llvm::opt::ArgList &TCArgs,
108 const char *LinkingOutput) const override;
111 class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
113 VerifyDebug(const ToolChain &TC)
114 : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
116 bool hasIntegratedCPP() const override { return false; }
118 void ConstructJob(Compilation &C, const JobAction &JA,
119 const InputInfo &Output, const InputInfoList &Inputs,
120 const llvm::opt::ArgList &TCArgs,
121 const char *LinkingOutput) const override;
123 } // end namespace darwin
124 } // end namespace tools
126 namespace toolchains {
128 class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
130 Tool *buildAssembler() const override;
131 Tool *buildLinker() const override;
132 Tool *getTool(Action::ActionClass AC) const override;
135 mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
136 mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
137 mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
140 MachO(const Driver &D, const llvm::Triple &Triple,
141 const llvm::opt::ArgList &Args);
144 /// @name MachO specific toolchain API
147 /// Get the "MachO" arch name for a particular compiler invocation. For
148 /// example, Apple treats different ARM variations as distinct architectures.
149 StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
151 /// Add the linker arguments to link the ARC runtime library.
152 virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
153 llvm::opt::ArgStringList &CmdArgs) const {}
155 /// Add the linker arguments to link the compiler runtime library.
157 /// FIXME: This API is intended for use with embedded libraries only, and is
158 /// misleadingly named.
159 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
160 llvm::opt::ArgStringList &CmdArgs,
161 bool ForceLinkBuiltinRT = false) const;
163 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
164 llvm::opt::ArgStringList &CmdArgs) const {
167 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
168 llvm::opt::ArgStringList &CmdArgs) const {}
170 /// On some iOS platforms, kernel and kernel modules were built statically. Is
171 /// this such a target?
172 virtual bool isKernelStatic() const { return false; }
174 /// Is the target either iOS or an iOS simulator?
175 bool isTargetIOSBased() const { return false; }
177 /// Options to control how a runtime library is linked.
178 enum RuntimeLinkOptions : unsigned {
179 /// Link the library in even if it can't be found in the VFS.
180 RLO_AlwaysLink = 1 << 0,
182 /// Use the embedded runtime from the macho_embedded directory.
183 RLO_IsEmbedded = 1 << 1,
185 /// Emit rpaths for @executable_path as well as the resource directory.
186 RLO_AddRPath = 1 << 2,
188 /// Link the library in before any others.
189 RLO_FirstLink = 1 << 3,
192 /// Add a runtime library to the list of items to link.
193 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
194 llvm::opt::ArgStringList &CmdArgs, StringRef Component,
195 RuntimeLinkOptions Opts = RuntimeLinkOptions(),
196 bool IsShared = false) const;
198 /// Add any profiling runtime libraries that are needed. This is essentially a
199 /// MachO specific version of addProfileRT in Tools.cpp.
200 void addProfileRTLibs(const llvm::opt::ArgList &Args,
201 llvm::opt::ArgStringList &CmdArgs) const override {
202 // There aren't any profiling libs for embedded targets currently.
206 /// @name ToolChain Implementation
209 types::ID LookupTypeForExtension(StringRef Ext) const override;
211 bool HasNativeLLVMSupport() const override;
213 llvm::opt::DerivedArgList *
214 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
215 Action::OffloadKind DeviceOffloadKind) const override;
217 bool IsBlocksDefault() const override {
218 // Always allow blocks on Apple; users interested in versioning are
219 // expected to use /usr/include/Block.h.
222 bool IsIntegratedAssemblerDefault() const override {
223 // Default integrated assembler to on for Apple's MachO targets.
227 bool IsMathErrnoDefault() const override { return false; }
229 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
231 bool IsObjCNonFragileABIDefault() const override {
232 // Non-fragile ABI is default for everything but i386.
233 return getTriple().getArch() != llvm::Triple::x86;
236 bool UseObjCMixedDispatch() const override { return true; }
238 bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
240 RuntimeLibType GetDefaultRuntimeLibType() const override {
241 return ToolChain::RLT_CompilerRT;
244 bool isPICDefault() const override;
245 bool isPIEDefault() const override;
246 bool isPICDefaultForced() const override;
248 bool SupportsProfiling() const override;
250 bool UseDwarfDebugFlags() const override;
252 llvm::ExceptionHandling
253 GetExceptionModel(const llvm::opt::ArgList &Args) const override {
254 return llvm::ExceptionHandling::None;
257 virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const {
264 /// Darwin - The base Darwin tool chain.
265 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
267 /// Whether the information on the target has been initialized.
269 // FIXME: This should be eliminated. What we want to do is make this part of
270 // the "default target for arguments" selection process, once we get out of
271 // the argument translation business.
272 mutable bool TargetInitialized;
274 enum DarwinPlatformKind {
279 LastDarwinPlatform = WatchOS
281 enum DarwinEnvironmentKind {
286 mutable DarwinPlatformKind TargetPlatform;
287 mutable DarwinEnvironmentKind TargetEnvironment;
289 /// The OS version we are targeting.
290 mutable VersionTuple TargetVersion;
292 /// The information about the darwin SDK that was used.
293 mutable Optional<DarwinSDKInfo> SDKInfo;
295 CudaInstallationDetector CudaInstallation;
298 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
301 Darwin(const Driver &D, const llvm::Triple &Triple,
302 const llvm::opt::ArgList &Args);
305 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
306 types::ID InputType) const override;
308 /// @name Apple Specific Toolchain Implementation
311 void addMinVersionArgs(const llvm::opt::ArgList &Args,
312 llvm::opt::ArgStringList &CmdArgs) const override;
314 void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
315 llvm::opt::ArgStringList &CmdArgs) const override;
317 bool isKernelStatic() const override {
318 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
322 void addProfileRTLibs(const llvm::opt::ArgList &Args,
323 llvm::opt::ArgStringList &CmdArgs) const override;
327 /// @name Darwin specific Toolchain functions
330 // FIXME: Eliminate these ...Target functions and derive separate tool chains
331 // for these targets and put version in constructor.
332 void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
333 unsigned Major, unsigned Minor, unsigned Micro) const {
334 // FIXME: For now, allow reinitialization as long as values don't
335 // change. This will go away when we move away from argument translation.
336 if (TargetInitialized && TargetPlatform == Platform &&
337 TargetEnvironment == Environment &&
338 TargetVersion == VersionTuple(Major, Minor, Micro))
341 assert(!TargetInitialized && "Target already initialized!");
342 TargetInitialized = true;
343 TargetPlatform = Platform;
344 TargetEnvironment = Environment;
345 TargetVersion = VersionTuple(Major, Minor, Micro);
346 if (Environment == Simulator)
347 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
350 bool isTargetIPhoneOS() const {
351 assert(TargetInitialized && "Target not initialized!");
352 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
353 TargetEnvironment == NativeEnvironment;
356 bool isTargetIOSSimulator() const {
357 assert(TargetInitialized && "Target not initialized!");
358 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) &&
359 TargetEnvironment == Simulator;
362 bool isTargetIOSBased() const {
363 assert(TargetInitialized && "Target not initialized!");
364 return isTargetIPhoneOS() || isTargetIOSSimulator();
367 bool isTargetTvOS() const {
368 assert(TargetInitialized && "Target not initialized!");
369 return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
372 bool isTargetTvOSSimulator() const {
373 assert(TargetInitialized && "Target not initialized!");
374 return TargetPlatform == TvOS && TargetEnvironment == Simulator;
377 bool isTargetTvOSBased() const {
378 assert(TargetInitialized && "Target not initialized!");
379 return TargetPlatform == TvOS;
382 bool isTargetWatchOS() const {
383 assert(TargetInitialized && "Target not initialized!");
384 return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment;
387 bool isTargetWatchOSSimulator() const {
388 assert(TargetInitialized && "Target not initialized!");
389 return TargetPlatform == WatchOS && TargetEnvironment == Simulator;
392 bool isTargetWatchOSBased() const {
393 assert(TargetInitialized && "Target not initialized!");
394 return TargetPlatform == WatchOS;
397 bool isTargetMacOS() const {
398 assert(TargetInitialized && "Target not initialized!");
399 return TargetPlatform == MacOS;
402 bool isTargetInitialized() const { return TargetInitialized; }
404 VersionTuple getTargetVersion() const {
405 assert(TargetInitialized && "Target not initialized!");
406 return TargetVersion;
409 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
410 unsigned V2 = 0) const {
411 assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
412 return TargetVersion < VersionTuple(V0, V1, V2);
415 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
416 assert(isTargetMacOS() && "Unexpected call for non OS X target!");
417 return TargetVersion < VersionTuple(V0, V1, V2);
420 /// Return true if c++17 aligned allocation/deallocation functions are not
421 /// implemented in the c++ standard library of the deployment target we are
423 bool isAlignedAllocationUnavailable() const;
425 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
426 llvm::opt::ArgStringList &CC1Args,
427 Action::OffloadKind DeviceOffloadKind) const override;
429 StringRef getPlatformFamily() const;
430 StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override;
433 static StringRef getSDKName(StringRef isysroot);
436 /// @name ToolChain Implementation
439 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
440 // most development is done against SDKs, so compiling for a different
441 // architecture should not get any special treatment.
442 bool isCrossCompiling() const override { return false; }
444 llvm::opt::DerivedArgList *
445 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
446 Action::OffloadKind DeviceOffloadKind) const override;
448 CXXStdlibType GetDefaultCXXStdlibType() const override;
449 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
450 bool hasBlocksRuntime() const override;
452 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
453 llvm::opt::ArgStringList &CC1Args) const override;
455 bool UseObjCMixedDispatch() const override {
456 // This is only used with the non-fragile ABI and non-legacy dispatch.
458 // Mixed dispatch is used everywhere except OS X before 10.6.
459 return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
462 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
463 // Stack protectors default to on for user code on 10.5,
464 // and for everything in 10.6 and beyond
465 if (isTargetIOSBased() || isTargetWatchOSBased())
467 else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
469 else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
475 void CheckObjCARC() const override;
477 llvm::ExceptionHandling GetExceptionModel(
478 const llvm::opt::ArgList &Args) const override;
480 bool SupportsEmbeddedBitcode() const override;
482 SanitizerMask getSupportedSanitizers() const override;
484 void printVerboseInfo(raw_ostream &OS) const override;
487 /// DarwinClang - The Darwin toolchain used by Clang.
488 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
490 DarwinClang(const Driver &D, const llvm::Triple &Triple,
491 const llvm::opt::ArgList &Args);
493 /// @name Apple ToolChain Implementation
496 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
498 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
499 llvm::opt::ArgStringList &CmdArgs,
500 bool ForceLinkBuiltinRT = false) const override;
502 void AddClangCXXStdlibIncludeArgs(
503 const llvm::opt::ArgList &DriverArgs,
504 llvm::opt::ArgStringList &CC1Args) const override;
506 void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
507 llvm::opt::ArgStringList &CC1Args) const override;
509 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
510 llvm::opt::ArgStringList &CmdArgs) const override;
512 void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
513 llvm::opt::ArgStringList &CmdArgs) const override;
515 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
517 void AddLinkARCArgs(const llvm::opt::ArgList &Args,
518 llvm::opt::ArgStringList &CmdArgs) const override;
520 unsigned GetDefaultDwarfVersion() const override;
521 // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
522 // Darwin defaults to standalone/full debug info.
523 bool GetDefaultStandaloneDebug() const override { return true; }
524 llvm::DebuggerKind getDefaultDebuggerTuning() const override {
525 return llvm::DebuggerKind::LLDB;
531 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
532 llvm::opt::ArgStringList &CmdArgs,
534 bool shared = true) const;
536 bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
537 llvm::opt::ArgStringList &CC1Args,
538 llvm::SmallString<128> Base,
539 llvm::StringRef Version,
540 llvm::StringRef ArchDir,
541 llvm::StringRef BitDir) const;
543 llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const;
546 } // end namespace toolchains
547 } // end namespace driver
548 } // end namespace clang
550 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H