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