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