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 getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
38 const llvm::Triple &Triple, StringRef &PlatformName,
39 VersionTuple &PlatformMinVersion);
40
41template <typename Target>
42class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
43protected:
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
50public:
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
141template <typename Target>
142class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
143 : public OSTargetInfo<Target> {
144protected:
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
157public:
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
176template <typename Target>
177class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
178protected:
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
209public:
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
239template <typename Target>
240class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> {
241protected:
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
255public:
256 using OSTargetInfo<Target>::OSTargetInfo;
257};
258
259// Haiku Target
260template <typename Target>
261class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
262protected:
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
272public:
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
291template <typename Target>
292class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
293protected:
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 }
307public:
308 using OSTargetInfo<Target>::OSTargetInfo;
309};
310
311// Linux target
312template <typename Target>
313class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
314protected:
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
342public:
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
373template <typename Target>
374class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
375protected:
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
387public:
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
403template <typename Target>
404class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
405protected:
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
421public:
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
451template <typename Target>
452class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
453protected:
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
464public:
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.
477template <typename Target>
478class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> {
479protected:
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
491public:
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
520template <typename Target>
521class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> {
522protected:
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
531public:
532 using PSOSTargetInfo<Target>::PSOSTargetInfo;
533};
534
535// PS5 Target
536template <typename Target>
537class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> {
538protected:
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
547public:
548 using PSOSTargetInfo<Target>::PSOSTargetInfo;
549};
550
551// RTEMS Target
552template <typename Target>
553class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
554protected:
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
564public:
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
587template <typename Target>
588class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
589protected:
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
618public:
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
638template <typename Target>
639class AIXTargetInfo : public OSTargetInfo<Target> {
640protected:
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
705public:
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
732template <typename Target>
733class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> {
734protected:
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
764public:
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
781void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
782 MacroBuilder &Builder);
783
784// Windows target
785template <typename Target>
786class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
787protected:
788 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
789 MacroBuilder &Builder) const override {
790 addWindowsDefines(Triple, Opts, Builder);
791 }
792
793public:
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
801template <typename Target>
802class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
803protected:
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
815public:
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
852template <typename Target>
853class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
854protected:
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
868public:
869 FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
870 : OSTargetInfo<Target>(Triple, Opts) {
871 this->WIntType = TargetInfo::UnsignedInt;
872 this->MCountName = "__mcount";
873 this->TheCXXABI.set(TargetCXXABI::Fuchsia);
874 }
875};
876
877// WebAssembly target
878template <typename Target>
879class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
880 : public OSTargetInfo<Target> {
881protected:
882 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
883 MacroBuilder &Builder) const override {
884 // A common platform macro.
885 if (Opts.POSIXThreads)
886 Builder.defineMacro(Name: "_REENTRANT");
887 // Follow g++ convention and predefine _GNU_SOURCE for C++.
888 if (Opts.CPlusPlus)
889 Builder.defineMacro(Name: "_GNU_SOURCE");
890 // Indicate that we have __float128.
891 Builder.defineMacro(Name: "__FLOAT128__");
892 }
893
894public:
895 explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
896 const TargetOptions &Opts)
897 : OSTargetInfo<Target>(Triple, Opts) {
898 this->MCountName = "__mcount";
899 this->TheCXXABI.set(TargetCXXABI::WebAssembly);
900 this->HasFloat128 = true;
901 }
902};
903
904// WASI target
905template <typename Target>
906class LLVM_LIBRARY_VISIBILITY WASITargetInfo
907 : public WebAssemblyOSTargetInfo<Target> {
908 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
909 MacroBuilder &Builder) const final {
910 WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
911 Builder.defineMacro(Name: "__wasi__");
912 }
913
914public:
915 using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
916};
917
918// Emscripten target
919template <typename Target>
920class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
921 : public WebAssemblyOSTargetInfo<Target> {
922 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
923 MacroBuilder &Builder) const final {
924 WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
925 DefineStd(Builder, MacroName: "unix", Opts);
926 Builder.defineMacro(Name: "__EMSCRIPTEN__");
927 if (Opts.POSIXThreads)
928 Builder.defineMacro(Name: "__EMSCRIPTEN_PTHREADS__");
929 }
930
931public:
932 explicit EmscriptenTargetInfo(const llvm::Triple &Triple,
933 const TargetOptions &Opts)
934 : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {
935 // Keeping the alignment of long double to 8 bytes even though its size is
936 // 16 bytes allows emscripten to have an 8-byte-aligned max_align_t which
937 // in turn gives is a 8-byte aligned malloc.
938 // Emscripten's ABI is unstable and we may change this back to 128 to match
939 // the WebAssembly default in the future.
940 this->LongDoubleAlign = 64;
941 }
942};
943
944// OHOS target
945template <typename Target>
946class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> {
947protected:
948 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
949 MacroBuilder &Builder) const override {
950 // Linux defines; list based off of gcc output
951 DefineStd(Builder, MacroName: "unix", Opts);
952
953 // Generic OHOS target defines
954 if (Triple.isOHOSFamily()) {
955 Builder.defineMacro(Name: "__OHOS_FAMILY__", Value: "1");
956
957 auto Version = Triple.getEnvironmentVersion();
958 this->PlatformName = "ohos";
959 this->PlatformMinVersion = Version;
960 Builder.defineMacro(Name: "__OHOS_Major__", Value: Twine(Version.getMajor()));
961 if (auto Minor = Version.getMinor())
962 Builder.defineMacro(Name: "__OHOS_Minor__", Value: Twine(*Minor));
963 if (auto Subminor = Version.getSubminor())
964 Builder.defineMacro(Name: "__OHOS_Micro__", Value: Twine(*Subminor));
965 }
966
967 if (Triple.isOpenHOS())
968 Builder.defineMacro(Name: "__OHOS__");
969
970 if (Triple.isOSLinux()) {
971 DefineStd(Builder, MacroName: "linux", Opts);
972 } else if (Triple.isOSLiteOS()) {
973 Builder.defineMacro(Name: "__LITEOS__");
974 }
975
976 if (Opts.POSIXThreads)
977 Builder.defineMacro(Name: "_REENTRANT");
978 if (Opts.CPlusPlus)
979 Builder.defineMacro(Name: "_GNU_SOURCE");
980 if (this->HasFloat128)
981 Builder.defineMacro(Name: "__FLOAT128__");
982 }
983
984public:
985 OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
986 : OSTargetInfo<Target>(Triple, Opts) {
987 this->WIntType = TargetInfo::UnsignedInt;
988
989 switch (Triple.getArch()) {
990 default:
991 break;
992 case llvm::Triple::x86:
993 case llvm::Triple::x86_64:
994 this->HasFloat128 = true;
995 break;
996 }
997 }
998
999 const char *getStaticInitSectionSpecifier() const override {
1000 return ".text.startup";
1001 }
1002};
1003
1004} // namespace targets
1005} // namespace clang
1006#endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
1007