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