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// NetBSD Target
399template <typename Target>
400class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
401protected:
402 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
403 MacroBuilder &Builder) const override {
404 // NetBSD defines; list based off of gcc output
405 Builder.defineMacro(Name: "__NetBSD__");
406 Builder.defineMacro(Name: "__unix__");
407 if (Opts.POSIXThreads)
408 Builder.defineMacro(Name: "_REENTRANT");
409 if (this->HasFloat128)
410 Builder.defineMacro(Name: "__FLOAT128__");
411 }
412
413public:
414 NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
415 : OSTargetInfo<Target>(Triple, Opts) {
416 this->MCountName = "__mcount";
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// OpenBSD Target
429template <typename Target>
430class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
431protected:
432 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
433 MacroBuilder &Builder) const override {
434 // OpenBSD defines; list based off of gcc output
435
436 Builder.defineMacro(Name: "__OpenBSD__");
437 DefineStd(Builder, MacroName: "unix", Opts);
438 if (Opts.POSIXThreads)
439 Builder.defineMacro(Name: "_REENTRANT");
440 if (this->HasFloat128)
441 Builder.defineMacro(Name: "__FLOAT128__");
442
443 if (Opts.C11)
444 Builder.defineMacro(Name: "__STDC_NO_THREADS__");
445 }
446
447public:
448 OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
449 : OSTargetInfo<Target>(Triple, Opts) {
450 this->WCharType = this->WIntType = this->SignedInt;
451 this->IntMaxType = TargetInfo::SignedLongLong;
452 this->Int64Type = TargetInfo::SignedLongLong;
453 switch (Triple.getArch()) {
454 case llvm::Triple::x86:
455 case llvm::Triple::x86_64:
456 this->HasFloat128 = true;
457 [[fallthrough]];
458 default:
459 this->MCountName = "__mcount";
460 break;
461 case llvm::Triple::mips64:
462 case llvm::Triple::mips64el:
463 case llvm::Triple::ppc:
464 case llvm::Triple::ppc64:
465 case llvm::Triple::ppc64le:
466 case llvm::Triple::sparcv9:
467 this->MCountName = "_mcount";
468 break;
469 case llvm::Triple::riscv64:
470 break;
471 }
472 }
473};
474
475// PS3 PPU Target
476template <typename Target>
477class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
478protected:
479 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
480 MacroBuilder &Builder) const override {
481 // PS3 PPU defines.
482 Builder.defineMacro(Name: "__PPU__");
483 Builder.defineMacro(Name: "__CELLOS_LV2__");
484 Builder.defineMacro(Name: "__LP32__");
485 Builder.defineMacro(Name: "_ARCH_PPC64");
486 Builder.defineMacro(Name: "__powerpc64__");
487 }
488
489public:
490 PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
491 : OSTargetInfo<Target>(Triple, Opts) {
492 this->LongWidth = this->LongAlign = 32;
493 this->PointerWidth = this->PointerAlign = 32;
494 this->IntMaxType = TargetInfo::SignedLongLong;
495 this->Int64Type = TargetInfo::SignedLongLong;
496 this->SizeType = TargetInfo::UnsignedInt;
497 this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64");
498 }
499};
500
501// Common base class for PS4/PS5 targets.
502template <typename Target>
503class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> {
504protected:
505 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
506 MacroBuilder &Builder) const override {
507 Builder.defineMacro(Name: "__FreeBSD__", Value: "9");
508 Builder.defineMacro(Name: "__FreeBSD_cc_version", Value: "900001");
509 Builder.defineMacro(Name: "__KPRINTF_ATTRIBUTE__");
510 DefineStd(Builder, MacroName: "unix", Opts);
511 Builder.defineMacro(Name: "__SCE__");
512 Builder.defineMacro(Name: "__STDC_NO_COMPLEX__");
513 Builder.defineMacro(Name: "__STDC_NO_THREADS__");
514 }
515
516public:
517 PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
518 : OSTargetInfo<Target>(Triple, Opts) {
519 this->WCharType = TargetInfo::UnsignedShort;
520
521 // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256
522 // bits).
523 this->MaxTLSAlign = 256;
524
525 // On PS4/PS5, do not honor explicit bit field alignment,
526 // as in "__attribute__((aligned(2))) int b : 1;".
527 this->UseExplicitBitFieldAlignment = false;
528
529 this->MCountName = ".mcount";
530 this->NewAlign = 256;
531 this->SuitableAlign = 256;
532 }
533
534 TargetInfo::CallingConvCheckResult
535 checkCallingConvention(CallingConv CC) const override {
536 return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
537 }
538
539 bool areDefaultedSMFStillPOD(const LangOptions &) const override {
540 return false;
541 }
542};
543
544// PS4 Target
545template <typename Target>
546class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> {
547protected:
548 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
549 MacroBuilder &Builder) const override {
550 // Start with base class defines.
551 PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
552
553 Builder.defineMacro(Name: "__ORBIS__");
554 }
555
556public:
557 using PSOSTargetInfo<Target>::PSOSTargetInfo;
558};
559
560// PS5 Target
561template <typename Target>
562class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> {
563protected:
564 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
565 MacroBuilder &Builder) const override {
566 // Start with base class defines.
567 PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
568
569 Builder.defineMacro(Name: "__PROSPERO__");
570 }
571
572public:
573 using PSOSTargetInfo<Target>::PSOSTargetInfo;
574};
575
576// RTEMS Target
577template <typename Target>
578class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
579protected:
580 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
581 MacroBuilder &Builder) const override {
582 // RTEMS defines; list based off of gcc output
583
584 Builder.defineMacro(Name: "__rtems__");
585 if (Opts.CPlusPlus)
586 Builder.defineMacro(Name: "_GNU_SOURCE");
587 }
588
589public:
590 RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
591 : OSTargetInfo<Target>(Triple, Opts) {
592 switch (Triple.getArch()) {
593 default:
594 case llvm::Triple::x86:
595 // this->MCountName = ".mcount";
596 break;
597 case llvm::Triple::mips:
598 case llvm::Triple::mipsel:
599 case llvm::Triple::ppc:
600 case llvm::Triple::ppc64:
601 case llvm::Triple::ppc64le:
602 // this->MCountName = "_mcount";
603 break;
604 case llvm::Triple::arm:
605 // this->MCountName = "__mcount";
606 break;
607 }
608 }
609};
610
611// Solaris target
612template <typename Target>
613class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
614protected:
615 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
616 MacroBuilder &Builder) const override {
617 DefineStd(Builder, MacroName: "sun", Opts);
618 DefineStd(Builder, MacroName: "unix", Opts);
619 Builder.defineMacro(Name: "__svr4__");
620 Builder.defineMacro(Name: "__SVR4");
621 Builder.defineMacro(Name: "_XOPEN_SOURCE", Value: "600");
622 if (Opts.CPlusPlus) {
623 Builder.defineMacro(Name: "__C99FEATURES__");
624 Builder.defineMacro(Name: "_FILE_OFFSET_BITS", Value: "64");
625 }
626 // GCC restricts the next two to C++.
627 Builder.defineMacro(Name: "_LARGEFILE_SOURCE");
628 Builder.defineMacro(Name: "_LARGEFILE64_SOURCE");
629 Builder.defineMacro(Name: "__EXTENSIONS__");
630 if (Opts.POSIXThreads)
631 Builder.defineMacro(Name: "_REENTRANT");
632 if (this->HasFloat128)
633 Builder.defineMacro(Name: "__FLOAT128__");
634 }
635
636public:
637 SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
638 : OSTargetInfo<Target>(Triple, Opts) {
639 if (this->PointerWidth == 64) {
640 this->WCharType = this->WIntType = this->SignedInt;
641 } else {
642 this->WCharType = this->WIntType = this->SignedLong;
643 }
644 switch (Triple.getArch()) {
645 default:
646 break;
647 case llvm::Triple::x86:
648 case llvm::Triple::x86_64:
649 this->HasFloat128 = true;
650 break;
651 }
652 }
653};
654
655// AIX Target
656template <typename Target>
657class AIXTargetInfo : public OSTargetInfo<Target> {
658protected:
659 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
660 MacroBuilder &Builder) const override {
661 DefineStd(Builder, MacroName: "unix", Opts);
662 Builder.defineMacro(Name: "_IBMR2");
663 Builder.defineMacro(Name: "_POWER");
664 Builder.defineMacro(Name: "__THW_BIG_ENDIAN__");
665
666 Builder.defineMacro(Name: "_AIX");
667 Builder.defineMacro(Name: "__TOS_AIX__");
668 Builder.defineMacro(Name: "__HOS_AIX__");
669
670 if (Opts.C11) {
671 Builder.defineMacro(Name: "__STDC_NO_ATOMICS__");
672 Builder.defineMacro(Name: "__STDC_NO_THREADS__");
673 }
674
675 if (Opts.EnableAIXExtendedAltivecABI)
676 Builder.defineMacro(Name: "__EXTABI__");
677
678 VersionTuple OsVersion = Triple.getOSVersion();
679
680 // Define AIX OS-Version Macros.
681 // Includes logic for legacy versions of AIX; no specific intent to support.
682 if (OsVersion >= VersionTuple(3, 2))
683 Builder.defineMacro(Name: "_AIX32");
684 if (OsVersion >= VersionTuple(4, 1))
685 Builder.defineMacro(Name: "_AIX41");
686 if (OsVersion >= VersionTuple(4, 3))
687 Builder.defineMacro(Name: "_AIX43");
688 if (OsVersion >= VersionTuple(5, 0))
689 Builder.defineMacro(Name: "_AIX50");
690 if (OsVersion >= VersionTuple(5, 1))
691 Builder.defineMacro(Name: "_AIX51");
692 if (OsVersion >= VersionTuple(5, 2))
693 Builder.defineMacro(Name: "_AIX52");
694 if (OsVersion >= VersionTuple(5, 3))
695 Builder.defineMacro(Name: "_AIX53");
696 if (OsVersion >= VersionTuple(6, 1))
697 Builder.defineMacro(Name: "_AIX61");
698 if (OsVersion >= VersionTuple(7, 1))
699 Builder.defineMacro(Name: "_AIX71");
700 if (OsVersion >= VersionTuple(7, 2))
701 Builder.defineMacro(Name: "_AIX72");
702 if (OsVersion >= VersionTuple(7, 3))
703 Builder.defineMacro(Name: "_AIX73");
704
705 // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
706 Builder.defineMacro(Name: "_LONG_LONG");
707
708 if (Opts.POSIXThreads) {
709 Builder.defineMacro(Name: "_THREAD_SAFE");
710 }
711
712 if (this->PointerWidth == 64) {
713 Builder.defineMacro(Name: "__64BIT__");
714 }
715
716 // Define _WCHAR_T when it is a fundamental type
717 // (i.e., for C++ without -fno-wchar).
718 if (Opts.CPlusPlus && Opts.WChar) {
719 Builder.defineMacro(Name: "_WCHAR_T");
720 }
721 }
722
723public:
724 AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
725 : OSTargetInfo<Target>(Triple, Opts) {
726 this->MCountName = "__mcount";
727 this->TheCXXABI.set(TargetCXXABI::XL);
728
729 if (this->PointerWidth == 64) {
730 this->WCharType = this->UnsignedInt;
731 } else {
732 this->WCharType = this->UnsignedShort;
733 }
734 this->UseZeroLengthBitfieldAlignment = true;
735 }
736
737 // AIX sets FLT_EVAL_METHOD to be 1.
738 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
739 return LangOptions::FPEvalMethodKind::FEM_Double;
740 }
741
742 bool defaultsToAIXPowerAlignment() const override { return true; }
743
744 bool areDefaultedSMFStillPOD(const LangOptions &) const override {
745 return false;
746 }
747};
748
749// z/OS target
750template <typename Target>
751class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> {
752protected:
753 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
754 MacroBuilder &Builder) const override {
755 // FIXME: _LONG_LONG should not be defined under -std=c89.
756 Builder.defineMacro(Name: "_LONG_LONG");
757 Builder.defineMacro(Name: "__370__");
758 Builder.defineMacro(Name: "__BFP__");
759 // FIXME: __BOOL__ should not be defined under -std=c89.
760 Builder.defineMacro(Name: "__BOOL__");
761 Builder.defineMacro(Name: "__COMPILER_VER__", Value: "0x50000000");
762 Builder.defineMacro(Name: "__LONGNAME__");
763 Builder.defineMacro(Name: "__MVS__");
764 Builder.defineMacro(Name: "__THW_370__");
765 Builder.defineMacro(Name: "__THW_BIG_ENDIAN__");
766 Builder.defineMacro(Name: "__TOS_390__");
767 Builder.defineMacro(Name: "__TOS_MVS__");
768 Builder.defineMacro(Name: "__XPLINK__");
769
770 if (this->PointerWidth == 64)
771 Builder.defineMacro(Name: "__64BIT__");
772
773 if (Opts.CPlusPlus && Opts.WChar) {
774 // Macro __wchar_t is defined so that the wchar_t data
775 // type is not declared as a typedef in system headers.
776 Builder.defineMacro(Name: "__wchar_t");
777 }
778
779 this->PlatformName = llvm::Triple::getOSTypeName(Kind: Triple.getOS());
780 }
781
782public:
783 ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
784 : OSTargetInfo<Target>(Triple, Opts) {
785 this->WCharType = TargetInfo::UnsignedInt;
786 this->MaxAlignedAttribute = 128;
787 this->UseBitFieldTypeAlignment = false;
788 this->UseZeroLengthBitfieldAlignment = true;
789 this->UseLeadingZeroLengthBitfield = false;
790 this->ZeroLengthBitfieldBoundary = 32;
791 this->TheCXXABI.set(TargetCXXABI::XL);
792 }
793
794 bool areDefaultedSMFStillPOD(const LangOptions &) const override {
795 return false;
796 }
797};
798
799// UEFI target
800template <typename Target>
801class LLVM_LIBRARY_VISIBILITY UEFITargetInfo : public OSTargetInfo<Target> {
802protected:
803 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
804 MacroBuilder &Builder) const override {
805 Builder.defineMacro(Name: "__UEFI__");
806 }
807
808public:
809 UEFITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
810 : OSTargetInfo<Target>(Triple, Opts) {
811 this->WCharType = TargetInfo::UnsignedShort;
812 this->WIntType = TargetInfo::UnsignedShort;
813 this->UseMicrosoftManglingForC = true;
814 }
815};
816
817void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
818 MacroBuilder &Builder);
819
820// Windows target
821template <typename Target>
822class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
823protected:
824 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
825 MacroBuilder &Builder) const override {
826 addWindowsDefines(Triple, Opts, Builder);
827 }
828
829public:
830 WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
831 : OSTargetInfo<Target>(Triple, Opts) {
832 this->WCharType = TargetInfo::UnsignedShort;
833 this->WIntType = TargetInfo::UnsignedShort;
834 this->UseMicrosoftManglingForC = true;
835 }
836};
837
838template <typename Target>
839class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
840protected:
841 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
842 MacroBuilder &Builder) const override {
843 if (Opts.POSIXThreads)
844 Builder.defineMacro(Name: "_REENTRANT");
845 if (Opts.CPlusPlus)
846 Builder.defineMacro(Name: "_GNU_SOURCE");
847
848 DefineStd(Builder, MacroName: "unix", Opts);
849 Builder.defineMacro(Name: "__native_client__");
850 }
851
852public:
853 NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
854 : OSTargetInfo<Target>(Triple, Opts) {
855 this->LongAlign = 32;
856 this->LongWidth = 32;
857 this->PointerAlign = 32;
858 this->PointerWidth = 32;
859 this->IntMaxType = TargetInfo::SignedLongLong;
860 this->Int64Type = TargetInfo::SignedLongLong;
861 this->DoubleAlign = 64;
862 this->LongDoubleWidth = 64;
863 this->LongDoubleAlign = 64;
864 this->LongLongWidth = 64;
865 this->LongLongAlign = 64;
866 this->SizeType = TargetInfo::UnsignedInt;
867 this->PtrDiffType = TargetInfo::SignedInt;
868 this->IntPtrType = TargetInfo::SignedInt;
869 // RegParmMax is inherited from the underlying architecture.
870 this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
871 if (Triple.getArch() == llvm::Triple::arm) {
872 // Handled in ARM's setABI().
873 } else if (Triple.getArch() == llvm::Triple::x86) {
874 this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
875 "i64:64-i128:128-n8:16:32-S128");
876 } else if (Triple.getArch() == llvm::Triple::x86_64) {
877 this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
878 "i64:64-i128:128-n8:16:32:64-S128");
879 } else if (Triple.getArch() == llvm::Triple::mipsel) {
880 // Handled on mips' setDataLayout.
881 }
882 }
883};
884
885// Fuchsia Target
886template <typename Target>
887class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
888protected:
889 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
890 MacroBuilder &Builder) const override {
891 Builder.defineMacro(Name: "__Fuchsia__");
892 if (Opts.POSIXThreads)
893 Builder.defineMacro(Name: "_REENTRANT");
894 // Required by the libc++ locale support.
895 if (Opts.CPlusPlus)
896 Builder.defineMacro(Name: "_GNU_SOURCE");
897 Builder.defineMacro(Name: "__Fuchsia_API_level__", Value: Twine(Opts.FuchsiaAPILevel));
898 this->PlatformName = "fuchsia";
899 this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel);
900 }
901
902public:
903 FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
904 : OSTargetInfo<Target>(Triple, Opts) {
905 this->WIntType = TargetInfo::UnsignedInt;
906 this->MCountName = "__mcount";
907 this->TheCXXABI.set(TargetCXXABI::Fuchsia);
908 }
909};
910
911// WebAssembly target
912template <typename Target>
913class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
914 : public OSTargetInfo<Target> {
915protected:
916 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
917 MacroBuilder &Builder) const override {
918 // A common platform macro.
919 if (Opts.POSIXThreads)
920 Builder.defineMacro(Name: "_REENTRANT");
921 // Follow g++ convention and predefine _GNU_SOURCE for C++.
922 if (Opts.CPlusPlus)
923 Builder.defineMacro(Name: "_GNU_SOURCE");
924 // Indicate that we have __float128.
925 Builder.defineMacro(Name: "__FLOAT128__");
926 }
927
928public:
929 explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
930 const TargetOptions &Opts)
931 : OSTargetInfo<Target>(Triple, Opts) {
932 this->MCountName = "__mcount";
933 this->TheCXXABI.set(TargetCXXABI::WebAssembly);
934 this->HasFloat128 = true;
935 }
936};
937
938// WASI target
939template <typename Target>
940class LLVM_LIBRARY_VISIBILITY WASITargetInfo
941 : public WebAssemblyOSTargetInfo<Target> {
942 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
943 MacroBuilder &Builder) const final {
944 WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
945 Builder.defineMacro(Name: "__wasi__");
946 }
947
948public:
949 using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
950};
951
952// Emscripten target
953template <typename Target>
954class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
955 : public WebAssemblyOSTargetInfo<Target> {
956 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
957 MacroBuilder &Builder) const final {
958 WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
959 DefineStd(Builder, MacroName: "unix", Opts);
960 Builder.defineMacro(Name: "__EMSCRIPTEN__");
961 if (Opts.POSIXThreads)
962 Builder.defineMacro(Name: "__EMSCRIPTEN_PTHREADS__");
963 }
964
965public:
966 explicit EmscriptenTargetInfo(const llvm::Triple &Triple,
967 const TargetOptions &Opts)
968 : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {
969 // Keeping the alignment of long double to 8 bytes even though its size is
970 // 16 bytes allows emscripten to have an 8-byte-aligned max_align_t which
971 // in turn gives is a 8-byte aligned malloc.
972 // Emscripten's ABI is unstable and we may change this back to 128 to match
973 // the WebAssembly default in the future.
974 this->LongDoubleAlign = 64;
975 }
976};
977
978// OHOS target
979template <typename Target>
980class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> {
981protected:
982 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
983 MacroBuilder &Builder) const override {
984 // Linux defines; list based off of gcc output
985 DefineStd(Builder, MacroName: "unix", Opts);
986
987 // Generic OHOS target defines
988 if (Triple.isOHOSFamily()) {
989 Builder.defineMacro(Name: "__OHOS_FAMILY__", Value: "1");
990
991 auto Version = Triple.getEnvironmentVersion();
992 this->PlatformName = "ohos";
993 this->PlatformMinVersion = Version;
994 Builder.defineMacro(Name: "__OHOS_Major__", Value: Twine(Version.getMajor()));
995 if (auto Minor = Version.getMinor())
996 Builder.defineMacro(Name: "__OHOS_Minor__", Value: Twine(*Minor));
997 if (auto Subminor = Version.getSubminor())
998 Builder.defineMacro(Name: "__OHOS_Micro__", Value: Twine(*Subminor));
999 }
1000
1001 if (Triple.isOpenHOS())
1002 Builder.defineMacro(Name: "__OHOS__");
1003
1004 if (Triple.isOSLinux()) {
1005 DefineStd(Builder, MacroName: "linux", Opts);
1006 } else if (Triple.isOSLiteOS()) {
1007 Builder.defineMacro(Name: "__LITEOS__");
1008 }
1009
1010 if (Opts.POSIXThreads)
1011 Builder.defineMacro(Name: "_REENTRANT");
1012 if (Opts.CPlusPlus)
1013 Builder.defineMacro(Name: "_GNU_SOURCE");
1014 if (this->HasFloat128)
1015 Builder.defineMacro(Name: "__FLOAT128__");
1016 }
1017
1018public:
1019 OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1020 : OSTargetInfo<Target>(Triple, Opts) {
1021 this->WIntType = TargetInfo::UnsignedInt;
1022
1023 switch (Triple.getArch()) {
1024 default:
1025 break;
1026 case llvm::Triple::x86:
1027 case llvm::Triple::x86_64:
1028 this->HasFloat128 = true;
1029 break;
1030 }
1031 }
1032
1033 const char *getStaticInitSectionSpecifier() const override {
1034 return ".text.startup";
1035 }
1036};
1037
1038} // namespace targets
1039} // namespace clang
1040#endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
1041

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/Basic/Targets/OSTargets.h