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