]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / Basic / Targets / OSTargets.h
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 };
565
566 // RTEMS Target
567 template <typename Target>
568 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
569 protected:
570   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
571                     MacroBuilder &Builder) const override {
572     // RTEMS defines; list based off of gcc output
573
574     Builder.defineMacro("__rtems__");
575     Builder.defineMacro("__ELF__");
576     if (Opts.CPlusPlus)
577       Builder.defineMacro("_GNU_SOURCE");
578   }
579
580 public:
581   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
582       : OSTargetInfo<Target>(Triple, Opts) {
583     switch (Triple.getArch()) {
584     default:
585     case llvm::Triple::x86:
586       // this->MCountName = ".mcount";
587       break;
588     case llvm::Triple::mips:
589     case llvm::Triple::mipsel:
590     case llvm::Triple::ppc:
591     case llvm::Triple::ppc64:
592     case llvm::Triple::ppc64le:
593       // this->MCountName = "_mcount";
594       break;
595     case llvm::Triple::arm:
596       // this->MCountName = "__mcount";
597       break;
598     }
599   }
600 };
601
602 // Solaris target
603 template <typename Target>
604 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
605 protected:
606   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
607                     MacroBuilder &Builder) const override {
608     DefineStd(Builder, "sun", Opts);
609     DefineStd(Builder, "unix", Opts);
610     Builder.defineMacro("__ELF__");
611     Builder.defineMacro("__svr4__");
612     Builder.defineMacro("__SVR4");
613     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
614     // newer, but to 500 for everything else.  feature_test.h has a check to
615     // ensure that you are not using C99 with an old version of X/Open or C89
616     // with a new version.
617     if (Opts.C99)
618       Builder.defineMacro("_XOPEN_SOURCE", "600");
619     else
620       Builder.defineMacro("_XOPEN_SOURCE", "500");
621     if (Opts.CPlusPlus) {
622       Builder.defineMacro("__C99FEATURES__");
623       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
624     }
625     // GCC restricts the next two to C++.
626     Builder.defineMacro("_LARGEFILE_SOURCE");
627     Builder.defineMacro("_LARGEFILE64_SOURCE");
628     Builder.defineMacro("__EXTENSIONS__");
629     if (Opts.POSIXThreads)
630       Builder.defineMacro("_REENTRANT");
631     if (this->HasFloat128)
632       Builder.defineMacro("__FLOAT128__");
633   }
634
635 public:
636   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
637       : OSTargetInfo<Target>(Triple, Opts) {
638     if (this->PointerWidth == 64) {
639       this->WCharType = this->WIntType = this->SignedInt;
640     } else {
641       this->WCharType = this->WIntType = this->SignedLong;
642     }
643     switch (Triple.getArch()) {
644     default:
645       break;
646     case llvm::Triple::x86:
647     case llvm::Triple::x86_64:
648       this->HasFloat128 = true;
649       break;
650     }
651   }
652 };
653
654 // AIX Target
655 template <typename Target>
656 class AIXTargetInfo : public OSTargetInfo<Target> {
657 protected:
658   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
659                     MacroBuilder &Builder) const override {
660     DefineStd(Builder, "unix", Opts);
661     Builder.defineMacro("_IBMR2");
662     Builder.defineMacro("_POWER");
663
664     Builder.defineMacro("_AIX");
665
666     unsigned Major, Minor, Micro;
667     Triple.getOSVersion(Major, Minor, Micro);
668
669     // Define AIX OS-Version Macros.
670     // Includes logic for legacy versions of AIX; no specific intent to support.
671     std::pair<int, int> OsVersion = {Major, Minor};
672     if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
673     if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
674     if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
675     if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
676     if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
677     if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
678     if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
679     if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
680     if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
681     if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
682
683     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
684     Builder.defineMacro("_LONG_LONG");
685
686     if (Opts.POSIXThreads) {
687       Builder.defineMacro("_THREAD_SAFE");
688     }
689
690     if (this->PointerWidth == 64) {
691       Builder.defineMacro("__64BIT__");
692     }
693
694     // Define _WCHAR_T when it is a fundamental type
695     // (i.e., for C++ without -fno-wchar).
696     if (Opts.CPlusPlus && Opts.WChar) {
697       Builder.defineMacro("_WCHAR_T");
698     }
699   }
700
701 public:
702   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
703       : OSTargetInfo<Target>(Triple, Opts) {
704     if (this->PointerWidth == 64) {
705       this->WCharType = this->UnsignedInt;
706     } else {
707       this->WCharType = this->UnsignedShort;
708     }
709     this->UseZeroLengthBitfieldAlignment = true;
710   }
711
712   // AIX sets FLT_EVAL_METHOD to be 1.
713   unsigned getFloatEvalMethod() const override { return 1; }
714   bool hasInt128Type() const override { return false; }
715 };
716
717 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
718                        MacroBuilder &Builder);
719
720 // Windows target
721 template <typename Target>
722 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
723 protected:
724   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
725                     MacroBuilder &Builder) const override {
726     addWindowsDefines(Triple, Opts, Builder);
727   }
728
729 public:
730   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
731       : OSTargetInfo<Target>(Triple, Opts) {
732     this->WCharType = TargetInfo::UnsignedShort;
733     this->WIntType = TargetInfo::UnsignedShort;
734   }
735 };
736
737 template <typename Target>
738 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
739 protected:
740   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
741                     MacroBuilder &Builder) const override {
742     if (Opts.POSIXThreads)
743       Builder.defineMacro("_REENTRANT");
744     if (Opts.CPlusPlus)
745       Builder.defineMacro("_GNU_SOURCE");
746
747     DefineStd(Builder, "unix", Opts);
748     Builder.defineMacro("__ELF__");
749     Builder.defineMacro("__native_client__");
750   }
751
752 public:
753   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
754       : OSTargetInfo<Target>(Triple, Opts) {
755     this->LongAlign = 32;
756     this->LongWidth = 32;
757     this->PointerAlign = 32;
758     this->PointerWidth = 32;
759     this->IntMaxType = TargetInfo::SignedLongLong;
760     this->Int64Type = TargetInfo::SignedLongLong;
761     this->DoubleAlign = 64;
762     this->LongDoubleWidth = 64;
763     this->LongDoubleAlign = 64;
764     this->LongLongWidth = 64;
765     this->LongLongAlign = 64;
766     this->SizeType = TargetInfo::UnsignedInt;
767     this->PtrDiffType = TargetInfo::SignedInt;
768     this->IntPtrType = TargetInfo::SignedInt;
769     // RegParmMax is inherited from the underlying architecture.
770     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
771     if (Triple.getArch() == llvm::Triple::arm) {
772       // Handled in ARM's setABI().
773     } else if (Triple.getArch() == llvm::Triple::x86) {
774       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128");
775     } else if (Triple.getArch() == llvm::Triple::x86_64) {
776       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128");
777     } else if (Triple.getArch() == llvm::Triple::mipsel) {
778       // Handled on mips' setDataLayout.
779     } else {
780       assert(Triple.getArch() == llvm::Triple::le32);
781       this->resetDataLayout("e-p:32:32-i64:64");
782     }
783   }
784 };
785
786 // Fuchsia Target
787 template <typename Target>
788 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
789 protected:
790   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
791                     MacroBuilder &Builder) const override {
792     Builder.defineMacro("__Fuchsia__");
793     Builder.defineMacro("__ELF__");
794     if (Opts.POSIXThreads)
795       Builder.defineMacro("_REENTRANT");
796     // Required by the libc++ locale support.
797     if (Opts.CPlusPlus)
798       Builder.defineMacro("_GNU_SOURCE");
799   }
800
801 public:
802   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
803       : OSTargetInfo<Target>(Triple, Opts) {
804     this->MCountName = "__mcount";
805   }
806 };
807
808 // WebAssembly target
809 template <typename Target>
810 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
811     : public OSTargetInfo<Target> {
812 protected:
813   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
814                     MacroBuilder &Builder) const {
815     // A common platform macro.
816     if (Opts.POSIXThreads)
817       Builder.defineMacro("_REENTRANT");
818     // Follow g++ convention and predefine _GNU_SOURCE for C++.
819     if (Opts.CPlusPlus)
820       Builder.defineMacro("_GNU_SOURCE");
821     // Indicate that we have __float128.
822     Builder.defineMacro("__FLOAT128__");
823   }
824
825 public:
826   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
827                                    const TargetOptions &Opts)
828       : OSTargetInfo<Target>(Triple, Opts) {
829     this->MCountName = "__mcount";
830     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
831     this->HasFloat128 = true;
832   }
833 };
834
835 // WASI target
836 template <typename Target>
837 class LLVM_LIBRARY_VISIBILITY WASITargetInfo
838     : public WebAssemblyOSTargetInfo<Target> {
839   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
840                     MacroBuilder &Builder) const final {
841     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
842     Builder.defineMacro("__wasi__");
843   }
844
845 public:
846   explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
847       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
848 };
849
850 // Emscripten target
851 template <typename Target>
852 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
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("__EMSCRIPTEN__");
858   }
859
860 public:
861   explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
862       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
863 };
864
865 } // namespace targets
866 } // namespace clang
867 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H