1 | //===--- OSTargets.h - Declare OS target feature support --------*- 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 | // This file declares OS specific TargetInfo types. |
10 | //===----------------------------------------------------------------------===// |
11 | |
12 | #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H |
13 | #define LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H |
14 | |
15 | #include "Targets.h" |
16 | |
17 | namespace clang { |
18 | namespace targets { |
19 | |
20 | template <typename TgtInfo> |
21 | class LLVM_LIBRARY_VISIBILITY OSTargetInfo : public TgtInfo { |
22 | protected: |
23 | virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
24 | MacroBuilder &Builder) const = 0; |
25 | |
26 | public: |
27 | OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
28 | : TgtInfo(Triple, Opts) {} |
29 | |
30 | void getTargetDefines(const LangOptions &Opts, |
31 | MacroBuilder &Builder) const override { |
32 | TgtInfo::getTargetDefines(Opts, Builder); |
33 | getOSDefines(Opts, Triple: TgtInfo::getTriple(), Builder); |
34 | } |
35 | }; |
36 | |
37 | void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, |
38 | const llvm::Triple &Triple, StringRef &PlatformName, |
39 | VersionTuple &PlatformMinVersion); |
40 | |
41 | template <typename Target> |
42 | class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> { |
43 | protected: |
44 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
45 | MacroBuilder &Builder) const override { |
46 | getDarwinDefines(Builder, Opts, Triple, this->PlatformName, |
47 | this->PlatformMinVersion); |
48 | } |
49 | |
50 | public: |
51 | DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
52 | : OSTargetInfo<Target>(Triple, Opts) { |
53 | // By default, no TLS, and we list permitted architecture/OS |
54 | // combinations. |
55 | this->TLSSupported = false; |
56 | |
57 | if (Triple.isMacOSX()) |
58 | this->TLSSupported = !Triple.isMacOSXVersionLT(Major: 10, Minor: 7); |
59 | else if (Triple.isiOS()) { |
60 | // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards, |
61 | // 32-bit simulator from 10 onwards. |
62 | if (Triple.isArch64Bit()) |
63 | this->TLSSupported = !Triple.isOSVersionLT(Major: 8); |
64 | else if (Triple.isArch32Bit()) { |
65 | if (!Triple.isSimulatorEnvironment()) |
66 | this->TLSSupported = !Triple.isOSVersionLT(Major: 9); |
67 | else |
68 | this->TLSSupported = !Triple.isOSVersionLT(Major: 10); |
69 | } |
70 | } else if (Triple.isWatchOS()) { |
71 | if (!Triple.isSimulatorEnvironment()) |
72 | this->TLSSupported = !Triple.isOSVersionLT(Major: 2); |
73 | else |
74 | this->TLSSupported = !Triple.isOSVersionLT(Major: 3); |
75 | } else if (Triple.isDriverKit()) { |
76 | // No TLS on DriverKit. |
77 | } else if (Triple.isXROS()) |
78 | this->TLSSupported = true; |
79 | |
80 | this->MCountName = "\01mcount" ; |
81 | } |
82 | |
83 | const char *getStaticInitSectionSpecifier() const override { |
84 | // FIXME: We should return 0 when building kexts. |
85 | return "__TEXT,__StaticInit,regular,pure_instructions" ; |
86 | } |
87 | |
88 | /// Darwin does not support protected visibility. Darwin's "default" |
89 | /// is very similar to ELF's "protected"; Darwin requires a "weak" |
90 | /// attribute on declarations that can be dynamically replaced. |
91 | bool hasProtectedVisibility() const override { return false; } |
92 | |
93 | unsigned getExnObjectAlignment() const override { |
94 | // Older versions of libc++abi guarantee an alignment of only 8-bytes for |
95 | // exception objects because of a bug in __cxa_exception that was |
96 | // eventually fixed in r319123. |
97 | llvm::VersionTuple MinVersion; |
98 | const llvm::Triple &T = this->getTriple(); |
99 | |
100 | // Compute the earliest OS versions that have the fix to libc++abi. |
101 | switch (T.getOS()) { |
102 | case llvm::Triple::Darwin: |
103 | case llvm::Triple::MacOSX: // Earliest supporting version is 10.14. |
104 | MinVersion = llvm::VersionTuple(10U, 14U); |
105 | break; |
106 | case llvm::Triple::IOS: |
107 | case llvm::Triple::TvOS: // Earliest supporting version is 12.0.0. |
108 | MinVersion = llvm::VersionTuple(12U); |
109 | break; |
110 | case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0. |
111 | MinVersion = llvm::VersionTuple(5U); |
112 | break; |
113 | case llvm::Triple::XROS: |
114 | MinVersion = llvm::VersionTuple(0); |
115 | break; |
116 | default: |
117 | // Conservatively return 8 bytes if OS is unknown. |
118 | return 64; |
119 | } |
120 | |
121 | if (T.getOSVersion() < MinVersion) |
122 | return 64; |
123 | return OSTargetInfo<Target>::getExnObjectAlignment(); |
124 | } |
125 | |
126 | TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth, |
127 | bool IsSigned) const final { |
128 | // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`. |
129 | return BitWidth == 64 |
130 | ? (IsSigned ? TargetInfo::SignedLongLong |
131 | : TargetInfo::UnsignedLongLong) |
132 | : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); |
133 | } |
134 | |
135 | bool areDefaultedSMFStillPOD(const LangOptions &) const override { |
136 | return false; |
137 | } |
138 | }; |
139 | |
140 | // DragonFlyBSD Target |
141 | template <typename Target> |
142 | class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo |
143 | : public OSTargetInfo<Target> { |
144 | protected: |
145 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
146 | MacroBuilder &Builder) const override { |
147 | // DragonFly defines; list based off of gcc output |
148 | Builder.defineMacro(Name: "__DragonFly__" ); |
149 | Builder.defineMacro(Name: "__DragonFly_cc_version" , Value: "100001" ); |
150 | Builder.defineMacro(Name: "__KPRINTF_ATTRIBUTE__" ); |
151 | Builder.defineMacro(Name: "__tune_i386__" ); |
152 | DefineStd(Builder, MacroName: "unix" , Opts); |
153 | if (this->HasFloat128) |
154 | Builder.defineMacro(Name: "__FLOAT128__" ); |
155 | } |
156 | |
157 | public: |
158 | DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
159 | : OSTargetInfo<Target>(Triple, Opts) { |
160 | switch (Triple.getArch()) { |
161 | default: |
162 | case llvm::Triple::x86: |
163 | case llvm::Triple::x86_64: |
164 | this->HasFloat128 = true; |
165 | this->MCountName = ".mcount" ; |
166 | break; |
167 | } |
168 | } |
169 | }; |
170 | |
171 | #ifndef FREEBSD_CC_VERSION |
172 | #define FREEBSD_CC_VERSION 0U |
173 | #endif |
174 | |
175 | // FreeBSD Target |
176 | template <typename Target> |
177 | class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> { |
178 | protected: |
179 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
180 | MacroBuilder &Builder) const override { |
181 | // FreeBSD defines; list based off of gcc output |
182 | |
183 | unsigned Release = Triple.getOSMajorVersion(); |
184 | if (Release == 0U) |
185 | Release = 8U; |
186 | unsigned CCVersion = FREEBSD_CC_VERSION; |
187 | if (CCVersion == 0U) |
188 | CCVersion = Release * 100000U + 1U; |
189 | |
190 | Builder.defineMacro(Name: "__FreeBSD__" , Value: Twine(Release)); |
191 | Builder.defineMacro(Name: "__FreeBSD_cc_version" , Value: Twine(CCVersion)); |
192 | Builder.defineMacro(Name: "__KPRINTF_ATTRIBUTE__" ); |
193 | DefineStd(Builder, MacroName: "unix" , Opts); |
194 | if (this->HasFloat128) |
195 | Builder.defineMacro(Name: "__FLOAT128__" ); |
196 | |
197 | // On FreeBSD, wchar_t contains the number of the code point as |
198 | // used by the character set of the locale. These character sets are |
199 | // not necessarily a superset of ASCII. |
200 | // |
201 | // FIXME: This is wrong; the macro refers to the numerical values |
202 | // of wchar_t *literals*, which are not locale-dependent. However, |
203 | // FreeBSD systems apparently depend on us getting this wrong, and |
204 | // setting this to 1 is conforming even if all the basic source |
205 | // character literals have the same encoding as char and wchar_t. |
206 | Builder.defineMacro(Name: "__STDC_MB_MIGHT_NEQ_WC__" , Value: "1" ); |
207 | } |
208 | |
209 | public: |
210 | FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
211 | : OSTargetInfo<Target>(Triple, Opts) { |
212 | switch (Triple.getArch()) { |
213 | case llvm::Triple::x86: |
214 | case llvm::Triple::x86_64: |
215 | this->HasFloat128 = true; |
216 | [[fallthrough]]; |
217 | default: |
218 | this->MCountName = ".mcount" ; |
219 | break; |
220 | case llvm::Triple::mips: |
221 | case llvm::Triple::mipsel: |
222 | case llvm::Triple::ppc: |
223 | case llvm::Triple::ppcle: |
224 | case llvm::Triple::ppc64: |
225 | case llvm::Triple::ppc64le: |
226 | this->MCountName = "_mcount" ; |
227 | break; |
228 | case llvm::Triple::arm: |
229 | this->MCountName = "__mcount" ; |
230 | break; |
231 | case llvm::Triple::riscv32: |
232 | case llvm::Triple::riscv64: |
233 | break; |
234 | } |
235 | } |
236 | }; |
237 | |
238 | // GNU/kFreeBSD Target |
239 | template <typename Target> |
240 | class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> { |
241 | protected: |
242 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
243 | MacroBuilder &Builder) const override { |
244 | // GNU/kFreeBSD defines; list based off of gcc output |
245 | |
246 | DefineStd(Builder, MacroName: "unix" , Opts); |
247 | Builder.defineMacro(Name: "__FreeBSD_kernel__" ); |
248 | Builder.defineMacro(Name: "__GLIBC__" ); |
249 | if (Opts.POSIXThreads) |
250 | Builder.defineMacro(Name: "_REENTRANT" ); |
251 | if (Opts.CPlusPlus) |
252 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
253 | } |
254 | |
255 | public: |
256 | using OSTargetInfo<Target>::OSTargetInfo; |
257 | }; |
258 | |
259 | // Haiku Target |
260 | template <typename Target> |
261 | class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> { |
262 | protected: |
263 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
264 | MacroBuilder &Builder) const override { |
265 | // Haiku defines; list based off of gcc output |
266 | Builder.defineMacro(Name: "__HAIKU__" ); |
267 | DefineStd(Builder, MacroName: "unix" , Opts); |
268 | if (this->HasFloat128) |
269 | Builder.defineMacro(Name: "__FLOAT128__" ); |
270 | } |
271 | |
272 | public: |
273 | HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
274 | : OSTargetInfo<Target>(Triple, Opts) { |
275 | this->SizeType = TargetInfo::UnsignedLong; |
276 | this->IntPtrType = TargetInfo::SignedLong; |
277 | this->PtrDiffType = TargetInfo::SignedLong; |
278 | this->ProcessIDType = TargetInfo::SignedLong; |
279 | switch (Triple.getArch()) { |
280 | default: |
281 | break; |
282 | case llvm::Triple::x86: |
283 | case llvm::Triple::x86_64: |
284 | this->HasFloat128 = true; |
285 | break; |
286 | } |
287 | } |
288 | }; |
289 | |
290 | // Hurd target |
291 | template <typename Target> |
292 | class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> { |
293 | protected: |
294 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
295 | MacroBuilder &Builder) const override { |
296 | // Hurd defines; list based off of gcc output. |
297 | DefineStd(Builder, MacroName: "unix" , Opts); |
298 | Builder.defineMacro(Name: "__GNU__" ); |
299 | Builder.defineMacro(Name: "__gnu_hurd__" ); |
300 | Builder.defineMacro(Name: "__MACH__" ); |
301 | Builder.defineMacro(Name: "__GLIBC__" ); |
302 | if (Opts.POSIXThreads) |
303 | Builder.defineMacro(Name: "_REENTRANT" ); |
304 | if (Opts.CPlusPlus) |
305 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
306 | } |
307 | public: |
308 | using OSTargetInfo<Target>::OSTargetInfo; |
309 | }; |
310 | |
311 | // Linux target |
312 | template <typename Target> |
313 | class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> { |
314 | protected: |
315 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
316 | MacroBuilder &Builder) const override { |
317 | // Linux defines; list based off of gcc output |
318 | DefineStd(Builder, MacroName: "unix" , Opts); |
319 | DefineStd(Builder, MacroName: "linux" , Opts); |
320 | if (Triple.isAndroid()) { |
321 | Builder.defineMacro(Name: "__ANDROID__" , Value: "1" ); |
322 | this->PlatformName = "android" ; |
323 | this->PlatformMinVersion = Triple.getEnvironmentVersion(); |
324 | const unsigned Maj = this->PlatformMinVersion.getMajor(); |
325 | if (Maj) { |
326 | Builder.defineMacro(Name: "__ANDROID_MIN_SDK_VERSION__" , Value: Twine(Maj)); |
327 | // This historical but ambiguous name for the minSdkVersion macro. Keep |
328 | // defined for compatibility. |
329 | Builder.defineMacro(Name: "__ANDROID_API__" , Value: "__ANDROID_MIN_SDK_VERSION__" ); |
330 | } |
331 | } else { |
332 | Builder.defineMacro(Name: "__gnu_linux__" ); |
333 | } |
334 | if (Opts.POSIXThreads) |
335 | Builder.defineMacro(Name: "_REENTRANT" ); |
336 | if (Opts.CPlusPlus) |
337 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
338 | if (this->HasFloat128) |
339 | Builder.defineMacro(Name: "__FLOAT128__" ); |
340 | } |
341 | |
342 | public: |
343 | LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
344 | : OSTargetInfo<Target>(Triple, Opts) { |
345 | this->WIntType = TargetInfo::UnsignedInt; |
346 | |
347 | switch (Triple.getArch()) { |
348 | default: |
349 | break; |
350 | case llvm::Triple::mips: |
351 | case llvm::Triple::mipsel: |
352 | case llvm::Triple::mips64: |
353 | case llvm::Triple::mips64el: |
354 | case llvm::Triple::ppc: |
355 | case llvm::Triple::ppcle: |
356 | case llvm::Triple::ppc64: |
357 | case llvm::Triple::ppc64le: |
358 | this->MCountName = "_mcount" ; |
359 | break; |
360 | case llvm::Triple::x86: |
361 | case llvm::Triple::x86_64: |
362 | this->HasFloat128 = true; |
363 | break; |
364 | } |
365 | } |
366 | |
367 | const char *getStaticInitSectionSpecifier() const override { |
368 | return ".text.startup" ; |
369 | } |
370 | }; |
371 | |
372 | // NetBSD Target |
373 | template <typename Target> |
374 | class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> { |
375 | protected: |
376 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
377 | MacroBuilder &Builder) const override { |
378 | // NetBSD defines; list based off of gcc output |
379 | Builder.defineMacro(Name: "__NetBSD__" ); |
380 | Builder.defineMacro(Name: "__unix__" ); |
381 | if (Opts.POSIXThreads) |
382 | Builder.defineMacro(Name: "_REENTRANT" ); |
383 | if (this->HasFloat128) |
384 | Builder.defineMacro(Name: "__FLOAT128__" ); |
385 | } |
386 | |
387 | public: |
388 | NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
389 | : OSTargetInfo<Target>(Triple, Opts) { |
390 | this->MCountName = "__mcount" ; |
391 | switch (Triple.getArch()) { |
392 | default: |
393 | break; |
394 | case llvm::Triple::x86: |
395 | case llvm::Triple::x86_64: |
396 | this->HasFloat128 = true; |
397 | break; |
398 | } |
399 | } |
400 | }; |
401 | |
402 | // OpenBSD Target |
403 | template <typename Target> |
404 | class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> { |
405 | protected: |
406 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
407 | MacroBuilder &Builder) const override { |
408 | // OpenBSD defines; list based off of gcc output |
409 | |
410 | Builder.defineMacro(Name: "__OpenBSD__" ); |
411 | DefineStd(Builder, MacroName: "unix" , Opts); |
412 | if (Opts.POSIXThreads) |
413 | Builder.defineMacro(Name: "_REENTRANT" ); |
414 | if (this->HasFloat128) |
415 | Builder.defineMacro(Name: "__FLOAT128__" ); |
416 | |
417 | if (Opts.C11) |
418 | Builder.defineMacro(Name: "__STDC_NO_THREADS__" ); |
419 | } |
420 | |
421 | public: |
422 | OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
423 | : OSTargetInfo<Target>(Triple, Opts) { |
424 | this->WCharType = this->WIntType = this->SignedInt; |
425 | this->IntMaxType = TargetInfo::SignedLongLong; |
426 | this->Int64Type = TargetInfo::SignedLongLong; |
427 | switch (Triple.getArch()) { |
428 | case llvm::Triple::x86: |
429 | case llvm::Triple::x86_64: |
430 | this->HasFloat128 = true; |
431 | [[fallthrough]]; |
432 | default: |
433 | this->MCountName = "__mcount" ; |
434 | break; |
435 | case llvm::Triple::mips64: |
436 | case llvm::Triple::mips64el: |
437 | case llvm::Triple::ppc: |
438 | case llvm::Triple::ppc64: |
439 | case llvm::Triple::ppc64le: |
440 | case llvm::Triple::sparcv9: |
441 | this->MCountName = "_mcount" ; |
442 | break; |
443 | case llvm::Triple::riscv32: |
444 | case llvm::Triple::riscv64: |
445 | break; |
446 | } |
447 | } |
448 | }; |
449 | |
450 | // PS3 PPU Target |
451 | template <typename Target> |
452 | class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> { |
453 | protected: |
454 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
455 | MacroBuilder &Builder) const override { |
456 | // PS3 PPU defines. |
457 | Builder.defineMacro(Name: "__PPU__" ); |
458 | Builder.defineMacro(Name: "__CELLOS_LV2__" ); |
459 | Builder.defineMacro(Name: "__LP32__" ); |
460 | Builder.defineMacro(Name: "_ARCH_PPC64" ); |
461 | Builder.defineMacro(Name: "__powerpc64__" ); |
462 | } |
463 | |
464 | public: |
465 | PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
466 | : OSTargetInfo<Target>(Triple, Opts) { |
467 | this->LongWidth = this->LongAlign = 32; |
468 | this->PointerWidth = this->PointerAlign = 32; |
469 | this->IntMaxType = TargetInfo::SignedLongLong; |
470 | this->Int64Type = TargetInfo::SignedLongLong; |
471 | this->SizeType = TargetInfo::UnsignedInt; |
472 | this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64" ); |
473 | } |
474 | }; |
475 | |
476 | // Common base class for PS4/PS5 targets. |
477 | template <typename Target> |
478 | class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> { |
479 | protected: |
480 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
481 | MacroBuilder &Builder) const override { |
482 | Builder.defineMacro(Name: "__FreeBSD__" , Value: "9" ); |
483 | Builder.defineMacro(Name: "__FreeBSD_cc_version" , Value: "900001" ); |
484 | Builder.defineMacro(Name: "__KPRINTF_ATTRIBUTE__" ); |
485 | DefineStd(Builder, MacroName: "unix" , Opts); |
486 | Builder.defineMacro(Name: "__SCE__" ); |
487 | Builder.defineMacro(Name: "__STDC_NO_COMPLEX__" ); |
488 | Builder.defineMacro(Name: "__STDC_NO_THREADS__" ); |
489 | } |
490 | |
491 | public: |
492 | PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
493 | : OSTargetInfo<Target>(Triple, Opts) { |
494 | this->WCharType = TargetInfo::UnsignedShort; |
495 | |
496 | // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256 |
497 | // bits). |
498 | this->MaxTLSAlign = 256; |
499 | |
500 | // On PS4/PS5, do not honor explicit bit field alignment, |
501 | // as in "__attribute__((aligned(2))) int b : 1;". |
502 | this->UseExplicitBitFieldAlignment = false; |
503 | |
504 | this->MCountName = ".mcount" ; |
505 | this->NewAlign = 256; |
506 | this->SuitableAlign = 256; |
507 | } |
508 | |
509 | TargetInfo::CallingConvCheckResult |
510 | checkCallingConvention(CallingConv CC) const override { |
511 | return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error; |
512 | } |
513 | |
514 | bool areDefaultedSMFStillPOD(const LangOptions &) const override { |
515 | return false; |
516 | } |
517 | }; |
518 | |
519 | // PS4 Target |
520 | template <typename Target> |
521 | class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> { |
522 | protected: |
523 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
524 | MacroBuilder &Builder) const override { |
525 | // Start with base class defines. |
526 | PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); |
527 | |
528 | Builder.defineMacro(Name: "__ORBIS__" ); |
529 | } |
530 | |
531 | public: |
532 | using PSOSTargetInfo<Target>::PSOSTargetInfo; |
533 | }; |
534 | |
535 | // PS5 Target |
536 | template <typename Target> |
537 | class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> { |
538 | protected: |
539 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
540 | MacroBuilder &Builder) const override { |
541 | // Start with base class defines. |
542 | PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); |
543 | |
544 | Builder.defineMacro(Name: "__PROSPERO__" ); |
545 | } |
546 | |
547 | public: |
548 | using PSOSTargetInfo<Target>::PSOSTargetInfo; |
549 | }; |
550 | |
551 | // RTEMS Target |
552 | template <typename Target> |
553 | class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> { |
554 | protected: |
555 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
556 | MacroBuilder &Builder) const override { |
557 | // RTEMS defines; list based off of gcc output |
558 | |
559 | Builder.defineMacro(Name: "__rtems__" ); |
560 | if (Opts.CPlusPlus) |
561 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
562 | } |
563 | |
564 | public: |
565 | RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
566 | : OSTargetInfo<Target>(Triple, Opts) { |
567 | switch (Triple.getArch()) { |
568 | default: |
569 | case llvm::Triple::x86: |
570 | // this->MCountName = ".mcount"; |
571 | break; |
572 | case llvm::Triple::mips: |
573 | case llvm::Triple::mipsel: |
574 | case llvm::Triple::ppc: |
575 | case llvm::Triple::ppc64: |
576 | case llvm::Triple::ppc64le: |
577 | // this->MCountName = "_mcount"; |
578 | break; |
579 | case llvm::Triple::arm: |
580 | // this->MCountName = "__mcount"; |
581 | break; |
582 | } |
583 | } |
584 | }; |
585 | |
586 | // Solaris target |
587 | template <typename Target> |
588 | class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> { |
589 | protected: |
590 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
591 | MacroBuilder &Builder) const override { |
592 | DefineStd(Builder, MacroName: "sun" , Opts); |
593 | DefineStd(Builder, MacroName: "unix" , Opts); |
594 | Builder.defineMacro(Name: "__svr4__" ); |
595 | Builder.defineMacro(Name: "__SVR4" ); |
596 | // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and |
597 | // newer, but to 500 for everything else. feature_test.h has a check to |
598 | // ensure that you are not using C99 with an old version of X/Open or C89 |
599 | // with a new version. |
600 | if (Opts.C99) |
601 | Builder.defineMacro(Name: "_XOPEN_SOURCE" , Value: "600" ); |
602 | else |
603 | Builder.defineMacro(Name: "_XOPEN_SOURCE" , Value: "500" ); |
604 | if (Opts.CPlusPlus) { |
605 | Builder.defineMacro(Name: "__C99FEATURES__" ); |
606 | Builder.defineMacro(Name: "_FILE_OFFSET_BITS" , Value: "64" ); |
607 | } |
608 | // GCC restricts the next two to C++. |
609 | Builder.defineMacro(Name: "_LARGEFILE_SOURCE" ); |
610 | Builder.defineMacro(Name: "_LARGEFILE64_SOURCE" ); |
611 | Builder.defineMacro(Name: "__EXTENSIONS__" ); |
612 | if (Opts.POSIXThreads) |
613 | Builder.defineMacro(Name: "_REENTRANT" ); |
614 | if (this->HasFloat128) |
615 | Builder.defineMacro(Name: "__FLOAT128__" ); |
616 | } |
617 | |
618 | public: |
619 | SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
620 | : OSTargetInfo<Target>(Triple, Opts) { |
621 | if (this->PointerWidth == 64) { |
622 | this->WCharType = this->WIntType = this->SignedInt; |
623 | } else { |
624 | this->WCharType = this->WIntType = this->SignedLong; |
625 | } |
626 | switch (Triple.getArch()) { |
627 | default: |
628 | break; |
629 | case llvm::Triple::x86: |
630 | case llvm::Triple::x86_64: |
631 | this->HasFloat128 = true; |
632 | break; |
633 | } |
634 | } |
635 | }; |
636 | |
637 | // AIX Target |
638 | template <typename Target> |
639 | class AIXTargetInfo : public OSTargetInfo<Target> { |
640 | protected: |
641 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
642 | MacroBuilder &Builder) const override { |
643 | DefineStd(Builder, MacroName: "unix" , Opts); |
644 | Builder.defineMacro(Name: "_IBMR2" ); |
645 | Builder.defineMacro(Name: "_POWER" ); |
646 | Builder.defineMacro(Name: "__THW_BIG_ENDIAN__" ); |
647 | |
648 | Builder.defineMacro(Name: "_AIX" ); |
649 | Builder.defineMacro(Name: "__TOS_AIX__" ); |
650 | Builder.defineMacro(Name: "__HOS_AIX__" ); |
651 | |
652 | if (Opts.C11) { |
653 | Builder.defineMacro(Name: "__STDC_NO_ATOMICS__" ); |
654 | Builder.defineMacro(Name: "__STDC_NO_THREADS__" ); |
655 | } |
656 | |
657 | if (Opts.EnableAIXExtendedAltivecABI) |
658 | Builder.defineMacro(Name: "__EXTABI__" ); |
659 | |
660 | VersionTuple OsVersion = Triple.getOSVersion(); |
661 | |
662 | // Define AIX OS-Version Macros. |
663 | // Includes logic for legacy versions of AIX; no specific intent to support. |
664 | if (OsVersion >= VersionTuple(3, 2)) |
665 | Builder.defineMacro(Name: "_AIX32" ); |
666 | if (OsVersion >= VersionTuple(4, 1)) |
667 | Builder.defineMacro(Name: "_AIX41" ); |
668 | if (OsVersion >= VersionTuple(4, 3)) |
669 | Builder.defineMacro(Name: "_AIX43" ); |
670 | if (OsVersion >= VersionTuple(5, 0)) |
671 | Builder.defineMacro(Name: "_AIX50" ); |
672 | if (OsVersion >= VersionTuple(5, 1)) |
673 | Builder.defineMacro(Name: "_AIX51" ); |
674 | if (OsVersion >= VersionTuple(5, 2)) |
675 | Builder.defineMacro(Name: "_AIX52" ); |
676 | if (OsVersion >= VersionTuple(5, 3)) |
677 | Builder.defineMacro(Name: "_AIX53" ); |
678 | if (OsVersion >= VersionTuple(6, 1)) |
679 | Builder.defineMacro(Name: "_AIX61" ); |
680 | if (OsVersion >= VersionTuple(7, 1)) |
681 | Builder.defineMacro(Name: "_AIX71" ); |
682 | if (OsVersion >= VersionTuple(7, 2)) |
683 | Builder.defineMacro(Name: "_AIX72" ); |
684 | if (OsVersion >= VersionTuple(7, 3)) |
685 | Builder.defineMacro(Name: "_AIX73" ); |
686 | |
687 | // FIXME: Do not define _LONG_LONG when -fno-long-long is specified. |
688 | Builder.defineMacro(Name: "_LONG_LONG" ); |
689 | |
690 | if (Opts.POSIXThreads) { |
691 | Builder.defineMacro(Name: "_THREAD_SAFE" ); |
692 | } |
693 | |
694 | if (this->PointerWidth == 64) { |
695 | Builder.defineMacro(Name: "__64BIT__" ); |
696 | } |
697 | |
698 | // Define _WCHAR_T when it is a fundamental type |
699 | // (i.e., for C++ without -fno-wchar). |
700 | if (Opts.CPlusPlus && Opts.WChar) { |
701 | Builder.defineMacro(Name: "_WCHAR_T" ); |
702 | } |
703 | } |
704 | |
705 | public: |
706 | AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
707 | : OSTargetInfo<Target>(Triple, Opts) { |
708 | this->MCountName = "__mcount" ; |
709 | this->TheCXXABI.set(TargetCXXABI::XL); |
710 | |
711 | if (this->PointerWidth == 64) { |
712 | this->WCharType = this->UnsignedInt; |
713 | } else { |
714 | this->WCharType = this->UnsignedShort; |
715 | } |
716 | this->UseZeroLengthBitfieldAlignment = true; |
717 | } |
718 | |
719 | // AIX sets FLT_EVAL_METHOD to be 1. |
720 | LangOptions::FPEvalMethodKind getFPEvalMethod() const override { |
721 | return LangOptions::FPEvalMethodKind::FEM_Double; |
722 | } |
723 | |
724 | bool defaultsToAIXPowerAlignment() const override { return true; } |
725 | |
726 | bool areDefaultedSMFStillPOD(const LangOptions &) const override { |
727 | return false; |
728 | } |
729 | }; |
730 | |
731 | // z/OS target |
732 | template <typename Target> |
733 | class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> { |
734 | protected: |
735 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
736 | MacroBuilder &Builder) const override { |
737 | // FIXME: _LONG_LONG should not be defined under -std=c89. |
738 | Builder.defineMacro(Name: "_LONG_LONG" ); |
739 | Builder.defineMacro(Name: "__370__" ); |
740 | Builder.defineMacro(Name: "__BFP__" ); |
741 | // FIXME: __BOOL__ should not be defined under -std=c89. |
742 | Builder.defineMacro(Name: "__BOOL__" ); |
743 | Builder.defineMacro(Name: "__COMPILER_VER__" , Value: "0x50000000" ); |
744 | Builder.defineMacro(Name: "__LONGNAME__" ); |
745 | Builder.defineMacro(Name: "__MVS__" ); |
746 | Builder.defineMacro(Name: "__THW_370__" ); |
747 | Builder.defineMacro(Name: "__THW_BIG_ENDIAN__" ); |
748 | Builder.defineMacro(Name: "__TOS_390__" ); |
749 | Builder.defineMacro(Name: "__TOS_MVS__" ); |
750 | Builder.defineMacro(Name: "__XPLINK__" ); |
751 | |
752 | if (this->PointerWidth == 64) |
753 | Builder.defineMacro(Name: "__64BIT__" ); |
754 | |
755 | if (Opts.CPlusPlus && Opts.WChar) { |
756 | // Macro __wchar_t is defined so that the wchar_t data |
757 | // type is not declared as a typedef in system headers. |
758 | Builder.defineMacro(Name: "__wchar_t" ); |
759 | } |
760 | |
761 | this->PlatformName = llvm::Triple::getOSTypeName(Kind: Triple.getOS()); |
762 | } |
763 | |
764 | public: |
765 | ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
766 | : OSTargetInfo<Target>(Triple, Opts) { |
767 | this->WCharType = TargetInfo::UnsignedInt; |
768 | this->MaxAlignedAttribute = 128; |
769 | this->UseBitFieldTypeAlignment = false; |
770 | this->UseZeroLengthBitfieldAlignment = true; |
771 | this->UseLeadingZeroLengthBitfield = false; |
772 | this->ZeroLengthBitfieldBoundary = 32; |
773 | this->TheCXXABI.set(TargetCXXABI::XL); |
774 | } |
775 | |
776 | bool areDefaultedSMFStillPOD(const LangOptions &) const override { |
777 | return false; |
778 | } |
779 | }; |
780 | |
781 | void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, |
782 | MacroBuilder &Builder); |
783 | |
784 | // Windows target |
785 | template <typename Target> |
786 | class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> { |
787 | protected: |
788 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
789 | MacroBuilder &Builder) const override { |
790 | addWindowsDefines(Triple, Opts, Builder); |
791 | } |
792 | |
793 | public: |
794 | WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
795 | : OSTargetInfo<Target>(Triple, Opts) { |
796 | this->WCharType = TargetInfo::UnsignedShort; |
797 | this->WIntType = TargetInfo::UnsignedShort; |
798 | } |
799 | }; |
800 | |
801 | template <typename Target> |
802 | class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> { |
803 | protected: |
804 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
805 | MacroBuilder &Builder) const override { |
806 | if (Opts.POSIXThreads) |
807 | Builder.defineMacro(Name: "_REENTRANT" ); |
808 | if (Opts.CPlusPlus) |
809 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
810 | |
811 | DefineStd(Builder, MacroName: "unix" , Opts); |
812 | Builder.defineMacro(Name: "__native_client__" ); |
813 | } |
814 | |
815 | public: |
816 | NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
817 | : OSTargetInfo<Target>(Triple, Opts) { |
818 | this->LongAlign = 32; |
819 | this->LongWidth = 32; |
820 | this->PointerAlign = 32; |
821 | this->PointerWidth = 32; |
822 | this->IntMaxType = TargetInfo::SignedLongLong; |
823 | this->Int64Type = TargetInfo::SignedLongLong; |
824 | this->DoubleAlign = 64; |
825 | this->LongDoubleWidth = 64; |
826 | this->LongDoubleAlign = 64; |
827 | this->LongLongWidth = 64; |
828 | this->LongLongAlign = 64; |
829 | this->SizeType = TargetInfo::UnsignedInt; |
830 | this->PtrDiffType = TargetInfo::SignedInt; |
831 | this->IntPtrType = TargetInfo::SignedInt; |
832 | // RegParmMax is inherited from the underlying architecture. |
833 | this->LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
834 | if (Triple.getArch() == llvm::Triple::arm) { |
835 | // Handled in ARM's setABI(). |
836 | } else if (Triple.getArch() == llvm::Triple::x86) { |
837 | this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" |
838 | "i64:64-i128:128-n8:16:32-S128" ); |
839 | } else if (Triple.getArch() == llvm::Triple::x86_64) { |
840 | this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" |
841 | "i64:64-i128:128-n8:16:32:64-S128" ); |
842 | } else if (Triple.getArch() == llvm::Triple::mipsel) { |
843 | // Handled on mips' setDataLayout. |
844 | } else { |
845 | assert(Triple.getArch() == llvm::Triple::le32); |
846 | this->resetDataLayout("e-p:32:32-i64:64" ); |
847 | } |
848 | } |
849 | }; |
850 | |
851 | // Fuchsia Target |
852 | template <typename Target> |
853 | class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> { |
854 | protected: |
855 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
856 | MacroBuilder &Builder) const override { |
857 | Builder.defineMacro(Name: "__Fuchsia__" ); |
858 | if (Opts.POSIXThreads) |
859 | Builder.defineMacro(Name: "_REENTRANT" ); |
860 | // Required by the libc++ locale support. |
861 | if (Opts.CPlusPlus) |
862 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
863 | Builder.defineMacro(Name: "__Fuchsia_API_level__" , Value: Twine(Opts.FuchsiaAPILevel)); |
864 | this->PlatformName = "fuchsia" ; |
865 | this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel); |
866 | } |
867 | |
868 | public: |
869 | FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
870 | : OSTargetInfo<Target>(Triple, Opts) { |
871 | this->MCountName = "__mcount" ; |
872 | this->TheCXXABI.set(TargetCXXABI::Fuchsia); |
873 | } |
874 | }; |
875 | |
876 | // WebAssembly target |
877 | template <typename Target> |
878 | class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo |
879 | : public OSTargetInfo<Target> { |
880 | protected: |
881 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
882 | MacroBuilder &Builder) const override { |
883 | // A common platform macro. |
884 | if (Opts.POSIXThreads) |
885 | Builder.defineMacro(Name: "_REENTRANT" ); |
886 | // Follow g++ convention and predefine _GNU_SOURCE for C++. |
887 | if (Opts.CPlusPlus) |
888 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
889 | // Indicate that we have __float128. |
890 | Builder.defineMacro(Name: "__FLOAT128__" ); |
891 | } |
892 | |
893 | public: |
894 | explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple, |
895 | const TargetOptions &Opts) |
896 | : OSTargetInfo<Target>(Triple, Opts) { |
897 | this->MCountName = "__mcount" ; |
898 | this->TheCXXABI.set(TargetCXXABI::WebAssembly); |
899 | this->HasFloat128 = true; |
900 | } |
901 | }; |
902 | |
903 | // WASI target |
904 | template <typename Target> |
905 | class LLVM_LIBRARY_VISIBILITY WASITargetInfo |
906 | : public WebAssemblyOSTargetInfo<Target> { |
907 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
908 | MacroBuilder &Builder) const final { |
909 | WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); |
910 | Builder.defineMacro(Name: "__wasi__" ); |
911 | } |
912 | |
913 | public: |
914 | using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo; |
915 | }; |
916 | |
917 | // Emscripten target |
918 | template <typename Target> |
919 | class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo |
920 | : public WebAssemblyOSTargetInfo<Target> { |
921 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
922 | MacroBuilder &Builder) const final { |
923 | WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder); |
924 | DefineStd(Builder, MacroName: "unix" , Opts); |
925 | Builder.defineMacro(Name: "__EMSCRIPTEN__" ); |
926 | if (Opts.POSIXThreads) |
927 | Builder.defineMacro(Name: "__EMSCRIPTEN_PTHREADS__" ); |
928 | } |
929 | |
930 | public: |
931 | explicit EmscriptenTargetInfo(const llvm::Triple &Triple, |
932 | const TargetOptions &Opts) |
933 | : WebAssemblyOSTargetInfo<Target>(Triple, Opts) { |
934 | // Keeping the alignment of long double to 8 bytes even though its size is |
935 | // 16 bytes allows emscripten to have an 8-byte-aligned max_align_t which |
936 | // in turn gives is a 8-byte aligned malloc. |
937 | // Emscripten's ABI is unstable and we may change this back to 128 to match |
938 | // the WebAssembly default in the future. |
939 | this->LongDoubleAlign = 64; |
940 | } |
941 | }; |
942 | |
943 | // OHOS target |
944 | template <typename Target> |
945 | class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> { |
946 | protected: |
947 | void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, |
948 | MacroBuilder &Builder) const override { |
949 | // Linux defines; list based off of gcc output |
950 | DefineStd(Builder, MacroName: "unix" , Opts); |
951 | |
952 | // Generic OHOS target defines |
953 | if (Triple.isOHOSFamily()) { |
954 | Builder.defineMacro(Name: "__OHOS_FAMILY__" , Value: "1" ); |
955 | |
956 | auto Version = Triple.getEnvironmentVersion(); |
957 | this->PlatformName = "ohos" ; |
958 | this->PlatformMinVersion = Version; |
959 | Builder.defineMacro(Name: "__OHOS_Major__" , Value: Twine(Version.getMajor())); |
960 | if (auto Minor = Version.getMinor()) |
961 | Builder.defineMacro(Name: "__OHOS_Minor__" , Value: Twine(*Minor)); |
962 | if (auto Subminor = Version.getSubminor()) |
963 | Builder.defineMacro(Name: "__OHOS_Micro__" , Value: Twine(*Subminor)); |
964 | } |
965 | |
966 | if (Triple.isOpenHOS()) |
967 | Builder.defineMacro(Name: "__OHOS__" ); |
968 | |
969 | if (Triple.isOSLinux()) { |
970 | DefineStd(Builder, MacroName: "linux" , Opts); |
971 | } else if (Triple.isOSLiteOS()) { |
972 | Builder.defineMacro(Name: "__LITEOS__" ); |
973 | } |
974 | |
975 | if (Opts.POSIXThreads) |
976 | Builder.defineMacro(Name: "_REENTRANT" ); |
977 | if (Opts.CPlusPlus) |
978 | Builder.defineMacro(Name: "_GNU_SOURCE" ); |
979 | if (this->HasFloat128) |
980 | Builder.defineMacro(Name: "__FLOAT128__" ); |
981 | } |
982 | |
983 | public: |
984 | OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
985 | : OSTargetInfo<Target>(Triple, Opts) { |
986 | this->WIntType = TargetInfo::UnsignedInt; |
987 | |
988 | switch (Triple.getArch()) { |
989 | default: |
990 | break; |
991 | case llvm::Triple::x86: |
992 | case llvm::Triple::x86_64: |
993 | this->HasFloat128 = true; |
994 | break; |
995 | } |
996 | } |
997 | |
998 | const char *getStaticInitSectionSpecifier() const override { |
999 | return ".text.startup" ; |
1000 | } |
1001 | }; |
1002 | |
1003 | } // namespace targets |
1004 | } // namespace clang |
1005 | #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H |
1006 | |