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