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