OSTargets.h revision 360784
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
18namespace clang {
19namespace targets {
20
21template <typename TgtInfo>
22class LLVM_LIBRARY_VISIBILITY OSTargetInfo : public TgtInfo {
23protected:
24  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
25                            MacroBuilder &Builder) const = 0;
26
27public:
28  OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
29      : TgtInfo(Triple, Opts) {}
30
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
39template <typename Target>
40class LLVM_LIBRARY_VISIBILITY CloudABITargetInfo : public OSTargetInfo<Target> {
41protected:
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
53public:
54  CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
55      : OSTargetInfo<Target>(Triple, Opts) {}
56};
57
58// Ananas target
59template <typename Target>
60class LLVM_LIBRARY_VISIBILITY AnanasTargetInfo : public OSTargetInfo<Target> {
61protected:
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
69public:
70  AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
71      : OSTargetInfo<Target>(Triple, Opts) {}
72};
73
74void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
75                      const llvm::Triple &Triple, StringRef &PlatformName,
76                      VersionTuple &PlatformMinVersion);
77
78template <typename Target>
79class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
80protected:
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
87public:
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
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
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.
134  bool hasProtectedVisibility() const override { return false; }
135
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
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
178template <typename Target>
179class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
180    : public OSTargetInfo<Target> {
181protected:
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("__DragonFly_cc_version", "100001");
187    Builder.defineMacro("__ELF__");
188    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
189    Builder.defineMacro("__tune_i386__");
190    DefineStd(Builder, "unix", Opts);
191  }
192
193public:
194  DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
195      : OSTargetInfo<Target>(Triple, Opts) {
196    switch (Triple.getArch()) {
197    default:
198    case llvm::Triple::x86:
199    case llvm::Triple::x86_64:
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
211template <typename Target>
212class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
213protected:
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
243public:
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
267template <typename Target>
268class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> {
269protected:
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
284public:
285  KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
286      : OSTargetInfo<Target>(Triple, Opts) {}
287};
288
289// Haiku Target
290template <typename Target>
291class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
292protected:
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
303public:
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
323template <typename Target>
324class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
325protected:
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  }
340public:
341  HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
342      : OSTargetInfo<Target>(Triple, Opts) {}
343};
344
345// Minix Target
346template <typename Target>
347class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> {
348protected:
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
364public:
365  MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
366      : OSTargetInfo<Target>(Triple, Opts) {}
367};
368
369// Linux target
370template <typename Target>
371class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
372protected:
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
398public:
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
422  const char *getStaticInitSectionSpecifier() const override {
423    return ".text.startup";
424  }
425};
426
427// NetBSD Target
428template <typename Target>
429class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
430protected:
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
441public:
442  NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
443      : OSTargetInfo<Target>(Triple, Opts) {
444    this->MCountName = "__mcount";
445  }
446};
447
448// OpenBSD Target
449template <typename Target>
450class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
451protected:
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
465public:
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
487template <typename Target>
488class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
489protected:
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
499public:
500  PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
501};
502
503// PS3 PPU Target
504template <typename Target>
505class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
506protected:
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
519public:
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
531template <typename Target>
532class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
533protected:
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
545public:
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
566  checkCallingConvention(CallingConv CC) const override {
567    return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
568  }
569};
570
571// RTEMS Target
572template <typename Target>
573class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
574protected:
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
585public:
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
608template <typename Target>
609class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
610protected:
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
640public:
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
660template <typename Target>
661class AIXTargetInfo : public OSTargetInfo<Target> {
662protected:
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
706public:
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.
718  unsigned getFloatEvalMethod() const override { return 1; }
719  bool hasInt128Type() const override { return false; }
720};
721
722void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
723                       MacroBuilder &Builder);
724
725// Windows target
726template <typename Target>
727class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
728protected:
729  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
730                    MacroBuilder &Builder) const override {
731    addWindowsDefines(Triple, Opts, Builder);
732  }
733
734public:
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
742template <typename Target>
743class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
744protected:
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
757public:
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
794template <typename Target>
795class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
796protected:
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
808public:
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
817template <typename Target>
818class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
819    : public OSTargetInfo<Target> {
820protected:
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
833public:
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
844template <typename Target>
845class LLVM_LIBRARY_VISIBILITY WASITargetInfo
846    : public WebAssemblyOSTargetInfo<Target> {
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
853public:
854  explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
855      : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
856};
857
858// Emscripten target
859template <typename Target>
860class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
861    : public WebAssemblyOSTargetInfo<Target> {
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
868public:
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