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