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