10b57cec5SDimitry Andric //===--- OSTargets.h - Declare OS target feature support --------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares OS specific TargetInfo types.
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
130b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "Targets.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric namespace clang {
180b57cec5SDimitry Andric namespace targets {
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric template <typename TgtInfo>
210b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY OSTargetInfo : public TgtInfo {
220b57cec5SDimitry Andric protected:
230b57cec5SDimitry Andric   virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
240b57cec5SDimitry Andric                             MacroBuilder &Builder) const = 0;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric public:
OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)270b57cec5SDimitry Andric   OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
280b57cec5SDimitry Andric       : TgtInfo(Triple, Opts) {}
290b57cec5SDimitry Andric 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)300b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
310b57cec5SDimitry Andric                         MacroBuilder &Builder) const override {
320b57cec5SDimitry Andric     TgtInfo::getTargetDefines(Opts, Builder);
330b57cec5SDimitry Andric     getOSDefines(Opts, TgtInfo::getTriple(), Builder);
340b57cec5SDimitry Andric   }
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
380b57cec5SDimitry Andric                       const llvm::Triple &Triple, StringRef &PlatformName,
390b57cec5SDimitry Andric                       VersionTuple &PlatformMinVersion);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric template <typename Target>
420b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
430b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)440b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
450b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
460b57cec5SDimitry Andric     getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
470b57cec5SDimitry Andric                      this->PlatformMinVersion);
480b57cec5SDimitry Andric   }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric public:
DarwinTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)510b57cec5SDimitry Andric   DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
520b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
535ffd83dbSDimitry Andric     // By default, no TLS, and we list permitted architecture/OS
540b57cec5SDimitry Andric     // combinations.
550b57cec5SDimitry Andric     this->TLSSupported = false;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric     if (Triple.isMacOSX())
580b57cec5SDimitry Andric       this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
590b57cec5SDimitry Andric     else if (Triple.isiOS()) {
600b57cec5SDimitry Andric       // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
610b57cec5SDimitry Andric       // 32-bit simulator from 10 onwards.
620b57cec5SDimitry Andric       if (Triple.isArch64Bit())
630b57cec5SDimitry Andric         this->TLSSupported = !Triple.isOSVersionLT(8);
640b57cec5SDimitry Andric       else if (Triple.isArch32Bit()) {
650b57cec5SDimitry Andric         if (!Triple.isSimulatorEnvironment())
660b57cec5SDimitry Andric           this->TLSSupported = !Triple.isOSVersionLT(9);
670b57cec5SDimitry Andric         else
680b57cec5SDimitry Andric           this->TLSSupported = !Triple.isOSVersionLT(10);
690b57cec5SDimitry Andric       }
700b57cec5SDimitry Andric     } else if (Triple.isWatchOS()) {
710b57cec5SDimitry Andric       if (!Triple.isSimulatorEnvironment())
720b57cec5SDimitry Andric         this->TLSSupported = !Triple.isOSVersionLT(2);
730b57cec5SDimitry Andric       else
740b57cec5SDimitry Andric         this->TLSSupported = !Triple.isOSVersionLT(3);
7581ad6265SDimitry Andric     } else if (Triple.isDriverKit()) {
7681ad6265SDimitry Andric       // No TLS on DriverKit.
777a6dacacSDimitry Andric     } else if (Triple.isXROS())
787a6dacacSDimitry Andric       this->TLSSupported = true;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric     this->MCountName = "\01mcount";
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
getStaticInitSectionSpecifier()830b57cec5SDimitry Andric   const char *getStaticInitSectionSpecifier() const override {
840b57cec5SDimitry Andric     // FIXME: We should return 0 when building kexts.
850b57cec5SDimitry Andric     return "__TEXT,__StaticInit,regular,pure_instructions";
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// Darwin does not support protected visibility.  Darwin's "default"
890b57cec5SDimitry Andric   /// is very similar to ELF's "protected";  Darwin requires a "weak"
900b57cec5SDimitry Andric   /// attribute on declarations that can be dynamically replaced.
hasProtectedVisibility()910b57cec5SDimitry Andric   bool hasProtectedVisibility() const override { return false; }
920b57cec5SDimitry Andric 
getExnObjectAlignment()930b57cec5SDimitry Andric   unsigned getExnObjectAlignment() const override {
940b57cec5SDimitry Andric     // Older versions of libc++abi guarantee an alignment of only 8-bytes for
950b57cec5SDimitry Andric     // exception objects because of a bug in __cxa_exception that was
960b57cec5SDimitry Andric     // eventually fixed in r319123.
970b57cec5SDimitry Andric     llvm::VersionTuple MinVersion;
980b57cec5SDimitry Andric     const llvm::Triple &T = this->getTriple();
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric     // Compute the earliest OS versions that have the fix to libc++abi.
1010b57cec5SDimitry Andric     switch (T.getOS()) {
1020b57cec5SDimitry Andric     case llvm::Triple::Darwin:
1030b57cec5SDimitry Andric     case llvm::Triple::MacOSX: // Earliest supporting version is 10.14.
1040b57cec5SDimitry Andric       MinVersion = llvm::VersionTuple(10U, 14U);
1050b57cec5SDimitry Andric       break;
1060b57cec5SDimitry Andric     case llvm::Triple::IOS:
1070b57cec5SDimitry Andric     case llvm::Triple::TvOS: // Earliest supporting version is 12.0.0.
1080b57cec5SDimitry Andric       MinVersion = llvm::VersionTuple(12U);
1090b57cec5SDimitry Andric       break;
1100b57cec5SDimitry Andric     case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0.
1110b57cec5SDimitry Andric       MinVersion = llvm::VersionTuple(5U);
1120b57cec5SDimitry Andric       break;
1137a6dacacSDimitry Andric     case llvm::Triple::XROS:
1147a6dacacSDimitry Andric       MinVersion = llvm::VersionTuple(0);
1157a6dacacSDimitry Andric       break;
1160b57cec5SDimitry Andric     default:
117e8d8bef9SDimitry Andric       // Conservatively return 8 bytes if OS is unknown.
118e8d8bef9SDimitry Andric       return 64;
1190b57cec5SDimitry Andric     }
1200b57cec5SDimitry Andric 
1210eae32dcSDimitry Andric     if (T.getOSVersion() < MinVersion)
1220b57cec5SDimitry Andric       return 64;
1230b57cec5SDimitry Andric     return OSTargetInfo<Target>::getExnObjectAlignment();
1240b57cec5SDimitry Andric   }
1250b57cec5SDimitry Andric 
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned)1260b57cec5SDimitry Andric   TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth,
1270b57cec5SDimitry Andric                                              bool IsSigned) const final {
1280b57cec5SDimitry Andric     // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`.
1290b57cec5SDimitry Andric     return BitWidth == 64
1300b57cec5SDimitry Andric                ? (IsSigned ? TargetInfo::SignedLongLong
1310b57cec5SDimitry Andric                            : TargetInfo::UnsignedLongLong)
1320b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1330b57cec5SDimitry Andric   }
134bdd1243dSDimitry Andric 
areDefaultedSMFStillPOD(const LangOptions &)135bdd1243dSDimitry Andric   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
136bdd1243dSDimitry Andric     return false;
137bdd1243dSDimitry Andric   }
1380b57cec5SDimitry Andric };
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric // DragonFlyBSD Target
1410b57cec5SDimitry Andric template <typename Target>
1420b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
1430b57cec5SDimitry Andric     : public OSTargetInfo<Target> {
1440b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)1450b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
1460b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
1470b57cec5SDimitry Andric     // DragonFly defines; list based off of gcc output
1480b57cec5SDimitry Andric     Builder.defineMacro("__DragonFly__");
1490b57cec5SDimitry Andric     Builder.defineMacro("__DragonFly_cc_version", "100001");
1500b57cec5SDimitry Andric     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
1510b57cec5SDimitry Andric     Builder.defineMacro("__tune_i386__");
1520b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
153349cc55cSDimitry Andric     if (this->HasFloat128)
154349cc55cSDimitry Andric       Builder.defineMacro("__FLOAT128__");
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric public:
DragonFlyBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1580b57cec5SDimitry Andric   DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1590b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
1600b57cec5SDimitry Andric     switch (Triple.getArch()) {
1610b57cec5SDimitry Andric     default:
1620b57cec5SDimitry Andric     case llvm::Triple::x86:
1630b57cec5SDimitry Andric     case llvm::Triple::x86_64:
164349cc55cSDimitry Andric       this->HasFloat128 = true;
1650b57cec5SDimitry Andric       this->MCountName = ".mcount";
1660b57cec5SDimitry Andric       break;
1670b57cec5SDimitry Andric     }
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric };
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric #ifndef FREEBSD_CC_VERSION
1720b57cec5SDimitry Andric #define FREEBSD_CC_VERSION 0U
1730b57cec5SDimitry Andric #endif
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric // FreeBSD Target
1760b57cec5SDimitry Andric template <typename Target>
1770b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
1780b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)1790b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
1800b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
1810b57cec5SDimitry Andric     // FreeBSD defines; list based off of gcc output
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric     unsigned Release = Triple.getOSMajorVersion();
1840b57cec5SDimitry Andric     if (Release == 0U)
1850b57cec5SDimitry Andric       Release = 8U;
1860b57cec5SDimitry Andric     unsigned CCVersion = FREEBSD_CC_VERSION;
1870b57cec5SDimitry Andric     if (CCVersion == 0U)
1880b57cec5SDimitry Andric       CCVersion = Release * 100000U + 1U;
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric     Builder.defineMacro("__FreeBSD__", Twine(Release));
1910b57cec5SDimitry Andric     Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
1920b57cec5SDimitry Andric     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
1930b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
1945c16e71dSDimitry Andric     if (this->HasFloat128)
1955c16e71dSDimitry Andric       Builder.defineMacro("__FLOAT128__");
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric     // On FreeBSD, wchar_t contains the number of the code point as
1980b57cec5SDimitry Andric     // used by the character set of the locale. These character sets are
1990b57cec5SDimitry Andric     // not necessarily a superset of ASCII.
2000b57cec5SDimitry Andric     //
2010b57cec5SDimitry Andric     // FIXME: This is wrong; the macro refers to the numerical values
2020b57cec5SDimitry Andric     // of wchar_t *literals*, which are not locale-dependent. However,
2030b57cec5SDimitry Andric     // FreeBSD systems apparently depend on us getting this wrong, and
2040b57cec5SDimitry Andric     // setting this to 1 is conforming even if all the basic source
2050b57cec5SDimitry Andric     // character literals have the same encoding as char and wchar_t.
2060b57cec5SDimitry Andric     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric public:
FreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)2100b57cec5SDimitry Andric   FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
2110b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
2120b57cec5SDimitry Andric     switch (Triple.getArch()) {
2130b57cec5SDimitry Andric     case llvm::Triple::x86:
2140b57cec5SDimitry Andric     case llvm::Triple::x86_64:
2155c16e71dSDimitry Andric       this->HasFloat128 = true;
2165c16e71dSDimitry Andric       [[fallthrough]];
2175c16e71dSDimitry Andric     default:
2180b57cec5SDimitry Andric       this->MCountName = ".mcount";
2190b57cec5SDimitry Andric       break;
2200b57cec5SDimitry Andric     case llvm::Triple::mips:
2210b57cec5SDimitry Andric     case llvm::Triple::mipsel:
2220b57cec5SDimitry Andric     case llvm::Triple::ppc:
223e8d8bef9SDimitry Andric     case llvm::Triple::ppcle:
2240b57cec5SDimitry Andric     case llvm::Triple::ppc64:
2250b57cec5SDimitry Andric     case llvm::Triple::ppc64le:
2260b57cec5SDimitry Andric       this->MCountName = "_mcount";
2270b57cec5SDimitry Andric       break;
2280b57cec5SDimitry Andric     case llvm::Triple::arm:
2290b57cec5SDimitry Andric       this->MCountName = "__mcount";
2300b57cec5SDimitry Andric       break;
231fe6060f1SDimitry Andric     case llvm::Triple::riscv32:
232fe6060f1SDimitry Andric     case llvm::Triple::riscv64:
233fe6060f1SDimitry Andric       break;
2340b57cec5SDimitry Andric     }
2350b57cec5SDimitry Andric   }
2360b57cec5SDimitry Andric };
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric // GNU/kFreeBSD Target
2390b57cec5SDimitry Andric template <typename Target>
2400b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> {
2410b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)2420b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
2430b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
2440b57cec5SDimitry Andric     // GNU/kFreeBSD defines; list based off of gcc output
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
2470b57cec5SDimitry Andric     Builder.defineMacro("__FreeBSD_kernel__");
2480b57cec5SDimitry Andric     Builder.defineMacro("__GLIBC__");
2490b57cec5SDimitry Andric     if (Opts.POSIXThreads)
2500b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
2510b57cec5SDimitry Andric     if (Opts.CPlusPlus)
2520b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
2530b57cec5SDimitry Andric   }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric public:
256bdd1243dSDimitry Andric   using OSTargetInfo<Target>::OSTargetInfo;
2570b57cec5SDimitry Andric };
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric // Haiku Target
2600b57cec5SDimitry Andric template <typename Target>
2610b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
2620b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)2630b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
2640b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
2650b57cec5SDimitry Andric     // Haiku defines; list based off of gcc output
2660b57cec5SDimitry Andric     Builder.defineMacro("__HAIKU__");
2670b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
2680b57cec5SDimitry Andric     if (this->HasFloat128)
2690b57cec5SDimitry Andric       Builder.defineMacro("__FLOAT128__");
2700b57cec5SDimitry Andric   }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric public:
HaikuTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)2730b57cec5SDimitry Andric   HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
2740b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
2750b57cec5SDimitry Andric     this->SizeType = TargetInfo::UnsignedLong;
2760b57cec5SDimitry Andric     this->IntPtrType = TargetInfo::SignedLong;
2770b57cec5SDimitry Andric     this->PtrDiffType = TargetInfo::SignedLong;
2780b57cec5SDimitry Andric     this->ProcessIDType = TargetInfo::SignedLong;
2790b57cec5SDimitry Andric     switch (Triple.getArch()) {
2800b57cec5SDimitry Andric     default:
2810b57cec5SDimitry Andric       break;
2820b57cec5SDimitry Andric     case llvm::Triple::x86:
2830b57cec5SDimitry Andric     case llvm::Triple::x86_64:
2840b57cec5SDimitry Andric       this->HasFloat128 = true;
2850b57cec5SDimitry Andric       break;
2860b57cec5SDimitry Andric     }
2870b57cec5SDimitry Andric   }
2880b57cec5SDimitry Andric };
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric // Hurd target
2910b57cec5SDimitry Andric template <typename Target>
2920b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
2930b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)2940b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
2950b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
2960b57cec5SDimitry Andric     // Hurd defines; list based off of gcc output.
2970b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
2980b57cec5SDimitry Andric     Builder.defineMacro("__GNU__");
2990b57cec5SDimitry Andric     Builder.defineMacro("__gnu_hurd__");
3000b57cec5SDimitry Andric     Builder.defineMacro("__MACH__");
3010b57cec5SDimitry Andric     Builder.defineMacro("__GLIBC__");
3020b57cec5SDimitry Andric     if (Opts.POSIXThreads)
3030b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
3040b57cec5SDimitry Andric     if (Opts.CPlusPlus)
3050b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric public:
308bdd1243dSDimitry Andric   using OSTargetInfo<Target>::OSTargetInfo;
3090b57cec5SDimitry Andric };
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric // Linux target
3120b57cec5SDimitry Andric template <typename Target>
3130b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
3140b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)3150b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3160b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
3170b57cec5SDimitry Andric     // Linux defines; list based off of gcc output
3180b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
3190b57cec5SDimitry Andric     DefineStd(Builder, "linux", Opts);
3200b57cec5SDimitry Andric     if (Triple.isAndroid()) {
3210b57cec5SDimitry Andric       Builder.defineMacro("__ANDROID__", "1");
3220b57cec5SDimitry Andric       this->PlatformName = "android";
3230eae32dcSDimitry Andric       this->PlatformMinVersion = Triple.getEnvironmentVersion();
3240eae32dcSDimitry Andric       const unsigned Maj = this->PlatformMinVersion.getMajor();
325e8d8bef9SDimitry Andric       if (Maj) {
326e8d8bef9SDimitry Andric         Builder.defineMacro("__ANDROID_MIN_SDK_VERSION__", Twine(Maj));
327e8d8bef9SDimitry Andric         // This historical but ambiguous name for the minSdkVersion macro. Keep
328e8d8bef9SDimitry Andric         // defined for compatibility.
329e8d8bef9SDimitry Andric         Builder.defineMacro("__ANDROID_API__", "__ANDROID_MIN_SDK_VERSION__");
330e8d8bef9SDimitry Andric       }
3310b57cec5SDimitry Andric     } else {
3320b57cec5SDimitry Andric         Builder.defineMacro("__gnu_linux__");
3330b57cec5SDimitry Andric     }
3340b57cec5SDimitry Andric     if (Opts.POSIXThreads)
3350b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
3360b57cec5SDimitry Andric     if (Opts.CPlusPlus)
3370b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
3380b57cec5SDimitry Andric     if (this->HasFloat128)
3390b57cec5SDimitry Andric       Builder.defineMacro("__FLOAT128__");
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric public:
LinuxTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)3430b57cec5SDimitry Andric   LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
3440b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
3450b57cec5SDimitry Andric     this->WIntType = TargetInfo::UnsignedInt;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric     switch (Triple.getArch()) {
3480b57cec5SDimitry Andric     default:
3490b57cec5SDimitry Andric       break;
3500b57cec5SDimitry Andric     case llvm::Triple::mips:
3510b57cec5SDimitry Andric     case llvm::Triple::mipsel:
3520b57cec5SDimitry Andric     case llvm::Triple::mips64:
3530b57cec5SDimitry Andric     case llvm::Triple::mips64el:
3540b57cec5SDimitry Andric     case llvm::Triple::ppc:
355e8d8bef9SDimitry Andric     case llvm::Triple::ppcle:
3560b57cec5SDimitry Andric     case llvm::Triple::ppc64:
3570b57cec5SDimitry Andric     case llvm::Triple::ppc64le:
3580b57cec5SDimitry Andric       this->MCountName = "_mcount";
3590b57cec5SDimitry Andric       break;
3600b57cec5SDimitry Andric     case llvm::Triple::x86:
3610b57cec5SDimitry Andric     case llvm::Triple::x86_64:
3620b57cec5SDimitry Andric       this->HasFloat128 = true;
3630b57cec5SDimitry Andric       break;
3640b57cec5SDimitry Andric     }
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
getStaticInitSectionSpecifier()3670b57cec5SDimitry Andric   const char *getStaticInitSectionSpecifier() const override {
3680b57cec5SDimitry Andric     return ".text.startup";
3690b57cec5SDimitry Andric   }
3700b57cec5SDimitry Andric };
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric // NetBSD Target
3730b57cec5SDimitry Andric template <typename Target>
3740b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
3750b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)3760b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3770b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
3780b57cec5SDimitry Andric     // NetBSD defines; list based off of gcc output
3790b57cec5SDimitry Andric     Builder.defineMacro("__NetBSD__");
3800b57cec5SDimitry Andric     Builder.defineMacro("__unix__");
3810b57cec5SDimitry Andric     if (Opts.POSIXThreads)
3820b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
3835c16e71dSDimitry Andric     if (this->HasFloat128)
3845c16e71dSDimitry Andric       Builder.defineMacro("__FLOAT128__");
3850b57cec5SDimitry Andric   }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric public:
NetBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)3880b57cec5SDimitry Andric   NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
3890b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
3900b57cec5SDimitry Andric     this->MCountName = "__mcount";
3915c16e71dSDimitry Andric     switch (Triple.getArch()) {
3925c16e71dSDimitry Andric     default:
3935c16e71dSDimitry Andric       break;
3945c16e71dSDimitry Andric     case llvm::Triple::x86:
3955c16e71dSDimitry Andric     case llvm::Triple::x86_64:
3965c16e71dSDimitry Andric       this->HasFloat128 = true;
3975c16e71dSDimitry Andric       break;
3985c16e71dSDimitry Andric     }
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric };
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric // OpenBSD Target
4030b57cec5SDimitry Andric template <typename Target>
4040b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
4050b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)4060b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4070b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
4080b57cec5SDimitry Andric     // OpenBSD defines; list based off of gcc output
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric     Builder.defineMacro("__OpenBSD__");
4110b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
4120b57cec5SDimitry Andric     if (Opts.POSIXThreads)
4130b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
4140b57cec5SDimitry Andric     if (this->HasFloat128)
4150b57cec5SDimitry Andric       Builder.defineMacro("__FLOAT128__");
41669ade1e0SDimitry Andric 
417349cc55cSDimitry Andric     if (Opts.C11)
41869ade1e0SDimitry Andric       Builder.defineMacro("__STDC_NO_THREADS__");
41969ade1e0SDimitry Andric   }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric public:
OpenBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4220b57cec5SDimitry Andric   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4230b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
42475b4d546SDimitry Andric     this->WCharType = this->WIntType = this->SignedInt;
42575b4d546SDimitry Andric     this->IntMaxType = TargetInfo::SignedLongLong;
42675b4d546SDimitry Andric     this->Int64Type = TargetInfo::SignedLongLong;
4270b57cec5SDimitry Andric     switch (Triple.getArch()) {
4280b57cec5SDimitry Andric     case llvm::Triple::x86:
4290b57cec5SDimitry Andric     case llvm::Triple::x86_64:
4300b57cec5SDimitry Andric       this->HasFloat128 = true;
431bdd1243dSDimitry Andric       [[fallthrough]];
4320b57cec5SDimitry Andric     default:
4330b57cec5SDimitry Andric       this->MCountName = "__mcount";
4340b57cec5SDimitry Andric       break;
4350b57cec5SDimitry Andric     case llvm::Triple::mips64:
4360b57cec5SDimitry Andric     case llvm::Triple::mips64el:
4370b57cec5SDimitry Andric     case llvm::Triple::ppc:
43875b4d546SDimitry Andric     case llvm::Triple::ppc64:
43975b4d546SDimitry Andric     case llvm::Triple::ppc64le:
4400b57cec5SDimitry Andric     case llvm::Triple::sparcv9:
4410b57cec5SDimitry Andric       this->MCountName = "_mcount";
4420b57cec5SDimitry Andric       break;
443fe6060f1SDimitry Andric     case llvm::Triple::riscv32:
444fe6060f1SDimitry Andric     case llvm::Triple::riscv64:
445fe6060f1SDimitry Andric       break;
4460b57cec5SDimitry Andric     }
4470b57cec5SDimitry Andric   }
4480b57cec5SDimitry Andric };
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric // PS3 PPU Target
4510b57cec5SDimitry Andric template <typename Target>
4520b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
4530b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)4540b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4550b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
4560b57cec5SDimitry Andric     // PS3 PPU defines.
4570b57cec5SDimitry Andric     Builder.defineMacro("__PPU__");
4580b57cec5SDimitry Andric     Builder.defineMacro("__CELLOS_LV2__");
4590b57cec5SDimitry Andric     Builder.defineMacro("__LP32__");
4600b57cec5SDimitry Andric     Builder.defineMacro("_ARCH_PPC64");
4610b57cec5SDimitry Andric     Builder.defineMacro("__powerpc64__");
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric public:
PS3PPUTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4650b57cec5SDimitry Andric   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4660b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
4670b57cec5SDimitry Andric     this->LongWidth = this->LongAlign = 32;
4680b57cec5SDimitry Andric     this->PointerWidth = this->PointerAlign = 32;
4690b57cec5SDimitry Andric     this->IntMaxType = TargetInfo::SignedLongLong;
4700b57cec5SDimitry Andric     this->Int64Type = TargetInfo::SignedLongLong;
4710b57cec5SDimitry Andric     this->SizeType = TargetInfo::UnsignedInt;
47206c3fb27SDimitry Andric     this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64");
4730b57cec5SDimitry Andric   }
4740b57cec5SDimitry Andric };
4750b57cec5SDimitry Andric 
47681ad6265SDimitry Andric // Common base class for PS4/PS5 targets.
4770b57cec5SDimitry Andric template <typename Target>
47881ad6265SDimitry Andric class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> {
4790b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)4800b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4810b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
4820b57cec5SDimitry Andric     Builder.defineMacro("__FreeBSD__", "9");
4830b57cec5SDimitry Andric     Builder.defineMacro("__FreeBSD_cc_version", "900001");
4840b57cec5SDimitry Andric     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
4850b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
486480093f4SDimitry Andric     Builder.defineMacro("__SCE__");
48706c3fb27SDimitry Andric     Builder.defineMacro("__STDC_NO_COMPLEX__");
48806c3fb27SDimitry Andric     Builder.defineMacro("__STDC_NO_THREADS__");
48981ad6265SDimitry Andric   }
49081ad6265SDimitry Andric 
49181ad6265SDimitry Andric public:
PSOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)49281ad6265SDimitry Andric   PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
49381ad6265SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
49481ad6265SDimitry Andric     this->WCharType = TargetInfo::UnsignedShort;
49581ad6265SDimitry Andric 
49681ad6265SDimitry Andric     // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256
49781ad6265SDimitry Andric     // bits).
49881ad6265SDimitry Andric     this->MaxTLSAlign = 256;
49981ad6265SDimitry Andric 
50081ad6265SDimitry Andric     // On PS4/PS5, do not honor explicit bit field alignment,
50181ad6265SDimitry Andric     // as in "__attribute__((aligned(2))) int b : 1;".
50281ad6265SDimitry Andric     this->UseExplicitBitFieldAlignment = false;
50381ad6265SDimitry Andric 
50481ad6265SDimitry Andric     this->MCountName = ".mcount";
50581ad6265SDimitry Andric     this->NewAlign = 256;
50681ad6265SDimitry Andric     this->SuitableAlign = 256;
50781ad6265SDimitry Andric   }
50881ad6265SDimitry Andric 
50981ad6265SDimitry Andric   TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC)51081ad6265SDimitry Andric   checkCallingConvention(CallingConv CC) const override {
51181ad6265SDimitry Andric     return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
51281ad6265SDimitry Andric   }
513bdd1243dSDimitry Andric 
areDefaultedSMFStillPOD(const LangOptions &)514bdd1243dSDimitry Andric   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
515bdd1243dSDimitry Andric     return false;
516bdd1243dSDimitry Andric   }
51781ad6265SDimitry Andric };
51881ad6265SDimitry Andric 
51981ad6265SDimitry Andric // PS4 Target
52081ad6265SDimitry Andric template <typename Target>
52181ad6265SDimitry Andric class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> {
52281ad6265SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)52381ad6265SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
52481ad6265SDimitry Andric                     MacroBuilder &Builder) const override {
52581ad6265SDimitry Andric     // Start with base class defines.
52681ad6265SDimitry Andric     PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
52781ad6265SDimitry Andric 
5280b57cec5SDimitry Andric     Builder.defineMacro("__ORBIS__");
5290b57cec5SDimitry Andric   }
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric public:
532bdd1243dSDimitry Andric   using PSOSTargetInfo<Target>::PSOSTargetInfo;
53381ad6265SDimitry Andric };
5340b57cec5SDimitry Andric 
53581ad6265SDimitry Andric // PS5 Target
53681ad6265SDimitry Andric template <typename Target>
53781ad6265SDimitry Andric class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> {
53881ad6265SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)53981ad6265SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
54081ad6265SDimitry Andric                     MacroBuilder &Builder) const override {
54181ad6265SDimitry Andric     // Start with base class defines.
54281ad6265SDimitry Andric     PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
5430b57cec5SDimitry Andric 
54481ad6265SDimitry Andric     Builder.defineMacro("__PROSPERO__");
54581ad6265SDimitry Andric   }
5460b57cec5SDimitry Andric 
54781ad6265SDimitry Andric public:
548bdd1243dSDimitry Andric   using PSOSTargetInfo<Target>::PSOSTargetInfo;
5490b57cec5SDimitry Andric };
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric // RTEMS Target
5520b57cec5SDimitry Andric template <typename Target>
5530b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
5540b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)5550b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
5560b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
5570b57cec5SDimitry Andric     // RTEMS defines; list based off of gcc output
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric     Builder.defineMacro("__rtems__");
5600b57cec5SDimitry Andric     if (Opts.CPlusPlus)
5610b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
5620b57cec5SDimitry Andric   }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric public:
RTEMSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5650b57cec5SDimitry Andric   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5660b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
5670b57cec5SDimitry Andric     switch (Triple.getArch()) {
5680b57cec5SDimitry Andric     default:
5690b57cec5SDimitry Andric     case llvm::Triple::x86:
5700b57cec5SDimitry Andric       // this->MCountName = ".mcount";
5710b57cec5SDimitry Andric       break;
5720b57cec5SDimitry Andric     case llvm::Triple::mips:
5730b57cec5SDimitry Andric     case llvm::Triple::mipsel:
5740b57cec5SDimitry Andric     case llvm::Triple::ppc:
5750b57cec5SDimitry Andric     case llvm::Triple::ppc64:
5760b57cec5SDimitry Andric     case llvm::Triple::ppc64le:
5770b57cec5SDimitry Andric       // this->MCountName = "_mcount";
5780b57cec5SDimitry Andric       break;
5790b57cec5SDimitry Andric     case llvm::Triple::arm:
5800b57cec5SDimitry Andric       // this->MCountName = "__mcount";
5810b57cec5SDimitry Andric       break;
5820b57cec5SDimitry Andric     }
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric };
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric // Solaris target
5870b57cec5SDimitry Andric template <typename Target>
5880b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
5890b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)5900b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
5910b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
5920b57cec5SDimitry Andric     DefineStd(Builder, "sun", Opts);
5930b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
5940b57cec5SDimitry Andric     Builder.defineMacro("__svr4__");
5950b57cec5SDimitry Andric     Builder.defineMacro("__SVR4");
5960b57cec5SDimitry Andric     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
5970b57cec5SDimitry Andric     // newer, but to 500 for everything else.  feature_test.h has a check to
5980b57cec5SDimitry Andric     // ensure that you are not using C99 with an old version of X/Open or C89
5990b57cec5SDimitry Andric     // with a new version.
6000b57cec5SDimitry Andric     if (Opts.C99)
6010b57cec5SDimitry Andric       Builder.defineMacro("_XOPEN_SOURCE", "600");
6020b57cec5SDimitry Andric     else
6030b57cec5SDimitry Andric       Builder.defineMacro("_XOPEN_SOURCE", "500");
6040b57cec5SDimitry Andric     if (Opts.CPlusPlus) {
6050b57cec5SDimitry Andric       Builder.defineMacro("__C99FEATURES__");
6060b57cec5SDimitry Andric       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
6070b57cec5SDimitry Andric     }
6080b57cec5SDimitry Andric     // GCC restricts the next two to C++.
6090b57cec5SDimitry Andric     Builder.defineMacro("_LARGEFILE_SOURCE");
6100b57cec5SDimitry Andric     Builder.defineMacro("_LARGEFILE64_SOURCE");
6110b57cec5SDimitry Andric     Builder.defineMacro("__EXTENSIONS__");
6120b57cec5SDimitry Andric     if (Opts.POSIXThreads)
6130b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
6140b57cec5SDimitry Andric     if (this->HasFloat128)
6150b57cec5SDimitry Andric       Builder.defineMacro("__FLOAT128__");
6160b57cec5SDimitry Andric   }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric public:
SolarisTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6190b57cec5SDimitry Andric   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6200b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
6210b57cec5SDimitry Andric     if (this->PointerWidth == 64) {
6220b57cec5SDimitry Andric       this->WCharType = this->WIntType = this->SignedInt;
6230b57cec5SDimitry Andric     } else {
6240b57cec5SDimitry Andric       this->WCharType = this->WIntType = this->SignedLong;
6250b57cec5SDimitry Andric     }
6260b57cec5SDimitry Andric     switch (Triple.getArch()) {
6270b57cec5SDimitry Andric     default:
6280b57cec5SDimitry Andric       break;
6290b57cec5SDimitry Andric     case llvm::Triple::x86:
6300b57cec5SDimitry Andric     case llvm::Triple::x86_64:
6310b57cec5SDimitry Andric       this->HasFloat128 = true;
6320b57cec5SDimitry Andric       break;
6330b57cec5SDimitry Andric     }
6340b57cec5SDimitry Andric   }
6350b57cec5SDimitry Andric };
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric // AIX Target
6380b57cec5SDimitry Andric template <typename Target>
6390b57cec5SDimitry Andric class AIXTargetInfo : public OSTargetInfo<Target> {
6400b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)6410b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
6420b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
6430b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
6440b57cec5SDimitry Andric     Builder.defineMacro("_IBMR2");
6450b57cec5SDimitry Andric     Builder.defineMacro("_POWER");
646349cc55cSDimitry Andric     Builder.defineMacro("__THW_BIG_ENDIAN__");
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric     Builder.defineMacro("_AIX");
649fe6060f1SDimitry Andric     Builder.defineMacro("__TOS_AIX__");
650349cc55cSDimitry Andric     Builder.defineMacro("__HOS_AIX__");
651fe6060f1SDimitry Andric 
652fe6060f1SDimitry Andric     if (Opts.C11) {
653fe6060f1SDimitry Andric       Builder.defineMacro("__STDC_NO_ATOMICS__");
654fe6060f1SDimitry Andric       Builder.defineMacro("__STDC_NO_THREADS__");
655fe6060f1SDimitry Andric     }
6560b57cec5SDimitry Andric 
657e8d8bef9SDimitry Andric     if (Opts.EnableAIXExtendedAltivecABI)
658e8d8bef9SDimitry Andric       Builder.defineMacro("__EXTABI__");
659e8d8bef9SDimitry Andric 
6600eae32dcSDimitry Andric     VersionTuple OsVersion = Triple.getOSVersion();
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric     // Define AIX OS-Version Macros.
6630b57cec5SDimitry Andric     // Includes logic for legacy versions of AIX; no specific intent to support.
6640eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(3, 2))
6650eae32dcSDimitry Andric       Builder.defineMacro("_AIX32");
6660eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(4, 1))
6670eae32dcSDimitry Andric       Builder.defineMacro("_AIX41");
6680eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(4, 3))
6690eae32dcSDimitry Andric       Builder.defineMacro("_AIX43");
6700eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(5, 0))
6710eae32dcSDimitry Andric       Builder.defineMacro("_AIX50");
6720eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(5, 1))
6730eae32dcSDimitry Andric       Builder.defineMacro("_AIX51");
6740eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(5, 2))
6750eae32dcSDimitry Andric       Builder.defineMacro("_AIX52");
6760eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(5, 3))
6770eae32dcSDimitry Andric       Builder.defineMacro("_AIX53");
6780eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(6, 1))
6790eae32dcSDimitry Andric       Builder.defineMacro("_AIX61");
6800eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(7, 1))
6810eae32dcSDimitry Andric       Builder.defineMacro("_AIX71");
6820eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(7, 2))
6830eae32dcSDimitry Andric       Builder.defineMacro("_AIX72");
6840eae32dcSDimitry Andric     if (OsVersion >= VersionTuple(7, 3))
6850eae32dcSDimitry Andric       Builder.defineMacro("_AIX73");
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
6880b57cec5SDimitry Andric     Builder.defineMacro("_LONG_LONG");
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric     if (Opts.POSIXThreads) {
6910b57cec5SDimitry Andric       Builder.defineMacro("_THREAD_SAFE");
6920b57cec5SDimitry Andric     }
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric     if (this->PointerWidth == 64) {
6950b57cec5SDimitry Andric       Builder.defineMacro("__64BIT__");
6960b57cec5SDimitry Andric     }
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric     // Define _WCHAR_T when it is a fundamental type
6990b57cec5SDimitry Andric     // (i.e., for C++ without -fno-wchar).
7000b57cec5SDimitry Andric     if (Opts.CPlusPlus && Opts.WChar) {
7010b57cec5SDimitry Andric       Builder.defineMacro("_WCHAR_T");
7020b57cec5SDimitry Andric     }
7030b57cec5SDimitry Andric   }
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric public:
AIXTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7060b57cec5SDimitry Andric   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7070b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
708bdd1243dSDimitry Andric     this->MCountName = "__mcount";
7095ffd83dbSDimitry Andric     this->TheCXXABI.set(TargetCXXABI::XL);
7105ffd83dbSDimitry Andric 
7110b57cec5SDimitry Andric     if (this->PointerWidth == 64) {
7120b57cec5SDimitry Andric       this->WCharType = this->UnsignedInt;
7130b57cec5SDimitry Andric     } else {
7140b57cec5SDimitry Andric       this->WCharType = this->UnsignedShort;
7150b57cec5SDimitry Andric     }
7160b57cec5SDimitry Andric     this->UseZeroLengthBitfieldAlignment = true;
7170b57cec5SDimitry Andric   }
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   // AIX sets FLT_EVAL_METHOD to be 1.
getFPEvalMethod()72081ad6265SDimitry Andric   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
72181ad6265SDimitry Andric     return LangOptions::FPEvalMethodKind::FEM_Double;
72281ad6265SDimitry Andric   }
723e8d8bef9SDimitry Andric 
defaultsToAIXPowerAlignment()724e8d8bef9SDimitry Andric   bool defaultsToAIXPowerAlignment() const override { return true; }
725bdd1243dSDimitry Andric 
areDefaultedSMFStillPOD(const LangOptions &)726bdd1243dSDimitry Andric   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
727bdd1243dSDimitry Andric     return false;
728bdd1243dSDimitry Andric   }
729e8d8bef9SDimitry Andric };
730e8d8bef9SDimitry Andric 
731e8d8bef9SDimitry Andric // z/OS target
732e8d8bef9SDimitry Andric template <typename Target>
733e8d8bef9SDimitry Andric class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> {
734e8d8bef9SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)735e8d8bef9SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
736e8d8bef9SDimitry Andric                     MacroBuilder &Builder) const override {
737e8d8bef9SDimitry Andric     // FIXME: _LONG_LONG should not be defined under -std=c89.
738e8d8bef9SDimitry Andric     Builder.defineMacro("_LONG_LONG");
739e8d8bef9SDimitry Andric     Builder.defineMacro("__370__");
740e8d8bef9SDimitry Andric     Builder.defineMacro("__BFP__");
741e8d8bef9SDimitry Andric     // FIXME: __BOOL__ should not be defined under -std=c89.
742e8d8bef9SDimitry Andric     Builder.defineMacro("__BOOL__");
74306c3fb27SDimitry Andric     Builder.defineMacro("__COMPILER_VER__", "0x50000000");
744e8d8bef9SDimitry Andric     Builder.defineMacro("__LONGNAME__");
745e8d8bef9SDimitry Andric     Builder.defineMacro("__MVS__");
746e8d8bef9SDimitry Andric     Builder.defineMacro("__THW_370__");
747e8d8bef9SDimitry Andric     Builder.defineMacro("__THW_BIG_ENDIAN__");
748e8d8bef9SDimitry Andric     Builder.defineMacro("__TOS_390__");
749e8d8bef9SDimitry Andric     Builder.defineMacro("__TOS_MVS__");
750e8d8bef9SDimitry Andric     Builder.defineMacro("__XPLINK__");
751e8d8bef9SDimitry Andric 
752e8d8bef9SDimitry Andric     if (this->PointerWidth == 64)
753e8d8bef9SDimitry Andric       Builder.defineMacro("__64BIT__");
754e8d8bef9SDimitry Andric 
755e8d8bef9SDimitry Andric     if (Opts.CPlusPlus && Opts.WChar) {
756e8d8bef9SDimitry Andric       // Macro __wchar_t is defined so that the wchar_t data
757e8d8bef9SDimitry Andric       // type is not declared as a typedef in system headers.
758e8d8bef9SDimitry Andric       Builder.defineMacro("__wchar_t");
759e8d8bef9SDimitry Andric     }
760e8d8bef9SDimitry Andric 
761e8d8bef9SDimitry Andric     this->PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
762e8d8bef9SDimitry Andric   }
763e8d8bef9SDimitry Andric 
764e8d8bef9SDimitry Andric public:
ZOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)765e8d8bef9SDimitry Andric   ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
766e8d8bef9SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
767e8d8bef9SDimitry Andric     this->WCharType = TargetInfo::UnsignedInt;
768fe6060f1SDimitry Andric     this->MaxAlignedAttribute = 128;
769e8d8bef9SDimitry Andric     this->UseBitFieldTypeAlignment = false;
770e8d8bef9SDimitry Andric     this->UseZeroLengthBitfieldAlignment = true;
771fe6060f1SDimitry Andric     this->UseLeadingZeroLengthBitfield = false;
772e8d8bef9SDimitry Andric     this->ZeroLengthBitfieldBoundary = 32;
77306c3fb27SDimitry Andric     this->TheCXXABI.set(TargetCXXABI::XL);
774e8d8bef9SDimitry Andric   }
775bdd1243dSDimitry Andric 
areDefaultedSMFStillPOD(const LangOptions &)776bdd1243dSDimitry Andric   bool areDefaultedSMFStillPOD(const LangOptions &) const override {
777bdd1243dSDimitry Andric     return false;
778bdd1243dSDimitry Andric   }
7790b57cec5SDimitry Andric };
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
7820b57cec5SDimitry Andric                        MacroBuilder &Builder);
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric // Windows target
7850b57cec5SDimitry Andric template <typename Target>
7860b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
7870b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)7880b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
7890b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
7900b57cec5SDimitry Andric     addWindowsDefines(Triple, Opts, Builder);
7910b57cec5SDimitry Andric   }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric public:
WindowsTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7940b57cec5SDimitry Andric   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7950b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
7960b57cec5SDimitry Andric     this->WCharType = TargetInfo::UnsignedShort;
7970b57cec5SDimitry Andric     this->WIntType = TargetInfo::UnsignedShort;
7980b57cec5SDimitry Andric   }
7990b57cec5SDimitry Andric };
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric template <typename Target>
8020b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
8030b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)8040b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
8050b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
8060b57cec5SDimitry Andric     if (Opts.POSIXThreads)
8070b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
8080b57cec5SDimitry Andric     if (Opts.CPlusPlus)
8090b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric     DefineStd(Builder, "unix", Opts);
8120b57cec5SDimitry Andric     Builder.defineMacro("__native_client__");
8130b57cec5SDimitry Andric   }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric public:
NaClTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8160b57cec5SDimitry Andric   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8170b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
8180b57cec5SDimitry Andric     this->LongAlign = 32;
8190b57cec5SDimitry Andric     this->LongWidth = 32;
8200b57cec5SDimitry Andric     this->PointerAlign = 32;
8210b57cec5SDimitry Andric     this->PointerWidth = 32;
8220b57cec5SDimitry Andric     this->IntMaxType = TargetInfo::SignedLongLong;
8230b57cec5SDimitry Andric     this->Int64Type = TargetInfo::SignedLongLong;
8240b57cec5SDimitry Andric     this->DoubleAlign = 64;
8250b57cec5SDimitry Andric     this->LongDoubleWidth = 64;
8260b57cec5SDimitry Andric     this->LongDoubleAlign = 64;
8270b57cec5SDimitry Andric     this->LongLongWidth = 64;
8280b57cec5SDimitry Andric     this->LongLongAlign = 64;
8290b57cec5SDimitry Andric     this->SizeType = TargetInfo::UnsignedInt;
8300b57cec5SDimitry Andric     this->PtrDiffType = TargetInfo::SignedInt;
8310b57cec5SDimitry Andric     this->IntPtrType = TargetInfo::SignedInt;
8320b57cec5SDimitry Andric     // RegParmMax is inherited from the underlying architecture.
8330b57cec5SDimitry Andric     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
8340b57cec5SDimitry Andric     if (Triple.getArch() == llvm::Triple::arm) {
8350b57cec5SDimitry Andric       // Handled in ARM's setABI().
8360b57cec5SDimitry Andric     } else if (Triple.getArch() == llvm::Triple::x86) {
837a7dea167SDimitry Andric       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
8385f757f3fSDimitry Andric                             "i64:64-i128:128-n8:16:32-S128");
8390b57cec5SDimitry Andric     } else if (Triple.getArch() == llvm::Triple::x86_64) {
840a7dea167SDimitry Andric       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
8415f757f3fSDimitry Andric                             "i64:64-i128:128-n8:16:32:64-S128");
8420b57cec5SDimitry Andric     } else if (Triple.getArch() == llvm::Triple::mipsel) {
8430b57cec5SDimitry Andric       // Handled on mips' setDataLayout.
8440b57cec5SDimitry Andric     } else {
8450b57cec5SDimitry Andric       assert(Triple.getArch() == llvm::Triple::le32);
8460b57cec5SDimitry Andric       this->resetDataLayout("e-p:32:32-i64:64");
8470b57cec5SDimitry Andric     }
8480b57cec5SDimitry Andric   }
8490b57cec5SDimitry Andric };
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric // Fuchsia Target
8520b57cec5SDimitry Andric template <typename Target>
8530b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
8540b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)8550b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
8560b57cec5SDimitry Andric                     MacroBuilder &Builder) const override {
8570b57cec5SDimitry Andric     Builder.defineMacro("__Fuchsia__");
8580b57cec5SDimitry Andric     if (Opts.POSIXThreads)
8590b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
8600b57cec5SDimitry Andric     // Required by the libc++ locale support.
8610b57cec5SDimitry Andric     if (Opts.CPlusPlus)
8620b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
863349cc55cSDimitry Andric     Builder.defineMacro("__Fuchsia_API_level__", Twine(Opts.FuchsiaAPILevel));
864349cc55cSDimitry Andric     this->PlatformName = "fuchsia";
865349cc55cSDimitry Andric     this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel);
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric public:
FuchsiaTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8690b57cec5SDimitry Andric   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8700b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
8710b57cec5SDimitry Andric     this->MCountName = "__mcount";
872480093f4SDimitry Andric     this->TheCXXABI.set(TargetCXXABI::Fuchsia);
8730b57cec5SDimitry Andric   }
8740b57cec5SDimitry Andric };
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric // WebAssembly target
8770b57cec5SDimitry Andric template <typename Target>
8780b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
8790b57cec5SDimitry Andric     : public OSTargetInfo<Target> {
8800b57cec5SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)8810b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
8825ffd83dbSDimitry Andric                     MacroBuilder &Builder) const override {
8830b57cec5SDimitry Andric     // A common platform macro.
8840b57cec5SDimitry Andric     if (Opts.POSIXThreads)
8850b57cec5SDimitry Andric       Builder.defineMacro("_REENTRANT");
8860b57cec5SDimitry Andric     // Follow g++ convention and predefine _GNU_SOURCE for C++.
8870b57cec5SDimitry Andric     if (Opts.CPlusPlus)
8880b57cec5SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
8890b57cec5SDimitry Andric     // Indicate that we have __float128.
8900b57cec5SDimitry Andric     Builder.defineMacro("__FLOAT128__");
8910b57cec5SDimitry Andric   }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric public:
WebAssemblyOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8940b57cec5SDimitry Andric   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
8950b57cec5SDimitry Andric                                    const TargetOptions &Opts)
8960b57cec5SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
8970b57cec5SDimitry Andric     this->MCountName = "__mcount";
8980b57cec5SDimitry Andric     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
8990b57cec5SDimitry Andric     this->HasFloat128 = true;
9000b57cec5SDimitry Andric   }
9010b57cec5SDimitry Andric };
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric // WASI target
9040b57cec5SDimitry Andric template <typename Target>
9050b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WASITargetInfo
9060b57cec5SDimitry Andric     : public WebAssemblyOSTargetInfo<Target> {
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)9070b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
9080b57cec5SDimitry Andric                     MacroBuilder &Builder) const final {
9090b57cec5SDimitry Andric     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
9100b57cec5SDimitry Andric     Builder.defineMacro("__wasi__");
9110b57cec5SDimitry Andric   }
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric public:
914bdd1243dSDimitry Andric   using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
9150b57cec5SDimitry Andric };
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric // Emscripten target
9180b57cec5SDimitry Andric template <typename Target>
9190b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
9200b57cec5SDimitry Andric     : public WebAssemblyOSTargetInfo<Target> {
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)9210b57cec5SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
9220b57cec5SDimitry Andric                     MacroBuilder &Builder) const final {
9230b57cec5SDimitry Andric     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
924349cc55cSDimitry Andric     DefineStd(Builder, "unix", Opts);
9250b57cec5SDimitry Andric     Builder.defineMacro("__EMSCRIPTEN__");
926fe6060f1SDimitry Andric     if (Opts.POSIXThreads)
927fe6060f1SDimitry Andric       Builder.defineMacro("__EMSCRIPTEN_PTHREADS__");
9280b57cec5SDimitry Andric   }
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric public:
EmscriptenTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)931fe6060f1SDimitry Andric   explicit EmscriptenTargetInfo(const llvm::Triple &Triple,
932fe6060f1SDimitry Andric                                 const TargetOptions &Opts)
933fe6060f1SDimitry Andric       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {
934fe6060f1SDimitry Andric     // Keeping the alignment of long double to 8 bytes even though its size is
935fe6060f1SDimitry Andric     // 16 bytes allows emscripten to have an 8-byte-aligned max_align_t which
936fe6060f1SDimitry Andric     // in turn gives is a 8-byte aligned malloc.
937fe6060f1SDimitry Andric     // Emscripten's ABI is unstable and we may change this back to 128 to match
938fe6060f1SDimitry Andric     // the WebAssembly default in the future.
939fe6060f1SDimitry Andric     this->LongDoubleAlign = 64;
940fe6060f1SDimitry Andric   }
9410b57cec5SDimitry Andric };
9420b57cec5SDimitry Andric 
94306c3fb27SDimitry Andric // OHOS target
94406c3fb27SDimitry Andric template <typename Target>
94506c3fb27SDimitry Andric class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> {
94606c3fb27SDimitry Andric protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)94706c3fb27SDimitry Andric   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
94806c3fb27SDimitry Andric                     MacroBuilder &Builder) const override {
94906c3fb27SDimitry Andric     // Linux defines; list based off of gcc output
95006c3fb27SDimitry Andric     DefineStd(Builder, "unix", Opts);
95106c3fb27SDimitry Andric 
95206c3fb27SDimitry Andric     // Generic OHOS target defines
95306c3fb27SDimitry Andric     if (Triple.isOHOSFamily()) {
95406c3fb27SDimitry Andric       Builder.defineMacro("__OHOS_FAMILY__", "1");
95506c3fb27SDimitry Andric 
95606c3fb27SDimitry Andric       auto Version = Triple.getEnvironmentVersion();
95706c3fb27SDimitry Andric       this->PlatformName = "ohos";
95806c3fb27SDimitry Andric       this->PlatformMinVersion = Version;
95906c3fb27SDimitry Andric       Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor()));
96006c3fb27SDimitry Andric       if (auto Minor = Version.getMinor())
96106c3fb27SDimitry Andric         Builder.defineMacro("__OHOS_Minor__", Twine(*Minor));
96206c3fb27SDimitry Andric       if (auto Subminor = Version.getSubminor())
96306c3fb27SDimitry Andric         Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor));
96406c3fb27SDimitry Andric     }
96506c3fb27SDimitry Andric 
96606c3fb27SDimitry Andric     if (Triple.isOpenHOS())
96706c3fb27SDimitry Andric       Builder.defineMacro("__OHOS__");
96806c3fb27SDimitry Andric 
96906c3fb27SDimitry Andric     if (Triple.isOSLinux()) {
97006c3fb27SDimitry Andric       DefineStd(Builder, "linux", Opts);
97106c3fb27SDimitry Andric     } else if (Triple.isOSLiteOS()) {
97206c3fb27SDimitry Andric       Builder.defineMacro("__LITEOS__");
97306c3fb27SDimitry Andric     }
97406c3fb27SDimitry Andric 
97506c3fb27SDimitry Andric     if (Opts.POSIXThreads)
97606c3fb27SDimitry Andric       Builder.defineMacro("_REENTRANT");
97706c3fb27SDimitry Andric     if (Opts.CPlusPlus)
97806c3fb27SDimitry Andric       Builder.defineMacro("_GNU_SOURCE");
97906c3fb27SDimitry Andric     if (this->HasFloat128)
98006c3fb27SDimitry Andric       Builder.defineMacro("__FLOAT128__");
98106c3fb27SDimitry Andric   }
98206c3fb27SDimitry Andric 
98306c3fb27SDimitry Andric public:
OHOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)98406c3fb27SDimitry Andric   OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
98506c3fb27SDimitry Andric       : OSTargetInfo<Target>(Triple, Opts) {
98606c3fb27SDimitry Andric     this->WIntType = TargetInfo::UnsignedInt;
98706c3fb27SDimitry Andric 
98806c3fb27SDimitry Andric     switch (Triple.getArch()) {
98906c3fb27SDimitry Andric     default:
99006c3fb27SDimitry Andric       break;
99106c3fb27SDimitry Andric     case llvm::Triple::x86:
99206c3fb27SDimitry Andric     case llvm::Triple::x86_64:
99306c3fb27SDimitry Andric       this->HasFloat128 = true;
99406c3fb27SDimitry Andric       break;
99506c3fb27SDimitry Andric     }
99606c3fb27SDimitry Andric   }
99706c3fb27SDimitry Andric 
getStaticInitSectionSpecifier()99806c3fb27SDimitry Andric   const char *getStaticInitSectionSpecifier() const override {
99906c3fb27SDimitry Andric     return ".text.startup";
100006c3fb27SDimitry Andric   }
100106c3fb27SDimitry Andric };
100206c3fb27SDimitry Andric 
10030b57cec5SDimitry Andric } // namespace targets
10040b57cec5SDimitry Andric } // namespace clang
10050b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
1006