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   }
341 
342 public:
343   LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
344       : OSTargetInfo<Target>(Triple, Opts) {
345     this->WIntType = TargetInfo::UnsignedInt;
346 
347     switch (Triple.getArch()) {
348     default:
349       break;
350     case llvm::Triple::mips:
351     case llvm::Triple::mipsel:
352     case llvm::Triple::mips64:
353     case llvm::Triple::mips64el:
354     case llvm::Triple::ppc:
355     case llvm::Triple::ppcle:
356     case llvm::Triple::ppc64:
357     case llvm::Triple::ppc64le:
358       this->MCountName = "_mcount";
359       break;
360     case llvm::Triple::x86:
361     case llvm::Triple::x86_64:
362       this->HasFloat128 = true;
363       break;
364     }
365   }
366 
367   const char *getStaticInitSectionSpecifier() const override {
368     return ".text.startup";
369   }
370 };
371 
372 // NetBSD Target
373 template <typename Target>
374 class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
375 protected:
376   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
377                     MacroBuilder &Builder) const override {
378     // NetBSD defines; list based off of gcc output
379     Builder.defineMacro("__NetBSD__");
380     Builder.defineMacro("__unix__");
381     if (Opts.POSIXThreads)
382       Builder.defineMacro("_REENTRANT");
383     if (this->HasFloat128)
384       Builder.defineMacro("__FLOAT128__");
385   }
386 
387 public:
388   NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
389       : OSTargetInfo<Target>(Triple, Opts) {
390     this->MCountName = "__mcount";
391     switch (Triple.getArch()) {
392     default:
393       break;
394     case llvm::Triple::x86:
395     case llvm::Triple::x86_64:
396       this->HasFloat128 = true;
397       break;
398     }
399   }
400 };
401 
402 // OpenBSD Target
403 template <typename Target>
404 class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
405 protected:
406   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
407                     MacroBuilder &Builder) const override {
408     // OpenBSD defines; list based off of gcc output
409 
410     Builder.defineMacro("__OpenBSD__");
411     DefineStd(Builder, "unix", Opts);
412     if (Opts.POSIXThreads)
413       Builder.defineMacro("_REENTRANT");
414     if (this->HasFloat128)
415       Builder.defineMacro("__FLOAT128__");
416 
417     if (Opts.C11)
418       Builder.defineMacro("__STDC_NO_THREADS__");
419   }
420 
421 public:
422   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
423       : OSTargetInfo<Target>(Triple, Opts) {
424     this->WCharType = this->WIntType = this->SignedInt;
425     this->IntMaxType = TargetInfo::SignedLongLong;
426     this->Int64Type = TargetInfo::SignedLongLong;
427     switch (Triple.getArch()) {
428     case llvm::Triple::x86:
429     case llvm::Triple::x86_64:
430       this->HasFloat128 = true;
431       [[fallthrough]];
432     default:
433       this->MCountName = "__mcount";
434       break;
435     case llvm::Triple::mips64:
436     case llvm::Triple::mips64el:
437     case llvm::Triple::ppc:
438     case llvm::Triple::ppc64:
439     case llvm::Triple::ppc64le:
440     case llvm::Triple::sparcv9:
441       this->MCountName = "_mcount";
442       break;
443     case llvm::Triple::riscv32:
444     case llvm::Triple::riscv64:
445       break;
446     }
447   }
448 };
449 
450 // PS3 PPU Target
451 template <typename Target>
452 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
453 protected:
454   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
455                     MacroBuilder &Builder) const override {
456     // PS3 PPU defines.
457     Builder.defineMacro("__PPU__");
458     Builder.defineMacro("__CELLOS_LV2__");
459     Builder.defineMacro("__LP32__");
460     Builder.defineMacro("_ARCH_PPC64");
461     Builder.defineMacro("__powerpc64__");
462   }
463 
464 public:
465   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
466       : OSTargetInfo<Target>(Triple, Opts) {
467     this->LongWidth = this->LongAlign = 32;
468     this->PointerWidth = this->PointerAlign = 32;
469     this->IntMaxType = TargetInfo::SignedLongLong;
470     this->Int64Type = TargetInfo::SignedLongLong;
471     this->SizeType = TargetInfo::UnsignedInt;
472     this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64");
473   }
474 };
475 
476 // Common base class for PS4/PS5 targets.
477 template <typename Target>
478 class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> {
479 protected:
480   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
481                     MacroBuilder &Builder) const override {
482     Builder.defineMacro("__FreeBSD__", "9");
483     Builder.defineMacro("__FreeBSD_cc_version", "900001");
484     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
485     DefineStd(Builder, "unix", Opts);
486     Builder.defineMacro("__SCE__");
487     Builder.defineMacro("__STDC_NO_COMPLEX__");
488     Builder.defineMacro("__STDC_NO_THREADS__");
489   }
490 
491 public:
492   PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
493       : OSTargetInfo<Target>(Triple, Opts) {
494     this->WCharType = TargetInfo::UnsignedShort;
495 
496     // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256
497     // bits).
498     this->MaxTLSAlign = 256;
499 
500     // On PS4/PS5, do not honor explicit bit field alignment,
501     // as in "__attribute__((aligned(2))) int b : 1;".
502     this->UseExplicitBitFieldAlignment = false;
503 
504     this->MCountName = ".mcount";
505     this->NewAlign = 256;
506     this->SuitableAlign = 256;
507   }
508 
509   TargetInfo::CallingConvCheckResult
510   checkCallingConvention(CallingConv CC) const override {
511     return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
512   }
513 
514   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
515     return false;
516   }
517 };
518 
519 // PS4 Target
520 template <typename Target>
521 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> {
522 protected:
523   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
524                     MacroBuilder &Builder) const override {
525     // Start with base class defines.
526     PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
527 
528     Builder.defineMacro("__ORBIS__");
529   }
530 
531 public:
532   using PSOSTargetInfo<Target>::PSOSTargetInfo;
533 };
534 
535 // PS5 Target
536 template <typename Target>
537 class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> {
538 protected:
539   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
540                     MacroBuilder &Builder) const override {
541     // Start with base class defines.
542     PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
543 
544     Builder.defineMacro("__PROSPERO__");
545   }
546 
547 public:
548   using PSOSTargetInfo<Target>::PSOSTargetInfo;
549 };
550 
551 // RTEMS Target
552 template <typename Target>
553 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
554 protected:
555   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
556                     MacroBuilder &Builder) const override {
557     // RTEMS defines; list based off of gcc output
558 
559     Builder.defineMacro("__rtems__");
560     if (Opts.CPlusPlus)
561       Builder.defineMacro("_GNU_SOURCE");
562   }
563 
564 public:
565   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
566       : OSTargetInfo<Target>(Triple, Opts) {
567     switch (Triple.getArch()) {
568     default:
569     case llvm::Triple::x86:
570       // this->MCountName = ".mcount";
571       break;
572     case llvm::Triple::mips:
573     case llvm::Triple::mipsel:
574     case llvm::Triple::ppc:
575     case llvm::Triple::ppc64:
576     case llvm::Triple::ppc64le:
577       // this->MCountName = "_mcount";
578       break;
579     case llvm::Triple::arm:
580       // this->MCountName = "__mcount";
581       break;
582     }
583   }
584 };
585 
586 // Solaris target
587 template <typename Target>
588 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
589 protected:
590   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
591                     MacroBuilder &Builder) const override {
592     DefineStd(Builder, "sun", Opts);
593     DefineStd(Builder, "unix", Opts);
594     Builder.defineMacro("__svr4__");
595     Builder.defineMacro("__SVR4");
596     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
597     // newer, but to 500 for everything else.  feature_test.h has a check to
598     // ensure that you are not using C99 with an old version of X/Open or C89
599     // with a new version.
600     if (Opts.C99)
601       Builder.defineMacro("_XOPEN_SOURCE", "600");
602     else
603       Builder.defineMacro("_XOPEN_SOURCE", "500");
604     if (Opts.CPlusPlus) {
605       Builder.defineMacro("__C99FEATURES__");
606       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
607     }
608     // GCC restricts the next two to C++.
609     Builder.defineMacro("_LARGEFILE_SOURCE");
610     Builder.defineMacro("_LARGEFILE64_SOURCE");
611     Builder.defineMacro("__EXTENSIONS__");
612     if (Opts.POSIXThreads)
613       Builder.defineMacro("_REENTRANT");
614     if (this->HasFloat128)
615       Builder.defineMacro("__FLOAT128__");
616   }
617 
618 public:
619   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
620       : OSTargetInfo<Target>(Triple, Opts) {
621     if (this->PointerWidth == 64) {
622       this->WCharType = this->WIntType = this->SignedInt;
623     } else {
624       this->WCharType = this->WIntType = this->SignedLong;
625     }
626     switch (Triple.getArch()) {
627     default:
628       break;
629     case llvm::Triple::x86:
630     case llvm::Triple::x86_64:
631       this->HasFloat128 = true;
632       break;
633     }
634   }
635 };
636 
637 // AIX Target
638 template <typename Target>
639 class AIXTargetInfo : public OSTargetInfo<Target> {
640 protected:
641   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
642                     MacroBuilder &Builder) const override {
643     DefineStd(Builder, "unix", Opts);
644     Builder.defineMacro("_IBMR2");
645     Builder.defineMacro("_POWER");
646     Builder.defineMacro("__THW_BIG_ENDIAN__");
647 
648     Builder.defineMacro("_AIX");
649     Builder.defineMacro("__TOS_AIX__");
650     Builder.defineMacro("__HOS_AIX__");
651 
652     if (Opts.C11) {
653       Builder.defineMacro("__STDC_NO_ATOMICS__");
654       Builder.defineMacro("__STDC_NO_THREADS__");
655     }
656 
657     if (Opts.EnableAIXExtendedAltivecABI)
658       Builder.defineMacro("__EXTABI__");
659 
660     VersionTuple OsVersion = Triple.getOSVersion();
661 
662     // Define AIX OS-Version Macros.
663     // Includes logic for legacy versions of AIX; no specific intent to support.
664     if (OsVersion >= VersionTuple(3, 2))
665       Builder.defineMacro("_AIX32");
666     if (OsVersion >= VersionTuple(4, 1))
667       Builder.defineMacro("_AIX41");
668     if (OsVersion >= VersionTuple(4, 3))
669       Builder.defineMacro("_AIX43");
670     if (OsVersion >= VersionTuple(5, 0))
671       Builder.defineMacro("_AIX50");
672     if (OsVersion >= VersionTuple(5, 1))
673       Builder.defineMacro("_AIX51");
674     if (OsVersion >= VersionTuple(5, 2))
675       Builder.defineMacro("_AIX52");
676     if (OsVersion >= VersionTuple(5, 3))
677       Builder.defineMacro("_AIX53");
678     if (OsVersion >= VersionTuple(6, 1))
679       Builder.defineMacro("_AIX61");
680     if (OsVersion >= VersionTuple(7, 1))
681       Builder.defineMacro("_AIX71");
682     if (OsVersion >= VersionTuple(7, 2))
683       Builder.defineMacro("_AIX72");
684     if (OsVersion >= VersionTuple(7, 3))
685       Builder.defineMacro("_AIX73");
686 
687     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
688     Builder.defineMacro("_LONG_LONG");
689 
690     if (Opts.POSIXThreads) {
691       Builder.defineMacro("_THREAD_SAFE");
692     }
693 
694     if (this->PointerWidth == 64) {
695       Builder.defineMacro("__64BIT__");
696     }
697 
698     // Define _WCHAR_T when it is a fundamental type
699     // (i.e., for C++ without -fno-wchar).
700     if (Opts.CPlusPlus && Opts.WChar) {
701       Builder.defineMacro("_WCHAR_T");
702     }
703   }
704 
705 public:
706   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
707       : OSTargetInfo<Target>(Triple, Opts) {
708     this->MCountName = "__mcount";
709     this->TheCXXABI.set(TargetCXXABI::XL);
710 
711     if (this->PointerWidth == 64) {
712       this->WCharType = this->UnsignedInt;
713     } else {
714       this->WCharType = this->UnsignedShort;
715     }
716     this->UseZeroLengthBitfieldAlignment = true;
717   }
718 
719   // AIX sets FLT_EVAL_METHOD to be 1.
720   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
721     return LangOptions::FPEvalMethodKind::FEM_Double;
722   }
723 
724   bool defaultsToAIXPowerAlignment() const override { return true; }
725 
726   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
727     return false;
728   }
729 };
730 
731 // z/OS target
732 template <typename Target>
733 class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> {
734 protected:
735   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
736                     MacroBuilder &Builder) const override {
737     // FIXME: _LONG_LONG should not be defined under -std=c89.
738     Builder.defineMacro("_LONG_LONG");
739     Builder.defineMacro("__370__");
740     Builder.defineMacro("__BFP__");
741     // FIXME: __BOOL__ should not be defined under -std=c89.
742     Builder.defineMacro("__BOOL__");
743     Builder.defineMacro("__COMPILER_VER__", "0x50000000");
744     Builder.defineMacro("__LONGNAME__");
745     Builder.defineMacro("__MVS__");
746     Builder.defineMacro("__THW_370__");
747     Builder.defineMacro("__THW_BIG_ENDIAN__");
748     Builder.defineMacro("__TOS_390__");
749     Builder.defineMacro("__TOS_MVS__");
750     Builder.defineMacro("__XPLINK__");
751 
752     if (this->PointerWidth == 64)
753       Builder.defineMacro("__64BIT__");
754 
755     if (Opts.CPlusPlus && Opts.WChar) {
756       // Macro __wchar_t is defined so that the wchar_t data
757       // type is not declared as a typedef in system headers.
758       Builder.defineMacro("__wchar_t");
759     }
760 
761     this->PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
762   }
763 
764 public:
765   ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
766       : OSTargetInfo<Target>(Triple, Opts) {
767     this->WCharType = TargetInfo::UnsignedInt;
768     this->MaxAlignedAttribute = 128;
769     this->UseBitFieldTypeAlignment = false;
770     this->UseZeroLengthBitfieldAlignment = true;
771     this->UseLeadingZeroLengthBitfield = false;
772     this->ZeroLengthBitfieldBoundary = 32;
773     this->TheCXXABI.set(TargetCXXABI::XL);
774   }
775 
776   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
777     return false;
778   }
779 };
780 
781 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
782                        MacroBuilder &Builder);
783 
784 // Windows target
785 template <typename Target>
786 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
787 protected:
788   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
789                     MacroBuilder &Builder) const override {
790     addWindowsDefines(Triple, Opts, Builder);
791   }
792 
793 public:
794   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
795       : OSTargetInfo<Target>(Triple, Opts) {
796     this->WCharType = TargetInfo::UnsignedShort;
797     this->WIntType = TargetInfo::UnsignedShort;
798   }
799 };
800 
801 template <typename Target>
802 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
803 protected:
804   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
805                     MacroBuilder &Builder) const override {
806     if (Opts.POSIXThreads)
807       Builder.defineMacro("_REENTRANT");
808     if (Opts.CPlusPlus)
809       Builder.defineMacro("_GNU_SOURCE");
810 
811     DefineStd(Builder, "unix", Opts);
812     Builder.defineMacro("__native_client__");
813   }
814 
815 public:
816   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
817       : OSTargetInfo<Target>(Triple, Opts) {
818     this->LongAlign = 32;
819     this->LongWidth = 32;
820     this->PointerAlign = 32;
821     this->PointerWidth = 32;
822     this->IntMaxType = TargetInfo::SignedLongLong;
823     this->Int64Type = TargetInfo::SignedLongLong;
824     this->DoubleAlign = 64;
825     this->LongDoubleWidth = 64;
826     this->LongDoubleAlign = 64;
827     this->LongLongWidth = 64;
828     this->LongLongAlign = 64;
829     this->SizeType = TargetInfo::UnsignedInt;
830     this->PtrDiffType = TargetInfo::SignedInt;
831     this->IntPtrType = TargetInfo::SignedInt;
832     // RegParmMax is inherited from the underlying architecture.
833     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
834     if (Triple.getArch() == llvm::Triple::arm) {
835       // Handled in ARM's setABI().
836     } else if (Triple.getArch() == llvm::Triple::x86) {
837       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
838                             "i64:64-i128:128-n8:16:32-S128");
839     } else if (Triple.getArch() == llvm::Triple::x86_64) {
840       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
841                             "i64:64-i128:128-n8:16:32:64-S128");
842     } else if (Triple.getArch() == llvm::Triple::mipsel) {
843       // Handled on mips' setDataLayout.
844     } else {
845       assert(Triple.getArch() == llvm::Triple::le32);
846       this->resetDataLayout("e-p:32:32-i64:64");
847     }
848   }
849 };
850 
851 // Fuchsia Target
852 template <typename Target>
853 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
854 protected:
855   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
856                     MacroBuilder &Builder) const override {
857     Builder.defineMacro("__Fuchsia__");
858     if (Opts.POSIXThreads)
859       Builder.defineMacro("_REENTRANT");
860     // Required by the libc++ locale support.
861     if (Opts.CPlusPlus)
862       Builder.defineMacro("_GNU_SOURCE");
863     Builder.defineMacro("__Fuchsia_API_level__", Twine(Opts.FuchsiaAPILevel));
864     this->PlatformName = "fuchsia";
865     this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel);
866   }
867 
868 public:
869   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
870       : OSTargetInfo<Target>(Triple, Opts) {
871     this->MCountName = "__mcount";
872     this->TheCXXABI.set(TargetCXXABI::Fuchsia);
873   }
874 };
875 
876 // WebAssembly target
877 template <typename Target>
878 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
879     : public OSTargetInfo<Target> {
880 protected:
881   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
882                     MacroBuilder &Builder) const override {
883     // A common platform macro.
884     if (Opts.POSIXThreads)
885       Builder.defineMacro("_REENTRANT");
886     // Follow g++ convention and predefine _GNU_SOURCE for C++.
887     if (Opts.CPlusPlus)
888       Builder.defineMacro("_GNU_SOURCE");
889     // Indicate that we have __float128.
890     Builder.defineMacro("__FLOAT128__");
891   }
892 
893 public:
894   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
895                                    const TargetOptions &Opts)
896       : OSTargetInfo<Target>(Triple, Opts) {
897     this->MCountName = "__mcount";
898     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
899     this->HasFloat128 = true;
900   }
901 };
902 
903 // WASI target
904 template <typename Target>
905 class LLVM_LIBRARY_VISIBILITY WASITargetInfo
906     : public WebAssemblyOSTargetInfo<Target> {
907   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
908                     MacroBuilder &Builder) const final {
909     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
910     Builder.defineMacro("__wasi__");
911   }
912 
913 public:
914   using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
915 };
916 
917 // Emscripten target
918 template <typename Target>
919 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
920     : public WebAssemblyOSTargetInfo<Target> {
921   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
922                     MacroBuilder &Builder) const final {
923     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
924     DefineStd(Builder, "unix", Opts);
925     Builder.defineMacro("__EMSCRIPTEN__");
926     if (Opts.POSIXThreads)
927       Builder.defineMacro("__EMSCRIPTEN_PTHREADS__");
928   }
929 
930 public:
931   explicit EmscriptenTargetInfo(const llvm::Triple &Triple,
932                                 const TargetOptions &Opts)
933       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {
934     // Keeping the alignment of long double to 8 bytes even though its size is
935     // 16 bytes allows emscripten to have an 8-byte-aligned max_align_t which
936     // in turn gives is a 8-byte aligned malloc.
937     // Emscripten's ABI is unstable and we may change this back to 128 to match
938     // the WebAssembly default in the future.
939     this->LongDoubleAlign = 64;
940   }
941 };
942 
943 // OHOS target
944 template <typename Target>
945 class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> {
946 protected:
947   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
948                     MacroBuilder &Builder) const override {
949     // Linux defines; list based off of gcc output
950     DefineStd(Builder, "unix", Opts);
951 
952     // Generic OHOS target defines
953     if (Triple.isOHOSFamily()) {
954       Builder.defineMacro("__OHOS_FAMILY__", "1");
955 
956       auto Version = Triple.getEnvironmentVersion();
957       this->PlatformName = "ohos";
958       this->PlatformMinVersion = Version;
959       Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor()));
960       if (auto Minor = Version.getMinor())
961         Builder.defineMacro("__OHOS_Minor__", Twine(*Minor));
962       if (auto Subminor = Version.getSubminor())
963         Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor));
964     }
965 
966     if (Triple.isOpenHOS())
967       Builder.defineMacro("__OHOS__");
968 
969     if (Triple.isOSLinux()) {
970       DefineStd(Builder, "linux", Opts);
971     } else if (Triple.isOSLiteOS()) {
972       Builder.defineMacro("__LITEOS__");
973     }
974 
975     if (Opts.POSIXThreads)
976       Builder.defineMacro("_REENTRANT");
977     if (Opts.CPlusPlus)
978       Builder.defineMacro("_GNU_SOURCE");
979     if (this->HasFloat128)
980       Builder.defineMacro("__FLOAT128__");
981   }
982 
983 public:
984   OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
985       : OSTargetInfo<Target>(Triple, Opts) {
986     this->WIntType = TargetInfo::UnsignedInt;
987 
988     switch (Triple.getArch()) {
989     default:
990       break;
991     case llvm::Triple::x86:
992     case llvm::Triple::x86_64:
993       this->HasFloat128 = true;
994       break;
995     }
996   }
997 
998   const char *getStaticInitSectionSpecifier() const override {
999     return ".text.startup";
1000   }
1001 };
1002 
1003 } // namespace targets
1004 } // namespace clang
1005 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
1006