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