xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
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 whitelist 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     switch (Triple.getArch()) {
469     case llvm::Triple::x86:
470     case llvm::Triple::x86_64:
471       this->HasFloat128 = true;
472       LLVM_FALLTHROUGH;
473     default:
474       this->MCountName = "__mcount";
475       break;
476     case llvm::Triple::mips64:
477     case llvm::Triple::mips64el:
478     case llvm::Triple::ppc:
479     case llvm::Triple::sparcv9:
480       this->MCountName = "_mcount";
481       break;
482     }
483   }
484 };
485 
486 // PSP Target
487 template <typename Target>
488 class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
489 protected:
490   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
491                     MacroBuilder &Builder) const override {
492     // PSP defines; list based on the output of the pspdev gcc toolchain.
493     Builder.defineMacro("PSP");
494     Builder.defineMacro("_PSP");
495     Builder.defineMacro("__psp__");
496     Builder.defineMacro("__ELF__");
497   }
498 
499 public:
500   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
501 };
502 
503 // PS3 PPU Target
504 template <typename Target>
505 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
506 protected:
507   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
508                     MacroBuilder &Builder) const override {
509     // PS3 PPU defines.
510     Builder.defineMacro("__PPC__");
511     Builder.defineMacro("__PPU__");
512     Builder.defineMacro("__CELLOS_LV2__");
513     Builder.defineMacro("__ELF__");
514     Builder.defineMacro("__LP32__");
515     Builder.defineMacro("_ARCH_PPC64");
516     Builder.defineMacro("__powerpc64__");
517   }
518 
519 public:
520   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
521       : OSTargetInfo<Target>(Triple, Opts) {
522     this->LongWidth = this->LongAlign = 32;
523     this->PointerWidth = this->PointerAlign = 32;
524     this->IntMaxType = TargetInfo::SignedLongLong;
525     this->Int64Type = TargetInfo::SignedLongLong;
526     this->SizeType = TargetInfo::UnsignedInt;
527     this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
528   }
529 };
530 
531 template <typename Target>
532 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
533 protected:
534   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
535                     MacroBuilder &Builder) const override {
536     Builder.defineMacro("__FreeBSD__", "9");
537     Builder.defineMacro("__FreeBSD_cc_version", "900001");
538     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
539     DefineStd(Builder, "unix", Opts);
540     Builder.defineMacro("__ELF__");
541     Builder.defineMacro("__ORBIS__");
542   }
543 
544 public:
545   PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
546       : OSTargetInfo<Target>(Triple, Opts) {
547     this->WCharType = TargetInfo::UnsignedShort;
548 
549     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
550     this->MaxTLSAlign = 256;
551 
552     // On PS4, do not honor explicit bit field alignment,
553     // as in "__attribute__((aligned(2))) int b : 1;".
554     this->UseExplicitBitFieldAlignment = false;
555 
556     switch (Triple.getArch()) {
557     default:
558     case llvm::Triple::x86_64:
559       this->MCountName = ".mcount";
560       this->NewAlign = 256;
561       break;
562     }
563   }
564   TargetInfo::CallingConvCheckResult
565   checkCallingConvention(CallingConv CC) const override {
566     return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
567   }
568 };
569 
570 // RTEMS Target
571 template <typename Target>
572 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
573 protected:
574   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
575                     MacroBuilder &Builder) const override {
576     // RTEMS defines; list based off of gcc output
577 
578     Builder.defineMacro("__rtems__");
579     Builder.defineMacro("__ELF__");
580     if (Opts.CPlusPlus)
581       Builder.defineMacro("_GNU_SOURCE");
582   }
583 
584 public:
585   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
586       : OSTargetInfo<Target>(Triple, Opts) {
587     switch (Triple.getArch()) {
588     default:
589     case llvm::Triple::x86:
590       // this->MCountName = ".mcount";
591       break;
592     case llvm::Triple::mips:
593     case llvm::Triple::mipsel:
594     case llvm::Triple::ppc:
595     case llvm::Triple::ppc64:
596     case llvm::Triple::ppc64le:
597       // this->MCountName = "_mcount";
598       break;
599     case llvm::Triple::arm:
600       // this->MCountName = "__mcount";
601       break;
602     }
603   }
604 };
605 
606 // Solaris target
607 template <typename Target>
608 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
609 protected:
610   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
611                     MacroBuilder &Builder) const override {
612     DefineStd(Builder, "sun", Opts);
613     DefineStd(Builder, "unix", Opts);
614     Builder.defineMacro("__ELF__");
615     Builder.defineMacro("__svr4__");
616     Builder.defineMacro("__SVR4");
617     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
618     // newer, but to 500 for everything else.  feature_test.h has a check to
619     // ensure that you are not using C99 with an old version of X/Open or C89
620     // with a new version.
621     if (Opts.C99)
622       Builder.defineMacro("_XOPEN_SOURCE", "600");
623     else
624       Builder.defineMacro("_XOPEN_SOURCE", "500");
625     if (Opts.CPlusPlus) {
626       Builder.defineMacro("__C99FEATURES__");
627       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
628     }
629     // GCC restricts the next two to C++.
630     Builder.defineMacro("_LARGEFILE_SOURCE");
631     Builder.defineMacro("_LARGEFILE64_SOURCE");
632     Builder.defineMacro("__EXTENSIONS__");
633     if (Opts.POSIXThreads)
634       Builder.defineMacro("_REENTRANT");
635     if (this->HasFloat128)
636       Builder.defineMacro("__FLOAT128__");
637   }
638 
639 public:
640   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
641       : OSTargetInfo<Target>(Triple, Opts) {
642     if (this->PointerWidth == 64) {
643       this->WCharType = this->WIntType = this->SignedInt;
644     } else {
645       this->WCharType = this->WIntType = this->SignedLong;
646     }
647     switch (Triple.getArch()) {
648     default:
649       break;
650     case llvm::Triple::x86:
651     case llvm::Triple::x86_64:
652       this->HasFloat128 = true;
653       break;
654     }
655   }
656 };
657 
658 // AIX Target
659 template <typename Target>
660 class AIXTargetInfo : public OSTargetInfo<Target> {
661 protected:
662   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
663                     MacroBuilder &Builder) const override {
664     DefineStd(Builder, "unix", Opts);
665     Builder.defineMacro("_IBMR2");
666     Builder.defineMacro("_POWER");
667 
668     Builder.defineMacro("_AIX");
669 
670     unsigned Major, Minor, Micro;
671     Triple.getOSVersion(Major, Minor, Micro);
672 
673     // Define AIX OS-Version Macros.
674     // Includes logic for legacy versions of AIX; no specific intent to support.
675     std::pair<int, int> OsVersion = {Major, Minor};
676     if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
677     if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
678     if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
679     if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
680     if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
681     if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
682     if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
683     if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
684     if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
685     if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
686 
687     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
688     Builder.defineMacro("_LONG_LONG");
689 
690     if (Opts.POSIXThreads) {
691       Builder.defineMacro("_THREAD_SAFE");
692     }
693 
694     if (this->PointerWidth == 64) {
695       Builder.defineMacro("__64BIT__");
696     }
697 
698     // Define _WCHAR_T when it is a fundamental type
699     // (i.e., for C++ without -fno-wchar).
700     if (Opts.CPlusPlus && Opts.WChar) {
701       Builder.defineMacro("_WCHAR_T");
702     }
703   }
704 
705 public:
706   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
707       : OSTargetInfo<Target>(Triple, Opts) {
708     if (this->PointerWidth == 64) {
709       this->WCharType = this->UnsignedInt;
710     } else {
711       this->WCharType = this->UnsignedShort;
712     }
713     this->UseZeroLengthBitfieldAlignment = true;
714   }
715 
716   // AIX sets FLT_EVAL_METHOD to be 1.
717   unsigned getFloatEvalMethod() const override { return 1; }
718   bool hasInt128Type() const override { return false; }
719 };
720 
721 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
722                        MacroBuilder &Builder);
723 
724 // Windows target
725 template <typename Target>
726 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
727 protected:
728   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
729                     MacroBuilder &Builder) const override {
730     addWindowsDefines(Triple, Opts, Builder);
731   }
732 
733 public:
734   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
735       : OSTargetInfo<Target>(Triple, Opts) {
736     this->WCharType = TargetInfo::UnsignedShort;
737     this->WIntType = TargetInfo::UnsignedShort;
738   }
739 };
740 
741 template <typename Target>
742 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
743 protected:
744   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
745                     MacroBuilder &Builder) const override {
746     if (Opts.POSIXThreads)
747       Builder.defineMacro("_REENTRANT");
748     if (Opts.CPlusPlus)
749       Builder.defineMacro("_GNU_SOURCE");
750 
751     DefineStd(Builder, "unix", Opts);
752     Builder.defineMacro("__ELF__");
753     Builder.defineMacro("__native_client__");
754   }
755 
756 public:
757   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
758       : OSTargetInfo<Target>(Triple, Opts) {
759     this->LongAlign = 32;
760     this->LongWidth = 32;
761     this->PointerAlign = 32;
762     this->PointerWidth = 32;
763     this->IntMaxType = TargetInfo::SignedLongLong;
764     this->Int64Type = TargetInfo::SignedLongLong;
765     this->DoubleAlign = 64;
766     this->LongDoubleWidth = 64;
767     this->LongDoubleAlign = 64;
768     this->LongLongWidth = 64;
769     this->LongLongAlign = 64;
770     this->SizeType = TargetInfo::UnsignedInt;
771     this->PtrDiffType = TargetInfo::SignedInt;
772     this->IntPtrType = TargetInfo::SignedInt;
773     // RegParmMax is inherited from the underlying architecture.
774     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
775     if (Triple.getArch() == llvm::Triple::arm) {
776       // Handled in ARM's setABI().
777     } else if (Triple.getArch() == llvm::Triple::x86) {
778       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
779                             "i64:64-n8:16:32-S128");
780     } else if (Triple.getArch() == llvm::Triple::x86_64) {
781       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
782                             "i64:64-n8:16:32:64-S128");
783     } else if (Triple.getArch() == llvm::Triple::mipsel) {
784       // Handled on mips' setDataLayout.
785     } else {
786       assert(Triple.getArch() == llvm::Triple::le32);
787       this->resetDataLayout("e-p:32:32-i64:64");
788     }
789   }
790 };
791 
792 // Fuchsia Target
793 template <typename Target>
794 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
795 protected:
796   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
797                     MacroBuilder &Builder) const override {
798     Builder.defineMacro("__Fuchsia__");
799     Builder.defineMacro("__ELF__");
800     if (Opts.POSIXThreads)
801       Builder.defineMacro("_REENTRANT");
802     // Required by the libc++ locale support.
803     if (Opts.CPlusPlus)
804       Builder.defineMacro("_GNU_SOURCE");
805   }
806 
807 public:
808   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
809       : OSTargetInfo<Target>(Triple, Opts) {
810     this->MCountName = "__mcount";
811   }
812 };
813 
814 // WebAssembly target
815 template <typename Target>
816 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
817     : public OSTargetInfo<Target> {
818 protected:
819   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
820                     MacroBuilder &Builder) const {
821     // A common platform macro.
822     if (Opts.POSIXThreads)
823       Builder.defineMacro("_REENTRANT");
824     // Follow g++ convention and predefine _GNU_SOURCE for C++.
825     if (Opts.CPlusPlus)
826       Builder.defineMacro("_GNU_SOURCE");
827     // Indicate that we have __float128.
828     Builder.defineMacro("__FLOAT128__");
829   }
830 
831 public:
832   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
833                                    const TargetOptions &Opts)
834       : OSTargetInfo<Target>(Triple, Opts) {
835     this->MCountName = "__mcount";
836     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
837     this->HasFloat128 = true;
838   }
839 };
840 
841 // WASI target
842 template <typename Target>
843 class LLVM_LIBRARY_VISIBILITY WASITargetInfo
844     : public WebAssemblyOSTargetInfo<Target> {
845   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
846                     MacroBuilder &Builder) const final {
847     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
848     Builder.defineMacro("__wasi__");
849   }
850 
851 public:
852   explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
853       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
854 };
855 
856 // Emscripten target
857 template <typename Target>
858 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
859     : public WebAssemblyOSTargetInfo<Target> {
860   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
861                     MacroBuilder &Builder) const final {
862     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
863     Builder.defineMacro("__EMSCRIPTEN__");
864   }
865 
866 public:
867   explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
868       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
869 };
870 
871 } // namespace targets
872 } // namespace clang
873 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
874