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