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