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