xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
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       llvm_unreachable("Unexpected OS");
158     }
159 
160     unsigned Major, Minor, Micro;
161     T.getOSVersion(Major, Minor, Micro);
162     if (llvm::VersionTuple(Major, Minor, Micro) < MinVersion)
163       return 64;
164     return OSTargetInfo<Target>::getExnObjectAlignment();
165   }
166 
167   TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth,
168                                              bool IsSigned) const final {
169     // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`.
170     return BitWidth == 64
171                ? (IsSigned ? TargetInfo::SignedLongLong
172                            : TargetInfo::UnsignedLongLong)
173                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
174   }
175 };
176 
177 // DragonFlyBSD Target
178 template <typename Target>
179 class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
180     : public OSTargetInfo<Target> {
181 protected:
182   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
183                     MacroBuilder &Builder) const override {
184     // DragonFly defines; list based off of gcc output
185     Builder.defineMacro("__DragonFly__");
186     Builder.defineMacro("__DragonFly_cc_version", "100001");
187     Builder.defineMacro("__ELF__");
188     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
189     Builder.defineMacro("__tune_i386__");
190     DefineStd(Builder, "unix", Opts);
191   }
192 
193 public:
194   DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
195       : OSTargetInfo<Target>(Triple, Opts) {
196     switch (Triple.getArch()) {
197     default:
198     case llvm::Triple::x86:
199     case llvm::Triple::x86_64:
200       this->MCountName = ".mcount";
201       break;
202     }
203   }
204 };
205 
206 #ifndef FREEBSD_CC_VERSION
207 #define FREEBSD_CC_VERSION 0U
208 #endif
209 
210 // FreeBSD Target
211 template <typename Target>
212 class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
213 protected:
214   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
215                     MacroBuilder &Builder) const override {
216     // FreeBSD defines; list based off of gcc output
217 
218     unsigned Release = Triple.getOSMajorVersion();
219     if (Release == 0U)
220       Release = 8U;
221     unsigned CCVersion = FREEBSD_CC_VERSION;
222     if (CCVersion == 0U)
223       CCVersion = Release * 100000U + 1U;
224 
225     Builder.defineMacro("__FreeBSD__", Twine(Release));
226     Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
227     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
228     DefineStd(Builder, "unix", Opts);
229     Builder.defineMacro("__ELF__");
230 
231     // On FreeBSD, wchar_t contains the number of the code point as
232     // used by the character set of the locale. These character sets are
233     // not necessarily a superset of ASCII.
234     //
235     // FIXME: This is wrong; the macro refers to the numerical values
236     // of wchar_t *literals*, which are not locale-dependent. However,
237     // FreeBSD systems apparently depend on us getting this wrong, and
238     // setting this to 1 is conforming even if all the basic source
239     // character literals have the same encoding as char and wchar_t.
240     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
241   }
242 
243 public:
244   FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
245       : OSTargetInfo<Target>(Triple, Opts) {
246     switch (Triple.getArch()) {
247     default:
248     case llvm::Triple::x86:
249     case llvm::Triple::x86_64:
250       this->MCountName = ".mcount";
251       break;
252     case llvm::Triple::mips:
253     case llvm::Triple::mipsel:
254     case llvm::Triple::ppc:
255     case llvm::Triple::ppc64:
256     case llvm::Triple::ppc64le:
257       this->MCountName = "_mcount";
258       break;
259     case llvm::Triple::arm:
260       this->MCountName = "__mcount";
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   KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
286       : OSTargetInfo<Target>(Triple, Opts) {}
287 };
288 
289 // Haiku Target
290 template <typename Target>
291 class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
292 protected:
293   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
294                     MacroBuilder &Builder) const override {
295     // Haiku defines; list based off of gcc output
296     Builder.defineMacro("__HAIKU__");
297     Builder.defineMacro("__ELF__");
298     DefineStd(Builder, "unix", Opts);
299     if (this->HasFloat128)
300       Builder.defineMacro("__FLOAT128__");
301   }
302 
303 public:
304   HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
305       : OSTargetInfo<Target>(Triple, Opts) {
306     this->SizeType = TargetInfo::UnsignedLong;
307     this->IntPtrType = TargetInfo::SignedLong;
308     this->PtrDiffType = TargetInfo::SignedLong;
309     this->ProcessIDType = TargetInfo::SignedLong;
310     this->TLSSupported = false;
311     switch (Triple.getArch()) {
312     default:
313       break;
314     case llvm::Triple::x86:
315     case llvm::Triple::x86_64:
316       this->HasFloat128 = true;
317       break;
318     }
319   }
320 };
321 
322 // Hurd target
323 template <typename Target>
324 class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
325 protected:
326   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
327                     MacroBuilder &Builder) const override {
328     // Hurd defines; list based off of gcc output.
329     DefineStd(Builder, "unix", Opts);
330     Builder.defineMacro("__GNU__");
331     Builder.defineMacro("__gnu_hurd__");
332     Builder.defineMacro("__MACH__");
333     Builder.defineMacro("__GLIBC__");
334     Builder.defineMacro("__ELF__");
335     if (Opts.POSIXThreads)
336       Builder.defineMacro("_REENTRANT");
337     if (Opts.CPlusPlus)
338       Builder.defineMacro("_GNU_SOURCE");
339   }
340 public:
341   HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
342       : OSTargetInfo<Target>(Triple, Opts) {}
343 };
344 
345 // Minix Target
346 template <typename Target>
347 class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> {
348 protected:
349   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
350                     MacroBuilder &Builder) const override {
351     // Minix defines
352 
353     Builder.defineMacro("__minix", "3");
354     Builder.defineMacro("_EM_WSIZE", "4");
355     Builder.defineMacro("_EM_PSIZE", "4");
356     Builder.defineMacro("_EM_SSIZE", "2");
357     Builder.defineMacro("_EM_LSIZE", "4");
358     Builder.defineMacro("_EM_FSIZE", "4");
359     Builder.defineMacro("_EM_DSIZE", "8");
360     Builder.defineMacro("__ELF__");
361     DefineStd(Builder, "unix", Opts);
362   }
363 
364 public:
365   MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
366       : OSTargetInfo<Target>(Triple, Opts) {}
367 };
368 
369 // Linux target
370 template <typename Target>
371 class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
372 protected:
373   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
374                     MacroBuilder &Builder) const override {
375     // Linux defines; list based off of gcc output
376     DefineStd(Builder, "unix", Opts);
377     DefineStd(Builder, "linux", Opts);
378     Builder.defineMacro("__ELF__");
379     if (Triple.isAndroid()) {
380       Builder.defineMacro("__ANDROID__", "1");
381       unsigned Maj, Min, Rev;
382       Triple.getEnvironmentVersion(Maj, Min, Rev);
383       this->PlatformName = "android";
384       this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
385       if (Maj)
386         Builder.defineMacro("__ANDROID_API__", Twine(Maj));
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::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 
465 public:
466   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
467       : OSTargetInfo<Target>(Triple, Opts) {
468     this->WCharType = this->WIntType = this->SignedInt;
469     this->IntMaxType = TargetInfo::SignedLongLong;
470     this->Int64Type = TargetInfo::SignedLongLong;
471     switch (Triple.getArch()) {
472     case llvm::Triple::x86:
473     case llvm::Triple::x86_64:
474       this->HasFloat128 = true;
475       LLVM_FALLTHROUGH;
476     default:
477       this->MCountName = "__mcount";
478       break;
479     case llvm::Triple::mips64:
480     case llvm::Triple::mips64el:
481     case llvm::Triple::ppc:
482     case llvm::Triple::ppc64:
483     case llvm::Triple::ppc64le:
484     case llvm::Triple::sparcv9:
485       this->MCountName = "_mcount";
486       break;
487     }
488   }
489 };
490 
491 // PSP Target
492 template <typename Target>
493 class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
494 protected:
495   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
496                     MacroBuilder &Builder) const override {
497     // PSP defines; list based on the output of the pspdev gcc toolchain.
498     Builder.defineMacro("PSP");
499     Builder.defineMacro("_PSP");
500     Builder.defineMacro("__psp__");
501     Builder.defineMacro("__ELF__");
502   }
503 
504 public:
505   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
506 };
507 
508 // PS3 PPU Target
509 template <typename Target>
510 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
511 protected:
512   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
513                     MacroBuilder &Builder) const override {
514     // PS3 PPU defines.
515     Builder.defineMacro("__PPC__");
516     Builder.defineMacro("__PPU__");
517     Builder.defineMacro("__CELLOS_LV2__");
518     Builder.defineMacro("__ELF__");
519     Builder.defineMacro("__LP32__");
520     Builder.defineMacro("_ARCH_PPC64");
521     Builder.defineMacro("__powerpc64__");
522   }
523 
524 public:
525   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
526       : OSTargetInfo<Target>(Triple, Opts) {
527     this->LongWidth = this->LongAlign = 32;
528     this->PointerWidth = this->PointerAlign = 32;
529     this->IntMaxType = TargetInfo::SignedLongLong;
530     this->Int64Type = TargetInfo::SignedLongLong;
531     this->SizeType = TargetInfo::UnsignedInt;
532     this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
533   }
534 };
535 
536 template <typename Target>
537 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
538 protected:
539   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
540                     MacroBuilder &Builder) const override {
541     Builder.defineMacro("__FreeBSD__", "9");
542     Builder.defineMacro("__FreeBSD_cc_version", "900001");
543     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
544     DefineStd(Builder, "unix", Opts);
545     Builder.defineMacro("__ELF__");
546     Builder.defineMacro("__SCE__");
547     Builder.defineMacro("__ORBIS__");
548   }
549 
550 public:
551   PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
552       : OSTargetInfo<Target>(Triple, Opts) {
553     this->WCharType = TargetInfo::UnsignedShort;
554 
555     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
556     this->MaxTLSAlign = 256;
557 
558     // On PS4, do not honor explicit bit field alignment,
559     // as in "__attribute__((aligned(2))) int b : 1;".
560     this->UseExplicitBitFieldAlignment = false;
561 
562     switch (Triple.getArch()) {
563     default:
564     case llvm::Triple::x86_64:
565       this->MCountName = ".mcount";
566       this->NewAlign = 256;
567       break;
568     }
569   }
570   TargetInfo::CallingConvCheckResult
571   checkCallingConvention(CallingConv CC) const override {
572     return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
573   }
574 };
575 
576 // RTEMS Target
577 template <typename Target>
578 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
579 protected:
580   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
581                     MacroBuilder &Builder) const override {
582     // RTEMS defines; list based off of gcc output
583 
584     Builder.defineMacro("__rtems__");
585     Builder.defineMacro("__ELF__");
586     if (Opts.CPlusPlus)
587       Builder.defineMacro("_GNU_SOURCE");
588   }
589 
590 public:
591   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
592       : OSTargetInfo<Target>(Triple, Opts) {
593     switch (Triple.getArch()) {
594     default:
595     case llvm::Triple::x86:
596       // this->MCountName = ".mcount";
597       break;
598     case llvm::Triple::mips:
599     case llvm::Triple::mipsel:
600     case llvm::Triple::ppc:
601     case llvm::Triple::ppc64:
602     case llvm::Triple::ppc64le:
603       // this->MCountName = "_mcount";
604       break;
605     case llvm::Triple::arm:
606       // this->MCountName = "__mcount";
607       break;
608     }
609   }
610 };
611 
612 // Solaris target
613 template <typename Target>
614 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
615 protected:
616   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
617                     MacroBuilder &Builder) const override {
618     DefineStd(Builder, "sun", Opts);
619     DefineStd(Builder, "unix", Opts);
620     Builder.defineMacro("__ELF__");
621     Builder.defineMacro("__svr4__");
622     Builder.defineMacro("__SVR4");
623     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
624     // newer, but to 500 for everything else.  feature_test.h has a check to
625     // ensure that you are not using C99 with an old version of X/Open or C89
626     // with a new version.
627     if (Opts.C99)
628       Builder.defineMacro("_XOPEN_SOURCE", "600");
629     else
630       Builder.defineMacro("_XOPEN_SOURCE", "500");
631     if (Opts.CPlusPlus) {
632       Builder.defineMacro("__C99FEATURES__");
633       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
634     }
635     // GCC restricts the next two to C++.
636     Builder.defineMacro("_LARGEFILE_SOURCE");
637     Builder.defineMacro("_LARGEFILE64_SOURCE");
638     Builder.defineMacro("__EXTENSIONS__");
639     if (Opts.POSIXThreads)
640       Builder.defineMacro("_REENTRANT");
641     if (this->HasFloat128)
642       Builder.defineMacro("__FLOAT128__");
643   }
644 
645 public:
646   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
647       : OSTargetInfo<Target>(Triple, Opts) {
648     if (this->PointerWidth == 64) {
649       this->WCharType = this->WIntType = this->SignedInt;
650     } else {
651       this->WCharType = this->WIntType = this->SignedLong;
652     }
653     switch (Triple.getArch()) {
654     default:
655       break;
656     case llvm::Triple::x86:
657     case llvm::Triple::x86_64:
658       this->HasFloat128 = true;
659       break;
660     }
661   }
662 };
663 
664 // AIX Target
665 template <typename Target>
666 class AIXTargetInfo : public OSTargetInfo<Target> {
667 protected:
668   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
669                     MacroBuilder &Builder) const override {
670     DefineStd(Builder, "unix", Opts);
671     Builder.defineMacro("_IBMR2");
672     Builder.defineMacro("_POWER");
673 
674     Builder.defineMacro("_AIX");
675 
676     unsigned Major, Minor, Micro;
677     Triple.getOSVersion(Major, Minor, Micro);
678 
679     // Define AIX OS-Version Macros.
680     // Includes logic for legacy versions of AIX; no specific intent to support.
681     std::pair<int, int> OsVersion = {Major, Minor};
682     if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
683     if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
684     if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
685     if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
686     if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
687     if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
688     if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
689     if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
690     if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
691     if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
692 
693     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
694     Builder.defineMacro("_LONG_LONG");
695 
696     if (Opts.POSIXThreads) {
697       Builder.defineMacro("_THREAD_SAFE");
698     }
699 
700     if (this->PointerWidth == 64) {
701       Builder.defineMacro("__64BIT__");
702     }
703 
704     // Define _WCHAR_T when it is a fundamental type
705     // (i.e., for C++ without -fno-wchar).
706     if (Opts.CPlusPlus && Opts.WChar) {
707       Builder.defineMacro("_WCHAR_T");
708     }
709   }
710 
711 public:
712   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
713       : OSTargetInfo<Target>(Triple, Opts) {
714     this->TheCXXABI.set(TargetCXXABI::XL);
715 
716     if (this->PointerWidth == 64) {
717       this->WCharType = this->UnsignedInt;
718     } else {
719       this->WCharType = this->UnsignedShort;
720     }
721     this->UseZeroLengthBitfieldAlignment = true;
722   }
723 
724   // AIX sets FLT_EVAL_METHOD to be 1.
725   unsigned getFloatEvalMethod() const override { return 1; }
726   bool hasInt128Type() const override { return false; }
727 };
728 
729 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
730                        MacroBuilder &Builder);
731 
732 // Windows target
733 template <typename Target>
734 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
735 protected:
736   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
737                     MacroBuilder &Builder) const override {
738     addWindowsDefines(Triple, Opts, Builder);
739   }
740 
741 public:
742   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
743       : OSTargetInfo<Target>(Triple, Opts) {
744     this->WCharType = TargetInfo::UnsignedShort;
745     this->WIntType = TargetInfo::UnsignedShort;
746   }
747 };
748 
749 template <typename Target>
750 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
751 protected:
752   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
753                     MacroBuilder &Builder) const override {
754     if (Opts.POSIXThreads)
755       Builder.defineMacro("_REENTRANT");
756     if (Opts.CPlusPlus)
757       Builder.defineMacro("_GNU_SOURCE");
758 
759     DefineStd(Builder, "unix", Opts);
760     Builder.defineMacro("__ELF__");
761     Builder.defineMacro("__native_client__");
762   }
763 
764 public:
765   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
766       : OSTargetInfo<Target>(Triple, Opts) {
767     this->LongAlign = 32;
768     this->LongWidth = 32;
769     this->PointerAlign = 32;
770     this->PointerWidth = 32;
771     this->IntMaxType = TargetInfo::SignedLongLong;
772     this->Int64Type = TargetInfo::SignedLongLong;
773     this->DoubleAlign = 64;
774     this->LongDoubleWidth = 64;
775     this->LongDoubleAlign = 64;
776     this->LongLongWidth = 64;
777     this->LongLongAlign = 64;
778     this->SizeType = TargetInfo::UnsignedInt;
779     this->PtrDiffType = TargetInfo::SignedInt;
780     this->IntPtrType = TargetInfo::SignedInt;
781     // RegParmMax is inherited from the underlying architecture.
782     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
783     if (Triple.getArch() == llvm::Triple::arm) {
784       // Handled in ARM's setABI().
785     } else if (Triple.getArch() == llvm::Triple::x86) {
786       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
787                             "i64:64-n8:16:32-S128");
788     } else if (Triple.getArch() == llvm::Triple::x86_64) {
789       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
790                             "i64:64-n8:16:32:64-S128");
791     } else if (Triple.getArch() == llvm::Triple::mipsel) {
792       // Handled on mips' setDataLayout.
793     } else {
794       assert(Triple.getArch() == llvm::Triple::le32);
795       this->resetDataLayout("e-p:32:32-i64:64");
796     }
797   }
798 };
799 
800 // Fuchsia Target
801 template <typename Target>
802 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
803 protected:
804   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
805                     MacroBuilder &Builder) const override {
806     Builder.defineMacro("__Fuchsia__");
807     Builder.defineMacro("__ELF__");
808     if (Opts.POSIXThreads)
809       Builder.defineMacro("_REENTRANT");
810     // Required by the libc++ locale support.
811     if (Opts.CPlusPlus)
812       Builder.defineMacro("_GNU_SOURCE");
813   }
814 
815 public:
816   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
817       : OSTargetInfo<Target>(Triple, Opts) {
818     this->MCountName = "__mcount";
819     this->TheCXXABI.set(TargetCXXABI::Fuchsia);
820   }
821 };
822 
823 // WebAssembly target
824 template <typename Target>
825 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
826     : public OSTargetInfo<Target> {
827 protected:
828   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
829                     MacroBuilder &Builder) const override {
830     // A common platform macro.
831     if (Opts.POSIXThreads)
832       Builder.defineMacro("_REENTRANT");
833     // Follow g++ convention and predefine _GNU_SOURCE for C++.
834     if (Opts.CPlusPlus)
835       Builder.defineMacro("_GNU_SOURCE");
836     // Indicate that we have __float128.
837     Builder.defineMacro("__FLOAT128__");
838   }
839 
840 public:
841   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
842                                    const TargetOptions &Opts)
843       : OSTargetInfo<Target>(Triple, Opts) {
844     this->MCountName = "__mcount";
845     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
846     this->HasFloat128 = true;
847   }
848 };
849 
850 // WASI target
851 template <typename Target>
852 class LLVM_LIBRARY_VISIBILITY WASITargetInfo
853     : public WebAssemblyOSTargetInfo<Target> {
854   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
855                     MacroBuilder &Builder) const final {
856     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
857     Builder.defineMacro("__wasi__");
858   }
859 
860 public:
861   explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
862       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
863 };
864 
865 // Emscripten target
866 template <typename Target>
867 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
868     : public WebAssemblyOSTargetInfo<Target> {
869   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
870                     MacroBuilder &Builder) const final {
871     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
872     Builder.defineMacro("__EMSCRIPTEN__");
873   }
874 
875 public:
876   explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
877       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
878 };
879 
880 } // namespace targets
881 } // namespace clang
882 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
883