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 | /// } |
227 | /// @name ToolChain Implementation |
228 | /// { |
229 | |
230 | types::ID LookupTypeForExtension(StringRef Ext) const override; |
231 | |
232 | bool HasNativeLLVMSupport() const override; |
233 | |
234 | llvm::opt::DerivedArgList * |
235 | TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, |
236 | Action::OffloadKind DeviceOffloadKind) const override; |
237 | |
238 | bool IsBlocksDefault() const override { |
239 | // Always allow blocks on Apple; users interested in versioning are |
240 | // expected to use /usr/include/Block.h. |
241 | return true; |
242 | } |
243 | |
244 | bool IsMathErrnoDefault() const override { return false; } |
245 | |
246 | bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } |
247 | |
248 | bool IsObjCNonFragileABIDefault() const override { |
249 | // Non-fragile ABI is default for everything but i386. |
250 | return getTriple().getArch() != llvm::Triple::x86; |
251 | } |
252 | |
253 | bool UseObjCMixedDispatch() const override { return true; } |
254 | |
255 | UnwindTableLevel |
256 | getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; |
257 | |
258 | RuntimeLibType GetDefaultRuntimeLibType() const override { |
259 | return ToolChain::RLT_CompilerRT; |
260 | } |
261 | |
262 | bool isPICDefault() const override; |
263 | bool isPIEDefault(const llvm::opt::ArgList &Args) const override; |
264 | bool isPICDefaultForced() const override; |
265 | |
266 | bool SupportsProfiling() const override; |
267 | |
268 | bool UseDwarfDebugFlags() const override; |
269 | std::string GetGlobalDebugPathRemapping() const override; |
270 | |
271 | llvm::ExceptionHandling |
272 | GetExceptionModel(const llvm::opt::ArgList &Args) const override { |
273 | return llvm::ExceptionHandling::None; |
274 | } |
275 | |
276 | virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { |
277 | return "" ; |
278 | } |
279 | |
280 | // Darwin toolchain uses legacy thin LTO API, which is not |
281 | // capable of unit splitting. |
282 | bool canSplitThinLTOUnit() const override { return false; } |
283 | /// } |
284 | }; |
285 | |
286 | /// Darwin - The base Darwin tool chain. |
287 | class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { |
288 | public: |
289 | /// Whether the information on the target has been initialized. |
290 | // |
291 | // FIXME: This should be eliminated. What we want to do is make this part of |
292 | // the "default target for arguments" selection process, once we get out of |
293 | // the argument translation business. |
294 | mutable bool TargetInitialized; |
295 | |
296 | enum DarwinPlatformKind { |
297 | MacOS, |
298 | IPhoneOS, |
299 | TvOS, |
300 | WatchOS, |
301 | DriverKit, |
302 | XROS, |
303 | LastDarwinPlatform = XROS |
304 | }; |
305 | enum DarwinEnvironmentKind { |
306 | NativeEnvironment, |
307 | Simulator, |
308 | MacCatalyst, |
309 | }; |
310 | |
311 | mutable DarwinPlatformKind TargetPlatform; |
312 | mutable DarwinEnvironmentKind TargetEnvironment; |
313 | |
314 | /// The native OS version we are targeting. |
315 | mutable VersionTuple TargetVersion; |
316 | /// The OS version we are targeting as specified in the triple. |
317 | mutable VersionTuple OSTargetVersion; |
318 | |
319 | /// The information about the darwin SDK that was used. |
320 | mutable std::optional<DarwinSDKInfo> SDKInfo; |
321 | |
322 | /// The target variant triple that was specified (if any). |
323 | mutable std::optional<llvm::Triple> TargetVariantTriple; |
324 | |
325 | LazyDetector<CudaInstallationDetector> CudaInstallation; |
326 | LazyDetector<RocmInstallationDetector> RocmInstallation; |
327 | |
328 | private: |
329 | void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; |
330 | |
331 | public: |
332 | Darwin(const Driver &D, const llvm::Triple &Triple, |
333 | const llvm::opt::ArgList &Args); |
334 | ~Darwin() override; |
335 | |
336 | std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, |
337 | types::ID InputType) const override; |
338 | |
339 | /// @name Apple Specific Toolchain Implementation |
340 | /// { |
341 | |
342 | void addMinVersionArgs(const llvm::opt::ArgList &Args, |
343 | llvm::opt::ArgStringList &CmdArgs) const override; |
344 | |
345 | void addPlatformVersionArgs(const llvm::opt::ArgList &Args, |
346 | llvm::opt::ArgStringList &CmdArgs) const override; |
347 | |
348 | void addStartObjectFileArgs(const llvm::opt::ArgList &Args, |
349 | llvm::opt::ArgStringList &CmdArgs) const override; |
350 | |
351 | bool isKernelStatic() const override { |
352 | return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(V0: 6, V1: 0)) && |
353 | !isTargetWatchOS() && !isTargetDriverKit()); |
354 | } |
355 | |
356 | void addProfileRTLibs(const llvm::opt::ArgList &Args, |
357 | llvm::opt::ArgStringList &CmdArgs) const override; |
358 | |
359 | protected: |
360 | /// } |
361 | /// @name Darwin specific Toolchain functions |
362 | /// { |
363 | |
364 | // FIXME: Eliminate these ...Target functions and derive separate tool chains |
365 | // for these targets and put version in constructor. |
366 | void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, |
367 | unsigned Major, unsigned Minor, unsigned Micro, |
368 | VersionTuple NativeTargetVersion) const { |
369 | // FIXME: For now, allow reinitialization as long as values don't |
370 | // change. This will go away when we move away from argument translation. |
371 | if (TargetInitialized && TargetPlatform == Platform && |
372 | TargetEnvironment == Environment && |
373 | (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == |
374 | VersionTuple(Major, Minor, Micro)) |
375 | return; |
376 | |
377 | assert(!TargetInitialized && "Target already initialized!" ); |
378 | TargetInitialized = true; |
379 | TargetPlatform = Platform; |
380 | TargetEnvironment = Environment; |
381 | TargetVersion = VersionTuple(Major, Minor, Micro); |
382 | if (Environment == Simulator) |
383 | const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); |
384 | else if (Environment == MacCatalyst) { |
385 | const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); |
386 | TargetVersion = NativeTargetVersion; |
387 | OSTargetVersion = VersionTuple(Major, Minor, Micro); |
388 | } |
389 | } |
390 | |
391 | public: |
392 | bool isTargetIPhoneOS() const { |
393 | assert(TargetInitialized && "Target not initialized!" ); |
394 | return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && |
395 | TargetEnvironment == NativeEnvironment; |
396 | } |
397 | |
398 | bool isTargetIOSSimulator() const { |
399 | assert(TargetInitialized && "Target not initialized!" ); |
400 | return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && |
401 | TargetEnvironment == Simulator; |
402 | } |
403 | |
404 | bool isTargetIOSBased() const { |
405 | assert(TargetInitialized && "Target not initialized!" ); |
406 | return isTargetIPhoneOS() || isTargetIOSSimulator(); |
407 | } |
408 | |
409 | bool isTargetXROSDevice() const { |
410 | return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment; |
411 | } |
412 | |
413 | bool isTargetXROSSimulator() const { |
414 | return TargetPlatform == XROS && TargetEnvironment == Simulator; |
415 | } |
416 | |
417 | bool isTargetXROS() const { return TargetPlatform == XROS; } |
418 | |
419 | bool isTargetTvOS() const { |
420 | assert(TargetInitialized && "Target not initialized!" ); |
421 | return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; |
422 | } |
423 | |
424 | bool isTargetTvOSSimulator() const { |
425 | assert(TargetInitialized && "Target not initialized!" ); |
426 | return TargetPlatform == TvOS && TargetEnvironment == Simulator; |
427 | } |
428 | |
429 | bool isTargetTvOSBased() const { |
430 | assert(TargetInitialized && "Target not initialized!" ); |
431 | return TargetPlatform == TvOS; |
432 | } |
433 | |
434 | bool isTargetWatchOS() const { |
435 | assert(TargetInitialized && "Target not initialized!" ); |
436 | return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; |
437 | } |
438 | |
439 | bool isTargetWatchOSSimulator() const { |
440 | assert(TargetInitialized && "Target not initialized!" ); |
441 | return TargetPlatform == WatchOS && TargetEnvironment == Simulator; |
442 | } |
443 | |
444 | bool isTargetWatchOSBased() const { |
445 | assert(TargetInitialized && "Target not initialized!" ); |
446 | return TargetPlatform == WatchOS; |
447 | } |
448 | |
449 | bool isTargetDriverKit() const { |
450 | assert(TargetInitialized && "Target not initialized!" ); |
451 | return TargetPlatform == DriverKit; |
452 | } |
453 | |
454 | bool isTargetMacCatalyst() const { |
455 | return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; |
456 | } |
457 | |
458 | bool isTargetMacOS() const { |
459 | assert(TargetInitialized && "Target not initialized!" ); |
460 | return TargetPlatform == MacOS; |
461 | } |
462 | |
463 | bool isTargetMacOSBased() const { |
464 | assert(TargetInitialized && "Target not initialized!" ); |
465 | return TargetPlatform == MacOS || isTargetMacCatalyst(); |
466 | } |
467 | |
468 | bool isTargetAppleSiliconMac() const { |
469 | assert(TargetInitialized && "Target not initialized!" ); |
470 | return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; |
471 | } |
472 | |
473 | bool isTargetInitialized() const { return TargetInitialized; } |
474 | |
475 | /// The version of the OS that's used by the OS specified in the target |
476 | /// triple. It might be different from the actual target OS on which the |
477 | /// program will run, e.g. MacCatalyst code runs on a macOS target, but its |
478 | /// target triple is iOS. |
479 | VersionTuple getTripleTargetVersion() const { |
480 | assert(TargetInitialized && "Target not initialized!" ); |
481 | return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; |
482 | } |
483 | |
484 | bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, |
485 | unsigned V2 = 0) const { |
486 | assert(isTargetIOSBased() && "Unexpected call for non iOS target!" ); |
487 | return TargetVersion < VersionTuple(V0, V1, V2); |
488 | } |
489 | |
490 | /// Returns true if the minimum supported macOS version for the slice that's |
491 | /// being built is less than the specified version. If there's no minimum |
492 | /// supported macOS version, the deployment target version is compared to the |
493 | /// specifed version instead. |
494 | bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { |
495 | assert(isTargetMacOSBased() && |
496 | (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && |
497 | "Unexpected call for non OS X target!" ); |
498 | // The effective triple might not be initialized yet, so construct a |
499 | // pseudo-effective triple to get the minimum supported OS version. |
500 | VersionTuple MinVers = |
501 | llvm::Triple(getTriple().getArchName(), "apple" , "macos" ) |
502 | .getMinimumSupportedOSVersion(); |
503 | return (!MinVers.empty() && MinVers > TargetVersion |
504 | ? MinVers |
505 | : TargetVersion) < VersionTuple(V0, V1, V2); |
506 | } |
507 | |
508 | protected: |
509 | /// Return true if c++17 aligned allocation/deallocation functions are not |
510 | /// implemented in the c++ standard library of the deployment target we are |
511 | /// targeting. |
512 | bool isAlignedAllocationUnavailable() const; |
513 | |
514 | void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, |
515 | llvm::opt::ArgStringList &CC1Args, |
516 | Action::OffloadKind DeviceOffloadKind) const override; |
517 | |
518 | void addClangCC1ASTargetOptions( |
519 | const llvm::opt::ArgList &Args, |
520 | llvm::opt::ArgStringList &CC1ASArgs) const override; |
521 | |
522 | StringRef getPlatformFamily() const; |
523 | StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; |
524 | |
525 | public: |
526 | static StringRef getSDKName(StringRef isysroot); |
527 | |
528 | /// } |
529 | /// @name ToolChain Implementation |
530 | /// { |
531 | |
532 | // Darwin tools support multiple architecture (e.g., i386 and x86_64) and |
533 | // most development is done against SDKs, so compiling for a different |
534 | // architecture should not get any special treatment. |
535 | bool isCrossCompiling() const override { return false; } |
536 | |
537 | llvm::opt::DerivedArgList * |
538 | TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, |
539 | Action::OffloadKind DeviceOffloadKind) const override; |
540 | |
541 | CXXStdlibType GetDefaultCXXStdlibType() const override; |
542 | ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; |
543 | bool hasBlocksRuntime() const override; |
544 | |
545 | void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
546 | llvm::opt::ArgStringList &CC1Args) const override; |
547 | void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
548 | llvm::opt::ArgStringList &CC1Args) const override; |
549 | |
550 | bool UseObjCMixedDispatch() const override { |
551 | // This is only used with the non-fragile ABI and non-legacy dispatch. |
552 | |
553 | // Mixed dispatch is used everywhere except OS X before 10.6. |
554 | return !(isTargetMacOSBased() && isMacosxVersionLT(V0: 10, V1: 6)); |
555 | } |
556 | |
557 | LangOptions::StackProtectorMode |
558 | GetDefaultStackProtectorLevel(bool KernelOrKext) const override { |
559 | // Stack protectors default to on for user code on 10.5, |
560 | // and for everything in 10.6 and beyond |
561 | if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() || |
562 | isTargetXROS()) |
563 | return LangOptions::SSPOn; |
564 | else if (isTargetMacOSBased() && !isMacosxVersionLT(V0: 10, V1: 6)) |
565 | return LangOptions::SSPOn; |
566 | else if (isTargetMacOSBased() && !isMacosxVersionLT(V0: 10, V1: 5) && !KernelOrKext) |
567 | return LangOptions::SSPOn; |
568 | |
569 | return LangOptions::SSPOff; |
570 | } |
571 | |
572 | void CheckObjCARC() const override; |
573 | |
574 | llvm::ExceptionHandling GetExceptionModel( |
575 | const llvm::opt::ArgList &Args) const override; |
576 | |
577 | bool SupportsEmbeddedBitcode() const override; |
578 | |
579 | SanitizerMask getSupportedSanitizers() const override; |
580 | |
581 | void printVerboseInfo(raw_ostream &OS) const override; |
582 | }; |
583 | |
584 | /// DarwinClang - The Darwin toolchain used by Clang. |
585 | class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { |
586 | public: |
587 | DarwinClang(const Driver &D, const llvm::Triple &Triple, |
588 | const llvm::opt::ArgList &Args); |
589 | |
590 | /// @name Apple ToolChain Implementation |
591 | /// { |
592 | |
593 | RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; |
594 | |
595 | void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, |
596 | llvm::opt::ArgStringList &CmdArgs, |
597 | bool ForceLinkBuiltinRT = false) const override; |
598 | |
599 | void AddClangCXXStdlibIncludeArgs( |
600 | const llvm::opt::ArgList &DriverArgs, |
601 | llvm::opt::ArgStringList &CC1Args) const override; |
602 | |
603 | void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, |
604 | llvm::opt::ArgStringList &CC1Args) const override; |
605 | |
606 | void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, |
607 | llvm::opt::ArgStringList &CmdArgs) const override; |
608 | |
609 | void AddCCKextLibArgs(const llvm::opt::ArgList &Args, |
610 | llvm::opt::ArgStringList &CmdArgs) const override; |
611 | |
612 | void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; |
613 | |
614 | void AddLinkARCArgs(const llvm::opt::ArgList &Args, |
615 | llvm::opt::ArgStringList &CmdArgs) const override; |
616 | |
617 | unsigned GetDefaultDwarfVersion() const override; |
618 | // Until dtrace (via CTF) and LLDB can deal with distributed debug info, |
619 | // Darwin defaults to standalone/full debug info. |
620 | bool GetDefaultStandaloneDebug() const override { return true; } |
621 | llvm::DebuggerKind getDefaultDebuggerTuning() const override { |
622 | return llvm::DebuggerKind::LLDB; |
623 | } |
624 | |
625 | /// } |
626 | |
627 | private: |
628 | void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, |
629 | llvm::opt::ArgStringList &CmdArgs, |
630 | StringRef Sanitizer, |
631 | bool shared = true) const; |
632 | |
633 | bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, |
634 | llvm::opt::ArgStringList &CC1Args, |
635 | llvm::SmallString<128> Base, |
636 | llvm::StringRef Version, |
637 | llvm::StringRef ArchDir, |
638 | llvm::StringRef BitDir) const; |
639 | |
640 | llvm::SmallString<128> |
641 | GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; |
642 | }; |
643 | |
644 | } // end namespace toolchains |
645 | } // end namespace driver |
646 | } // end namespace clang |
647 | |
648 | #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H |
649 | |