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 whitelist 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       llvm_unreachable("Unexpected OS");
158     }
159 
160     unsigned Major, Minor, Micro;
161     T.getOSVersion(Major, Minor, Micro);
162     if (llvm::VersionTuple(Major, Minor, Micro) < MinVersion)
163       return 64;
164     return OSTargetInfo<Target>::getExnObjectAlignment();
165   }
166 
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned)167   TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth,
168                                              bool IsSigned) const final {
169     // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`.
170     return BitWidth == 64
171                ? (IsSigned ? TargetInfo::SignedLongLong
172                            : TargetInfo::UnsignedLongLong)
173                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
174   }
175 };
176 
177 // DragonFlyBSD Target
178 template <typename Target>
179 class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
180     : public OSTargetInfo<Target> {
181 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)182   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
183                     MacroBuilder &Builder) const override {
184     // DragonFly defines; list based off of gcc output
185     Builder.defineMacro("__DragonFly__");
186     Builder.defineMacro("__ELF__");
187     DefineStd(Builder, "unix", Opts);
188     if (this->HasFloat128)
189       Builder.defineMacro("__FLOAT128__");
190   }
191 
192 public:
DragonFlyBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)193   DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
194       : OSTargetInfo<Target>(Triple, Opts) {
195     switch (Triple.getArch()) {
196     default:
197     case llvm::Triple::x86:
198     case llvm::Triple::x86_64:
199       this->HasFloat128 = true;
200       this->MCountName = ".mcount";
201       break;
202     }
203   }
204 };
205 
206 #ifndef FREEBSD_CC_VERSION
207 #define FREEBSD_CC_VERSION 0U
208 #endif
209 
210 // FreeBSD Target
211 template <typename Target>
212 class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
213 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)214   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
215                     MacroBuilder &Builder) const override {
216     // FreeBSD defines; list based off of gcc output
217 
218     unsigned Release = Triple.getOSMajorVersion();
219     if (Release == 0U)
220       Release = 8U;
221     unsigned CCVersion = FREEBSD_CC_VERSION;
222     if (CCVersion == 0U)
223       CCVersion = Release * 100000U + 1U;
224 
225     Builder.defineMacro("__FreeBSD__", Twine(Release));
226     Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
227     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
228     DefineStd(Builder, "unix", Opts);
229     Builder.defineMacro("__ELF__");
230 
231     // On FreeBSD, wchar_t contains the number of the code point as
232     // used by the character set of the locale. These character sets are
233     // not necessarily a superset of ASCII.
234     //
235     // FIXME: This is wrong; the macro refers to the numerical values
236     // of wchar_t *literals*, which are not locale-dependent. However,
237     // FreeBSD systems apparently depend on us getting this wrong, and
238     // setting this to 1 is conforming even if all the basic source
239     // character literals have the same encoding as char and wchar_t.
240     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
241   }
242 
243 public:
FreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)244   FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
245       : OSTargetInfo<Target>(Triple, Opts) {
246     switch (Triple.getArch()) {
247     default:
248     case llvm::Triple::x86:
249     case llvm::Triple::x86_64:
250       this->MCountName = ".mcount";
251       break;
252     case llvm::Triple::mips:
253     case llvm::Triple::mipsel:
254     case llvm::Triple::ppc:
255     case llvm::Triple::ppc64:
256     case llvm::Triple::ppc64le:
257       this->MCountName = "_mcount";
258       break;
259     case llvm::Triple::arm:
260       this->MCountName = "__mcount";
261       break;
262     }
263   }
264 };
265 
266 // GNU/kFreeBSD Target
267 template <typename Target>
268 class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> {
269 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)270   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
271                     MacroBuilder &Builder) const override {
272     // GNU/kFreeBSD defines; list based off of gcc output
273 
274     DefineStd(Builder, "unix", Opts);
275     Builder.defineMacro("__FreeBSD_kernel__");
276     Builder.defineMacro("__GLIBC__");
277     Builder.defineMacro("__ELF__");
278     if (Opts.POSIXThreads)
279       Builder.defineMacro("_REENTRANT");
280     if (Opts.CPlusPlus)
281       Builder.defineMacro("_GNU_SOURCE");
282   }
283 
284 public:
KFreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)285   KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
286       : OSTargetInfo<Target>(Triple, Opts) {}
287 };
288 
289 // Haiku Target
290 template <typename Target>
291 class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
292 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)293   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
294                     MacroBuilder &Builder) const override {
295     // Haiku defines; list based off of gcc output
296     Builder.defineMacro("__HAIKU__");
297     Builder.defineMacro("__ELF__");
298     DefineStd(Builder, "unix", Opts);
299     if (this->HasFloat128)
300       Builder.defineMacro("__FLOAT128__");
301   }
302 
303 public:
HaikuTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)304   HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
305       : OSTargetInfo<Target>(Triple, Opts) {
306     this->SizeType = TargetInfo::UnsignedLong;
307     this->IntPtrType = TargetInfo::SignedLong;
308     this->PtrDiffType = TargetInfo::SignedLong;
309     this->ProcessIDType = TargetInfo::SignedLong;
310     this->TLSSupported = false;
311     switch (Triple.getArch()) {
312     default:
313       break;
314     case llvm::Triple::x86:
315     case llvm::Triple::x86_64:
316       this->HasFloat128 = true;
317       break;
318     }
319   }
320 };
321 
322 // Hurd target
323 template <typename Target>
324 class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
325 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)326   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
327                     MacroBuilder &Builder) const override {
328     // Hurd defines; list based off of gcc output.
329     DefineStd(Builder, "unix", Opts);
330     Builder.defineMacro("__GNU__");
331     Builder.defineMacro("__gnu_hurd__");
332     Builder.defineMacro("__MACH__");
333     Builder.defineMacro("__GLIBC__");
334     Builder.defineMacro("__ELF__");
335     if (Opts.POSIXThreads)
336       Builder.defineMacro("_REENTRANT");
337     if (Opts.CPlusPlus)
338       Builder.defineMacro("_GNU_SOURCE");
339   }
340 public:
HurdTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)341   HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
342       : OSTargetInfo<Target>(Triple, Opts) {}
343 };
344 
345 // Minix Target
346 template <typename Target>
347 class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> {
348 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)349   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
350                     MacroBuilder &Builder) const override {
351     // Minix defines
352 
353     Builder.defineMacro("__minix", "3");
354     Builder.defineMacro("_EM_WSIZE", "4");
355     Builder.defineMacro("_EM_PSIZE", "4");
356     Builder.defineMacro("_EM_SSIZE", "2");
357     Builder.defineMacro("_EM_LSIZE", "4");
358     Builder.defineMacro("_EM_FSIZE", "4");
359     Builder.defineMacro("_EM_DSIZE", "8");
360     Builder.defineMacro("__ELF__");
361     DefineStd(Builder, "unix", Opts);
362   }
363 
364 public:
MinixTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)365   MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
366       : OSTargetInfo<Target>(Triple, Opts) {}
367 };
368 
369 // Linux target
370 template <typename Target>
371 class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
372 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)373   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
374                     MacroBuilder &Builder) const override {
375     // Linux defines; list based off of gcc output
376     DefineStd(Builder, "unix", Opts);
377     DefineStd(Builder, "linux", Opts);
378     Builder.defineMacro("__ELF__");
379     if (Triple.isAndroid()) {
380       Builder.defineMacro("__ANDROID__", "1");
381       unsigned Maj, Min, Rev;
382       Triple.getEnvironmentVersion(Maj, Min, Rev);
383       this->PlatformName = "android";
384       this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
385       if (Maj)
386         Builder.defineMacro("__ANDROID_API__", Twine(Maj));
387     } else {
388         Builder.defineMacro("__gnu_linux__");
389     }
390     if (Opts.POSIXThreads)
391       Builder.defineMacro("_REENTRANT");
392     if (Opts.CPlusPlus)
393       Builder.defineMacro("_GNU_SOURCE");
394     if (this->HasFloat128)
395       Builder.defineMacro("__FLOAT128__");
396   }
397 
398 public:
LinuxTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)399   LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
400       : OSTargetInfo<Target>(Triple, Opts) {
401     this->WIntType = TargetInfo::UnsignedInt;
402 
403     switch (Triple.getArch()) {
404     default:
405       break;
406     case llvm::Triple::mips:
407     case llvm::Triple::mipsel:
408     case llvm::Triple::mips64:
409     case llvm::Triple::mips64el:
410     case llvm::Triple::ppc:
411     case llvm::Triple::ppc64:
412     case llvm::Triple::ppc64le:
413       this->MCountName = "_mcount";
414       break;
415     case llvm::Triple::x86:
416     case llvm::Triple::x86_64:
417       this->HasFloat128 = true;
418       break;
419     }
420   }
421 
getStaticInitSectionSpecifier()422   const char *getStaticInitSectionSpecifier() const override {
423     return ".text.startup";
424   }
425 };
426 
427 // NetBSD Target
428 template <typename Target>
429 class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
430 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)431   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
432                     MacroBuilder &Builder) const override {
433     // NetBSD defines; list based off of gcc output
434     Builder.defineMacro("__NetBSD__");
435     Builder.defineMacro("__unix__");
436     Builder.defineMacro("__ELF__");
437     if (Opts.POSIXThreads)
438       Builder.defineMacro("_REENTRANT");
439   }
440 
441 public:
NetBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)442   NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
443       : OSTargetInfo<Target>(Triple, Opts) {
444     this->MCountName = "__mcount";
445   }
446 };
447 
448 // OpenBSD Target
449 template <typename Target>
450 class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
451 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)452   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
453                     MacroBuilder &Builder) const override {
454     // OpenBSD defines; list based off of gcc output
455 
456     Builder.defineMacro("__OpenBSD__");
457     DefineStd(Builder, "unix", Opts);
458     Builder.defineMacro("__ELF__");
459     if (Opts.POSIXThreads)
460       Builder.defineMacro("_REENTRANT");
461     if (this->HasFloat128)
462       Builder.defineMacro("__FLOAT128__");
463   }
464 
465 public:
OpenBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)466   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
467       : OSTargetInfo<Target>(Triple, Opts) {
468     switch (Triple.getArch()) {
469     case llvm::Triple::x86:
470     case llvm::Triple::x86_64:
471       this->HasFloat128 = true;
472       LLVM_FALLTHROUGH;
473     default:
474       this->MCountName = "__mcount";
475       break;
476     case llvm::Triple::mips64:
477     case llvm::Triple::mips64el:
478     case llvm::Triple::ppc:
479     case llvm::Triple::sparcv9:
480       this->MCountName = "_mcount";
481       break;
482     }
483   }
484 };
485 
486 // PSP Target
487 template <typename Target>
488 class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
489 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)490   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
491                     MacroBuilder &Builder) const override {
492     // PSP defines; list based on the output of the pspdev gcc toolchain.
493     Builder.defineMacro("PSP");
494     Builder.defineMacro("_PSP");
495     Builder.defineMacro("__psp__");
496     Builder.defineMacro("__ELF__");
497   }
498 
499 public:
PSPTargetInfo(const llvm::Triple & Triple)500   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
501 };
502 
503 // PS3 PPU Target
504 template <typename Target>
505 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
506 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)507   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
508                     MacroBuilder &Builder) const override {
509     // PS3 PPU defines.
510     Builder.defineMacro("__PPC__");
511     Builder.defineMacro("__PPU__");
512     Builder.defineMacro("__CELLOS_LV2__");
513     Builder.defineMacro("__ELF__");
514     Builder.defineMacro("__LP32__");
515     Builder.defineMacro("_ARCH_PPC64");
516     Builder.defineMacro("__powerpc64__");
517   }
518 
519 public:
PS3PPUTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)520   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
521       : OSTargetInfo<Target>(Triple, Opts) {
522     this->LongWidth = this->LongAlign = 32;
523     this->PointerWidth = this->PointerAlign = 32;
524     this->IntMaxType = TargetInfo::SignedLongLong;
525     this->Int64Type = TargetInfo::SignedLongLong;
526     this->SizeType = TargetInfo::UnsignedInt;
527     this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
528   }
529 };
530 
531 template <typename Target>
532 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
533 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)534   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
535                     MacroBuilder &Builder) const override {
536     Builder.defineMacro("__FreeBSD__", "9");
537     Builder.defineMacro("__FreeBSD_cc_version", "900001");
538     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
539     DefineStd(Builder, "unix", Opts);
540     Builder.defineMacro("__ELF__");
541     Builder.defineMacro("__SCE__");
542     Builder.defineMacro("__ORBIS__");
543   }
544 
545 public:
PS4OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)546   PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
547       : OSTargetInfo<Target>(Triple, Opts) {
548     this->WCharType = TargetInfo::UnsignedShort;
549 
550     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
551     this->MaxTLSAlign = 256;
552 
553     // On PS4, do not honor explicit bit field alignment,
554     // as in "__attribute__((aligned(2))) int b : 1;".
555     this->UseExplicitBitFieldAlignment = false;
556 
557     switch (Triple.getArch()) {
558     default:
559     case llvm::Triple::x86_64:
560       this->MCountName = ".mcount";
561       this->NewAlign = 256;
562       break;
563     }
564   }
565   TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC)566   checkCallingConvention(CallingConv CC) const override {
567     return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
568   }
569 };
570 
571 // RTEMS Target
572 template <typename Target>
573 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
574 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)575   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
576                     MacroBuilder &Builder) const override {
577     // RTEMS defines; list based off of gcc output
578 
579     Builder.defineMacro("__rtems__");
580     Builder.defineMacro("__ELF__");
581     if (Opts.CPlusPlus)
582       Builder.defineMacro("_GNU_SOURCE");
583   }
584 
585 public:
RTEMSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)586   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
587       : OSTargetInfo<Target>(Triple, Opts) {
588     switch (Triple.getArch()) {
589     default:
590     case llvm::Triple::x86:
591       // this->MCountName = ".mcount";
592       break;
593     case llvm::Triple::mips:
594     case llvm::Triple::mipsel:
595     case llvm::Triple::ppc:
596     case llvm::Triple::ppc64:
597     case llvm::Triple::ppc64le:
598       // this->MCountName = "_mcount";
599       break;
600     case llvm::Triple::arm:
601       // this->MCountName = "__mcount";
602       break;
603     }
604   }
605 };
606 
607 // Solaris target
608 template <typename Target>
609 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
610 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)611   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
612                     MacroBuilder &Builder) const override {
613     DefineStd(Builder, "sun", Opts);
614     DefineStd(Builder, "unix", Opts);
615     Builder.defineMacro("__ELF__");
616     Builder.defineMacro("__svr4__");
617     Builder.defineMacro("__SVR4");
618     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
619     // newer, but to 500 for everything else.  feature_test.h has a check to
620     // ensure that you are not using C99 with an old version of X/Open or C89
621     // with a new version.
622     if (Opts.C99)
623       Builder.defineMacro("_XOPEN_SOURCE", "600");
624     else
625       Builder.defineMacro("_XOPEN_SOURCE", "500");
626     if (Opts.CPlusPlus) {
627       Builder.defineMacro("__C99FEATURES__");
628       Builder.defineMacro("_FILE_OFFSET_BITS", "64");
629     }
630     // GCC restricts the next two to C++.
631     Builder.defineMacro("_LARGEFILE_SOURCE");
632     Builder.defineMacro("_LARGEFILE64_SOURCE");
633     Builder.defineMacro("__EXTENSIONS__");
634     if (Opts.POSIXThreads)
635       Builder.defineMacro("_REENTRANT");
636     if (this->HasFloat128)
637       Builder.defineMacro("__FLOAT128__");
638   }
639 
640 public:
SolarisTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)641   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
642       : OSTargetInfo<Target>(Triple, Opts) {
643     if (this->PointerWidth == 64) {
644       this->WCharType = this->WIntType = this->SignedInt;
645     } else {
646       this->WCharType = this->WIntType = this->SignedLong;
647     }
648     switch (Triple.getArch()) {
649     default:
650       break;
651     case llvm::Triple::x86:
652     case llvm::Triple::x86_64:
653       this->HasFloat128 = true;
654       break;
655     }
656   }
657 };
658 
659 // AIX Target
660 template <typename Target>
661 class AIXTargetInfo : public OSTargetInfo<Target> {
662 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)663   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
664                     MacroBuilder &Builder) const override {
665     DefineStd(Builder, "unix", Opts);
666     Builder.defineMacro("_IBMR2");
667     Builder.defineMacro("_POWER");
668 
669     Builder.defineMacro("_AIX");
670 
671     unsigned Major, Minor, Micro;
672     Triple.getOSVersion(Major, Minor, Micro);
673 
674     // Define AIX OS-Version Macros.
675     // Includes logic for legacy versions of AIX; no specific intent to support.
676     std::pair<int, int> OsVersion = {Major, Minor};
677     if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
678     if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
679     if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
680     if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
681     if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
682     if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
683     if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
684     if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
685     if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
686     if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
687 
688     // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
689     Builder.defineMacro("_LONG_LONG");
690 
691     if (Opts.POSIXThreads) {
692       Builder.defineMacro("_THREAD_SAFE");
693     }
694 
695     if (this->PointerWidth == 64) {
696       Builder.defineMacro("__64BIT__");
697     }
698 
699     // Define _WCHAR_T when it is a fundamental type
700     // (i.e., for C++ without -fno-wchar).
701     if (Opts.CPlusPlus && Opts.WChar) {
702       Builder.defineMacro("_WCHAR_T");
703     }
704   }
705 
706 public:
AIXTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)707   AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
708       : OSTargetInfo<Target>(Triple, Opts) {
709     if (this->PointerWidth == 64) {
710       this->WCharType = this->UnsignedInt;
711     } else {
712       this->WCharType = this->UnsignedShort;
713     }
714     this->UseZeroLengthBitfieldAlignment = true;
715   }
716 
717   // AIX sets FLT_EVAL_METHOD to be 1.
getFloatEvalMethod()718   unsigned getFloatEvalMethod() const override { return 1; }
hasInt128Type()719   bool hasInt128Type() const override { return false; }
720 };
721 
722 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
723                        MacroBuilder &Builder);
724 
725 // Windows target
726 template <typename Target>
727 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
728 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)729   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
730                     MacroBuilder &Builder) const override {
731     addWindowsDefines(Triple, Opts, Builder);
732   }
733 
734 public:
WindowsTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)735   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
736       : OSTargetInfo<Target>(Triple, Opts) {
737     this->WCharType = TargetInfo::UnsignedShort;
738     this->WIntType = TargetInfo::UnsignedShort;
739   }
740 };
741 
742 template <typename Target>
743 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
744 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)745   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
746                     MacroBuilder &Builder) const override {
747     if (Opts.POSIXThreads)
748       Builder.defineMacro("_REENTRANT");
749     if (Opts.CPlusPlus)
750       Builder.defineMacro("_GNU_SOURCE");
751 
752     DefineStd(Builder, "unix", Opts);
753     Builder.defineMacro("__ELF__");
754     Builder.defineMacro("__native_client__");
755   }
756 
757 public:
NaClTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)758   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
759       : OSTargetInfo<Target>(Triple, Opts) {
760     this->LongAlign = 32;
761     this->LongWidth = 32;
762     this->PointerAlign = 32;
763     this->PointerWidth = 32;
764     this->IntMaxType = TargetInfo::SignedLongLong;
765     this->Int64Type = TargetInfo::SignedLongLong;
766     this->DoubleAlign = 64;
767     this->LongDoubleWidth = 64;
768     this->LongDoubleAlign = 64;
769     this->LongLongWidth = 64;
770     this->LongLongAlign = 64;
771     this->SizeType = TargetInfo::UnsignedInt;
772     this->PtrDiffType = TargetInfo::SignedInt;
773     this->IntPtrType = TargetInfo::SignedInt;
774     // RegParmMax is inherited from the underlying architecture.
775     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
776     if (Triple.getArch() == llvm::Triple::arm) {
777       // Handled in ARM's setABI().
778     } else if (Triple.getArch() == llvm::Triple::x86) {
779       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
780                             "i64:64-n8:16:32-S128");
781     } else if (Triple.getArch() == llvm::Triple::x86_64) {
782       this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
783                             "i64:64-n8:16:32:64-S128");
784     } else if (Triple.getArch() == llvm::Triple::mipsel) {
785       // Handled on mips' setDataLayout.
786     } else {
787       assert(Triple.getArch() == llvm::Triple::le32);
788       this->resetDataLayout("e-p:32:32-i64:64");
789     }
790   }
791 };
792 
793 // Fuchsia Target
794 template <typename Target>
795 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
796 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)797   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
798                     MacroBuilder &Builder) const override {
799     Builder.defineMacro("__Fuchsia__");
800     Builder.defineMacro("__ELF__");
801     if (Opts.POSIXThreads)
802       Builder.defineMacro("_REENTRANT");
803     // Required by the libc++ locale support.
804     if (Opts.CPlusPlus)
805       Builder.defineMacro("_GNU_SOURCE");
806   }
807 
808 public:
FuchsiaTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)809   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
810       : OSTargetInfo<Target>(Triple, Opts) {
811     this->MCountName = "__mcount";
812     this->TheCXXABI.set(TargetCXXABI::Fuchsia);
813   }
814 };
815 
816 // WebAssembly target
817 template <typename Target>
818 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
819     : public OSTargetInfo<Target> {
820 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)821   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
822                     MacroBuilder &Builder) const {
823     // A common platform macro.
824     if (Opts.POSIXThreads)
825       Builder.defineMacro("_REENTRANT");
826     // Follow g++ convention and predefine _GNU_SOURCE for C++.
827     if (Opts.CPlusPlus)
828       Builder.defineMacro("_GNU_SOURCE");
829     // Indicate that we have __float128.
830     Builder.defineMacro("__FLOAT128__");
831   }
832 
833 public:
WebAssemblyOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)834   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
835                                    const TargetOptions &Opts)
836       : OSTargetInfo<Target>(Triple, Opts) {
837     this->MCountName = "__mcount";
838     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
839     this->HasFloat128 = true;
840   }
841 };
842 
843 // WASI target
844 template <typename Target>
845 class LLVM_LIBRARY_VISIBILITY WASITargetInfo
846     : public WebAssemblyOSTargetInfo<Target> {
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)847   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
848                     MacroBuilder &Builder) const final {
849     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
850     Builder.defineMacro("__wasi__");
851   }
852 
853 public:
WASITargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)854   explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
855       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
856 };
857 
858 // Emscripten target
859 template <typename Target>
860 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
861     : public WebAssemblyOSTargetInfo<Target> {
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)862   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
863                     MacroBuilder &Builder) const final {
864     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
865     Builder.defineMacro("__EMSCRIPTEN__");
866   }
867 
868 public:
EmscriptenTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)869   explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
870       : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
871 };
872 
873 } // namespace targets
874 } // namespace clang
875 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
876