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