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