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 list permitted architecture/OS
91    // combinations.
92    this->TLSSupported = false;
93
94    if (Triple.isMacOSX())
95      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
96    else if (Triple.isiOS()) {
97      // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
98      // 32-bit simulator from 10 onwards.
99      if (Triple.isArch64Bit())
100        this->TLSSupported = !Triple.isOSVersionLT(8);
101      else if (Triple.isArch32Bit()) {
102        if (!Triple.isSimulatorEnvironment())
103          this->TLSSupported = !Triple.isOSVersionLT(9);
104        else
105          this->TLSSupported = !Triple.isOSVersionLT(10);
106      }
107    } else if (Triple.isWatchOS()) {
108      if (!Triple.isSimulatorEnvironment())
109        this->TLSSupported = !Triple.isOSVersionLT(2);
110      else
111        this->TLSSupported = !Triple.isOSVersionLT(3);
112    }
113
114    this->MCountName = "\01mcount";
115  }
116
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    this->WCharType = this->WIntType = this->SignedInt;
469    this->IntMaxType = TargetInfo::SignedLongLong;
470    this->Int64Type = TargetInfo::SignedLongLong;
471    switch (Triple.getArch()) {
472    case llvm::Triple::x86:
473    case llvm::Triple::x86_64:
474      this->HasFloat128 = true;
475      LLVM_FALLTHROUGH;
476    default:
477      this->MCountName = "__mcount";
478      break;
479    case llvm::Triple::mips64:
480    case llvm::Triple::mips64el:
481    case llvm::Triple::ppc:
482    case llvm::Triple::ppc64:
483    case llvm::Triple::ppc64le:
484    case llvm::Triple::sparcv9:
485      this->MCountName = "_mcount";
486      break;
487    }
488  }
489};
490
491// PSP Target
492template <typename Target>
493class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
494protected:
495  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
496                    MacroBuilder &Builder) const override {
497    // PSP defines; list based on the output of the pspdev gcc toolchain.
498    Builder.defineMacro("PSP");
499    Builder.defineMacro("_PSP");
500    Builder.defineMacro("__psp__");
501    Builder.defineMacro("__ELF__");
502  }
503
504public:
505  PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
506};
507
508// PS3 PPU Target
509template <typename Target>
510class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
511protected:
512  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
513                    MacroBuilder &Builder) const override {
514    // PS3 PPU defines.
515    Builder.defineMacro("__PPC__");
516    Builder.defineMacro("__PPU__");
517    Builder.defineMacro("__CELLOS_LV2__");
518    Builder.defineMacro("__ELF__");
519    Builder.defineMacro("__LP32__");
520    Builder.defineMacro("_ARCH_PPC64");
521    Builder.defineMacro("__powerpc64__");
522  }
523
524public:
525  PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
526      : OSTargetInfo<Target>(Triple, Opts) {
527    this->LongWidth = this->LongAlign = 32;
528    this->PointerWidth = this->PointerAlign = 32;
529    this->IntMaxType = TargetInfo::SignedLongLong;
530    this->Int64Type = TargetInfo::SignedLongLong;
531    this->SizeType = TargetInfo::UnsignedInt;
532    this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
533  }
534};
535
536template <typename Target>
537class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
538protected:
539  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
540                    MacroBuilder &Builder) const override {
541    Builder.defineMacro("__FreeBSD__", "9");
542    Builder.defineMacro("__FreeBSD_cc_version", "900001");
543    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
544    DefineStd(Builder, "unix", Opts);
545    Builder.defineMacro("__ELF__");
546    Builder.defineMacro("__SCE__");
547    Builder.defineMacro("__ORBIS__");
548  }
549
550public:
551  PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
552      : OSTargetInfo<Target>(Triple, Opts) {
553    this->WCharType = TargetInfo::UnsignedShort;
554
555    // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
556    this->MaxTLSAlign = 256;
557
558    // On PS4, do not honor explicit bit field alignment,
559    // as in "__attribute__((aligned(2))) int b : 1;".
560    this->UseExplicitBitFieldAlignment = false;
561
562    switch (Triple.getArch()) {
563    default:
564    case llvm::Triple::x86_64:
565      this->MCountName = ".mcount";
566      this->NewAlign = 256;
567      break;
568    }
569  }
570  TargetInfo::CallingConvCheckResult
571  checkCallingConvention(CallingConv CC) const override {
572    return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
573  }
574};
575
576// RTEMS Target
577template <typename Target>
578class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
579protected:
580  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
581                    MacroBuilder &Builder) const override {
582    // RTEMS defines; list based off of gcc output
583
584    Builder.defineMacro("__rtems__");
585    Builder.defineMacro("__ELF__");
586    if (Opts.CPlusPlus)
587      Builder.defineMacro("_GNU_SOURCE");
588  }
589
590public:
591  RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
592      : OSTargetInfo<Target>(Triple, Opts) {
593    switch (Triple.getArch()) {
594    default:
595    case llvm::Triple::x86:
596      // this->MCountName = ".mcount";
597      break;
598    case llvm::Triple::mips:
599    case llvm::Triple::mipsel:
600    case llvm::Triple::ppc:
601    case llvm::Triple::ppc64:
602    case llvm::Triple::ppc64le:
603      // this->MCountName = "_mcount";
604      break;
605    case llvm::Triple::arm:
606      // this->MCountName = "__mcount";
607      break;
608    }
609  }
610};
611
612// Solaris target
613template <typename Target>
614class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
615protected:
616  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
617                    MacroBuilder &Builder) const override {
618    DefineStd(Builder, "sun", Opts);
619    DefineStd(Builder, "unix", Opts);
620    Builder.defineMacro("__ELF__");
621    Builder.defineMacro("__svr4__");
622    Builder.defineMacro("__SVR4");
623    // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
624    // newer, but to 500 for everything else.  feature_test.h has a check to
625    // ensure that you are not using C99 with an old version of X/Open or C89
626    // with a new version.
627    if (Opts.C99)
628      Builder.defineMacro("_XOPEN_SOURCE", "600");
629    else
630      Builder.defineMacro("_XOPEN_SOURCE", "500");
631    if (Opts.CPlusPlus) {
632      Builder.defineMacro("__C99FEATURES__");
633      Builder.defineMacro("_FILE_OFFSET_BITS", "64");
634    }
635    // GCC restricts the next two to C++.
636    Builder.defineMacro("_LARGEFILE_SOURCE");
637    Builder.defineMacro("_LARGEFILE64_SOURCE");
638    Builder.defineMacro("__EXTENSIONS__");
639    if (Opts.POSIXThreads)
640      Builder.defineMacro("_REENTRANT");
641    if (this->HasFloat128)
642      Builder.defineMacro("__FLOAT128__");
643  }
644
645public:
646  SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
647      : OSTargetInfo<Target>(Triple, Opts) {
648    if (this->PointerWidth == 64) {
649      this->WCharType = this->WIntType = this->SignedInt;
650    } else {
651      this->WCharType = this->WIntType = this->SignedLong;
652    }
653    switch (Triple.getArch()) {
654    default:
655      break;
656    case llvm::Triple::x86:
657    case llvm::Triple::x86_64:
658      this->HasFloat128 = true;
659      break;
660    }
661  }
662};
663
664// AIX Target
665template <typename Target>
666class AIXTargetInfo : public OSTargetInfo<Target> {
667protected:
668  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
669                    MacroBuilder &Builder) const override {
670    DefineStd(Builder, "unix", Opts);
671    Builder.defineMacro("_IBMR2");
672    Builder.defineMacro("_POWER");
673
674    Builder.defineMacro("_AIX");
675
676    unsigned Major, Minor, Micro;
677    Triple.getOSVersion(Major, Minor, Micro);
678
679    // Define AIX OS-Version Macros.
680    // Includes logic for legacy versions of AIX; no specific intent to support.
681    std::pair<int, int> OsVersion = {Major, Minor};
682    if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
683    if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
684    if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
685    if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
686    if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
687    if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
688    if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
689    if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
690    if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
691    if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
692
693    // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
694    Builder.defineMacro("_LONG_LONG");
695
696    if (Opts.POSIXThreads) {
697      Builder.defineMacro("_THREAD_SAFE");
698    }
699
700    if (this->PointerWidth == 64) {
701      Builder.defineMacro("__64BIT__");
702    }
703
704    // Define _WCHAR_T when it is a fundamental type
705    // (i.e., for C++ without -fno-wchar).
706    if (Opts.CPlusPlus && Opts.WChar) {
707      Builder.defineMacro("_WCHAR_T");
708    }
709  }
710
711public:
712  AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
713      : OSTargetInfo<Target>(Triple, Opts) {
714    this->TheCXXABI.set(TargetCXXABI::XL);
715
716    if (this->PointerWidth == 64) {
717      this->WCharType = this->UnsignedInt;
718    } else {
719      this->WCharType = this->UnsignedShort;
720    }
721    this->UseZeroLengthBitfieldAlignment = true;
722  }
723
724  // AIX sets FLT_EVAL_METHOD to be 1.
725  unsigned getFloatEvalMethod() const override { return 1; }
726  bool hasInt128Type() const override { return false; }
727};
728
729void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
730                       MacroBuilder &Builder);
731
732// Windows target
733template <typename Target>
734class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
735protected:
736  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
737                    MacroBuilder &Builder) const override {
738    addWindowsDefines(Triple, Opts, Builder);
739  }
740
741public:
742  WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
743      : OSTargetInfo<Target>(Triple, Opts) {
744    this->WCharType = TargetInfo::UnsignedShort;
745    this->WIntType = TargetInfo::UnsignedShort;
746  }
747};
748
749template <typename Target>
750class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
751protected:
752  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
753                    MacroBuilder &Builder) const override {
754    if (Opts.POSIXThreads)
755      Builder.defineMacro("_REENTRANT");
756    if (Opts.CPlusPlus)
757      Builder.defineMacro("_GNU_SOURCE");
758
759    DefineStd(Builder, "unix", Opts);
760    Builder.defineMacro("__ELF__");
761    Builder.defineMacro("__native_client__");
762  }
763
764public:
765  NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
766      : OSTargetInfo<Target>(Triple, Opts) {
767    this->LongAlign = 32;
768    this->LongWidth = 32;
769    this->PointerAlign = 32;
770    this->PointerWidth = 32;
771    this->IntMaxType = TargetInfo::SignedLongLong;
772    this->Int64Type = TargetInfo::SignedLongLong;
773    this->DoubleAlign = 64;
774    this->LongDoubleWidth = 64;
775    this->LongDoubleAlign = 64;
776    this->LongLongWidth = 64;
777    this->LongLongAlign = 64;
778    this->SizeType = TargetInfo::UnsignedInt;
779    this->PtrDiffType = TargetInfo::SignedInt;
780    this->IntPtrType = TargetInfo::SignedInt;
781    // RegParmMax is inherited from the underlying architecture.
782    this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
783    if (Triple.getArch() == llvm::Triple::arm) {
784      // Handled in ARM's setABI().
785    } else if (Triple.getArch() == llvm::Triple::x86) {
786      this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
787                            "i64:64-n8:16:32-S128");
788    } else if (Triple.getArch() == llvm::Triple::x86_64) {
789      this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
790                            "i64:64-n8:16:32:64-S128");
791    } else if (Triple.getArch() == llvm::Triple::mipsel) {
792      // Handled on mips' setDataLayout.
793    } else {
794      assert(Triple.getArch() == llvm::Triple::le32);
795      this->resetDataLayout("e-p:32:32-i64:64");
796    }
797  }
798};
799
800// Fuchsia Target
801template <typename Target>
802class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
803protected:
804  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
805                    MacroBuilder &Builder) const override {
806    Builder.defineMacro("__Fuchsia__");
807    Builder.defineMacro("__ELF__");
808    if (Opts.POSIXThreads)
809      Builder.defineMacro("_REENTRANT");
810    // Required by the libc++ locale support.
811    if (Opts.CPlusPlus)
812      Builder.defineMacro("_GNU_SOURCE");
813  }
814
815public:
816  FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
817      : OSTargetInfo<Target>(Triple, Opts) {
818    this->MCountName = "__mcount";
819    this->TheCXXABI.set(TargetCXXABI::Fuchsia);
820  }
821};
822
823// WebAssembly target
824template <typename Target>
825class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
826    : public OSTargetInfo<Target> {
827protected:
828  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
829                    MacroBuilder &Builder) const override {
830    // A common platform macro.
831    if (Opts.POSIXThreads)
832      Builder.defineMacro("_REENTRANT");
833    // Follow g++ convention and predefine _GNU_SOURCE for C++.
834    if (Opts.CPlusPlus)
835      Builder.defineMacro("_GNU_SOURCE");
836    // Indicate that we have __float128.
837    Builder.defineMacro("__FLOAT128__");
838  }
839
840public:
841  explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
842                                   const TargetOptions &Opts)
843      : OSTargetInfo<Target>(Triple, Opts) {
844    this->MCountName = "__mcount";
845    this->TheCXXABI.set(TargetCXXABI::WebAssembly);
846    this->HasFloat128 = true;
847  }
848};
849
850// WASI target
851template <typename Target>
852class LLVM_LIBRARY_VISIBILITY WASITargetInfo
853    : public WebAssemblyOSTargetInfo<Target> {
854  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
855                    MacroBuilder &Builder) const final {
856    WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
857    Builder.defineMacro("__wasi__");
858  }
859
860public:
861  explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
862      : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
863};
864
865// Emscripten target
866template <typename Target>
867class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
868    : public WebAssemblyOSTargetInfo<Target> {
869  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
870                    MacroBuilder &Builder) const final {
871    WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
872    Builder.defineMacro("__EMSCRIPTEN__");
873  }
874
875public:
876  explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
877      : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
878};
879
880} // namespace targets
881} // namespace clang
882#endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
883