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