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