]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Basic/Targets/OSTargets.h
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / lib / Basic / Targets / OSTargets.h
1 //===--- OSTargets.h - Declare OS target feature support --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares OS specific TargetInfo types.
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
15
16 #include "Targets.h"
17 #include "llvm/MC/MCSectionMachO.h"
18
19 namespace clang {
20 namespace targets {
21
22 template <typename TgtInfo>
23 class LLVM_LIBRARY_VISIBILITY OSTargetInfo : public TgtInfo {
24 protected:
25   virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
26                             MacroBuilder &Builder) const = 0;
27
28 public:
29   OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
30       : TgtInfo(Triple, Opts) {}
31
32   void getTargetDefines(const LangOptions &Opts,
33                         MacroBuilder &Builder) const override {
34     TgtInfo::getTargetDefines(Opts, Builder);
35     getOSDefines(Opts, TgtInfo::getTriple(), Builder);
36   }
37 };
38
39 // CloudABI Target
40 template <typename Target>
41 class LLVM_LIBRARY_VISIBILITY CloudABITargetInfo : public OSTargetInfo<Target> {
42 protected:
43   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
44                     MacroBuilder &Builder) const override {
45     Builder.defineMacro("__CloudABI__");
46     Builder.defineMacro("__ELF__");
47
48     // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t.
49     Builder.defineMacro("__STDC_ISO_10646__", "201206L");
50     Builder.defineMacro("__STDC_UTF_16__");
51     Builder.defineMacro("__STDC_UTF_32__");
52   }
53
54 public:
55   CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
56       : OSTargetInfo<Target>(Triple, Opts) {}
57 };
58
59 // Ananas target
60 template <typename Target>
61 class LLVM_LIBRARY_VISIBILITY AnanasTargetInfo : public OSTargetInfo<Target> {
62 protected:
63   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
64                     MacroBuilder &Builder) const override {
65     // Ananas defines
66     Builder.defineMacro("__Ananas__");
67     Builder.defineMacro("__ELF__");
68   }
69
70 public:
71   AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
72       : OSTargetInfo<Target>(Triple, Opts) {}
73 };
74
75 void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
76                       const llvm::Triple &Triple, StringRef &PlatformName,
77                       VersionTuple &PlatformMinVersion);
78
79 template <typename Target>
80 class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
81 protected:
82   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
83                     MacroBuilder &Builder) const override {
84     getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
85                      this->PlatformMinVersion);
86   }
87
88 public:
89   DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
90       : OSTargetInfo<Target>(Triple, Opts) {
91     // By default, no TLS, and we whitelist permitted architecture/OS
92     // combinations.
93     this->TLSSupported = false;
94
95     if (Triple.isMacOSX())
96       this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
97     else if (Triple.isiOS()) {
98       // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
99       // 32-bit simulator from 10 onwards.
100       if (Triple.isArch64Bit())
101         this->TLSSupported = !Triple.isOSVersionLT(8);
102       else if (Triple.isArch32Bit()) {
103         if (!Triple.isSimulatorEnvironment())
104           this->TLSSupported = !Triple.isOSVersionLT(9);
105         else
106           this->TLSSupported = !Triple.isOSVersionLT(10);
107       }
108     } else if (Triple.isWatchOS()) {
109       if (!Triple.isSimulatorEnvironment())
110         this->TLSSupported = !Triple.isOSVersionLT(2);
111       else
112         this->TLSSupported = !Triple.isOSVersionLT(3);
113     }
114
115     this->MCountName = "\01mcount";
116   }
117
118   std::string isValidSectionSpecifier(StringRef SR) const override {
119     // Let MCSectionMachO validate this.
120     StringRef Segment, Section;
121     unsigned TAA, StubSize;
122     bool HasTAA;
123     return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
124                                                        TAA, HasTAA, StubSize);
125   }
126
127   const char *getStaticInitSectionSpecifier() const override {
128     // FIXME: We should return 0 when building kexts.
129     return "__TEXT,__StaticInit,regular,pure_instructions";
130   }
131
132   /// Darwin does not support protected visibility.  Darwin's "default"
133   /// is very similar to ELF's "protected";  Darwin requires a "weak"
134   /// attribute on declarations that can be dynamically replaced.
135   bool hasProtectedVisibility() const override { return false; }
136
137   TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth,
138                                              bool IsSigned) const final {
139     // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`.
140     return BitWidth == 64
141                ? (IsSigned ? TargetInfo::SignedLongLong
142                            : TargetInfo::UnsignedLongLong)
143                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
144   }
145 };
146
147 // DragonFlyBSD Target
148 template <typename Target>
149 class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo
150     : public OSTargetInfo<Target> {
151 protected:
152   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
153                     MacroBuilder &Builder) const override {
154     // DragonFly defines; list based off of gcc output
155     Builder.defineMacro("__DragonFly__");
156     Builder.defineMacro("__DragonFly_cc_version", "100001");
157     Builder.defineMacro("__ELF__");
158     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
159     Builder.defineMacro("__tune_i386__");
160     DefineStd(Builder, "unix", Opts);
161   }
162
163 public:
164   DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
165       : OSTargetInfo<Target>(Triple, Opts) {
166     switch (Triple.getArch()) {
167     default:
168     case llvm::Triple::x86:
169     case llvm::Triple::x86_64:
170       this->MCountName = ".mcount";
171       break;
172     }
173   }
174 };
175
176 #ifndef FREEBSD_CC_VERSION
177 #define FREEBSD_CC_VERSION 0U
178 #endif
179
180 // FreeBSD Target
181 template <typename Target>
182 class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
183 protected:
184   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
185                     MacroBuilder &Builder) const override {
186     // FreeBSD defines; list based off of gcc output
187
188     unsigned Release = Triple.getOSMajorVersion();
189     if (Release == 0U)
190       Release = 8U;
191     unsigned CCVersion = FREEBSD_CC_VERSION;
192     if (CCVersion == 0U)
193       CCVersion = Release * 100000U + 1U;
194
195     Builder.defineMacro("__FreeBSD__", Twine(Release));
196     Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
197     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
198     DefineStd(Builder, "unix", Opts);
199     Builder.defineMacro("__ELF__");
200
201     // On FreeBSD, wchar_t contains the number of the code point as
202     // used by the character set of the locale. These character sets are
203     // not necessarily a superset of ASCII.
204     //
205     // FIXME: This is wrong; the macro refers to the numerical values
206     // of wchar_t *literals*, which are not locale-dependent. However,
207     // FreeBSD systems apparently depend on us getting this wrong, and
208     // setting this to 1 is conforming even if all the basic source
209     // character literals have the same encoding as char and wchar_t.
210     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
211   }
212
213 public:
214   FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
215       : OSTargetInfo<Target>(Triple, Opts) {
216     switch (Triple.getArch()) {
217     default:
218     case llvm::Triple::x86:
219     case llvm::Triple::x86_64:
220       this->MCountName = ".mcount";
221       break;
222     case llvm::Triple::mips:
223     case llvm::Triple::mipsel:
224     case llvm::Triple::ppc:
225     case llvm::Triple::ppc64:
226     case llvm::Triple::ppc64le:
227       this->MCountName = "_mcount";
228       break;
229     case llvm::Triple::arm:
230       this->MCountName = "__mcount";
231       break;
232     }
233   }
234 };
235
236 // GNU/kFreeBSD Target
237 template <typename Target>
238 class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> {
239 protected:
240   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
241                     MacroBuilder &Builder) const override {
242     // GNU/kFreeBSD defines; list based off of gcc output
243
244     DefineStd(Builder, "unix", Opts);
245     Builder.defineMacro("__FreeBSD_kernel__");
246     Builder.defineMacro("__GLIBC__");
247     Builder.defineMacro("__ELF__");
248     if (Opts.POSIXThreads)
249       Builder.defineMacro("_REENTRANT");
250     if (Opts.CPlusPlus)
251       Builder.defineMacro("_GNU_SOURCE");
252   }
253
254 public:
255   KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
256       : OSTargetInfo<Target>(Triple, Opts) {}
257 };
258
259 // Haiku Target
260 template <typename Target>
261 class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> {
262 protected:
263   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
264                     MacroBuilder &Builder) const override {
265     // Haiku defines; list based off of gcc output
266     Builder.defineMacro("__HAIKU__");
267     Builder.defineMacro("__ELF__");
268     DefineStd(Builder, "unix", Opts);
269     if (this->HasFloat128) 
270       Builder.defineMacro("__FLOAT128__");
271   }
272
273 public:
274   HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
275       : OSTargetInfo<Target>(Triple, Opts) {
276     this->SizeType = TargetInfo::UnsignedLong;
277     this->IntPtrType = TargetInfo::SignedLong;
278     this->PtrDiffType = TargetInfo::SignedLong;
279     this->ProcessIDType = TargetInfo::SignedLong;
280     this->TLSSupported = false;
281     switch (Triple.getArch()) {
282     default:
283       break;
284     case llvm::Triple::x86:
285     case llvm::Triple::x86_64:
286       this->HasFloat128 = true;
287       break;
288     }
289   }
290 };
291
292 // Hurd target
293 template <typename Target>
294 class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> {
295 protected:
296   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
297                     MacroBuilder &Builder) const override {
298     // Hurd defines; list based off of gcc output.
299     DefineStd(Builder, "unix", Opts);
300     Builder.defineMacro("__GNU__");
301     Builder.defineMacro("__gnu_hurd__");
302     Builder.defineMacro("__MACH__");
303     Builder.defineMacro("__GLIBC__");
304     Builder.defineMacro("__ELF__");
305     if (Opts.POSIXThreads)
306       Builder.defineMacro("_REENTRANT");
307     if (Opts.CPlusPlus)
308       Builder.defineMacro("_GNU_SOURCE");
309   }
310 public:
311   HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
312       : OSTargetInfo<Target>(Triple, Opts) {}
313 };
314
315 // Minix Target
316 template <typename Target>
317 class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> {
318 protected:
319   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
320                     MacroBuilder &Builder) const override {
321     // Minix defines
322
323     Builder.defineMacro("__minix", "3");
324     Builder.defineMacro("_EM_WSIZE", "4");
325     Builder.defineMacro("_EM_PSIZE", "4");
326     Builder.defineMacro("_EM_SSIZE", "2");
327     Builder.defineMacro("_EM_LSIZE", "4");
328     Builder.defineMacro("_EM_FSIZE", "4");
329     Builder.defineMacro("_EM_DSIZE", "8");
330     Builder.defineMacro("__ELF__");
331     DefineStd(Builder, "unix", Opts);
332   }
333
334 public:
335   MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
336       : OSTargetInfo<Target>(Triple, Opts) {}
337 };
338
339 // Linux target
340 template <typename Target>
341 class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
342 protected:
343   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
344                     MacroBuilder &Builder) const override {
345     // Linux defines; list based off of gcc output
346     DefineStd(Builder, "unix", Opts);
347     DefineStd(Builder, "linux", Opts);
348     Builder.defineMacro("__ELF__");
349     if (Triple.isAndroid()) {
350       Builder.defineMacro("__ANDROID__", "1");
351       unsigned Maj, Min, Rev;
352       Triple.getEnvironmentVersion(Maj, Min, Rev);
353       this->PlatformName = "android";
354       this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
355       if (Maj)
356         Builder.defineMacro("__ANDROID_API__", Twine(Maj));
357     } else {
358         Builder.defineMacro("__gnu_linux__");
359     }
360     if (Opts.POSIXThreads)
361       Builder.defineMacro("_REENTRANT");
362     if (Opts.CPlusPlus)
363       Builder.defineMacro("_GNU_SOURCE");
364     if (this->HasFloat128)
365       Builder.defineMacro("__FLOAT128__");
366   }
367
368 public:
369   LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
370       : OSTargetInfo<Target>(Triple, Opts) {
371     this->WIntType = TargetInfo::UnsignedInt;
372
373     switch (Triple.getArch()) {
374     default:
375       break;
376     case llvm::Triple::mips:
377     case llvm::Triple::mipsel:
378     case llvm::Triple::mips64:
379     case llvm::Triple::mips64el:
380     case llvm::Triple::ppc:
381     case llvm::Triple::ppc64:
382     case llvm::Triple::ppc64le:
383       this->MCountName = "_mcount";
384       break;
385     case llvm::Triple::x86:
386     case llvm::Triple::x86_64:
387       this->HasFloat128 = true;
388       break;
389     }
390   }
391
392   const char *getStaticInitSectionSpecifier() const override {
393     return ".text.startup";
394   }
395 };
396
397 // NetBSD Target
398 template <typename Target>
399 class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {
400 protected:
401   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
402                     MacroBuilder &Builder) const override {
403     // NetBSD defines; list based off of gcc output
404     Builder.defineMacro("__NetBSD__");
405     Builder.defineMacro("__unix__");
406     Builder.defineMacro("__ELF__");
407     if (Opts.POSIXThreads)
408       Builder.defineMacro("_REENTRANT");
409   }
410
411 public:
412   NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
413       : OSTargetInfo<Target>(Triple, Opts) {
414     this->MCountName = "__mcount";
415   }
416 };
417
418 // OpenBSD Target
419 template <typename Target>
420 class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
421 protected:
422   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
423                     MacroBuilder &Builder) const override {
424     // OpenBSD defines; list based off of gcc output
425
426     Builder.defineMacro("__OpenBSD__");
427     DefineStd(Builder, "unix", Opts);
428     Builder.defineMacro("__ELF__");
429     if (Opts.POSIXThreads)
430       Builder.defineMacro("_REENTRANT");
431     if (this->HasFloat128)
432       Builder.defineMacro("__FLOAT128__");
433   }
434
435 public:
436   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
437       : OSTargetInfo<Target>(Triple, Opts) {
438     switch (Triple.getArch()) {
439     case llvm::Triple::x86:
440     case llvm::Triple::x86_64:
441       this->HasFloat128 = true;
442       LLVM_FALLTHROUGH;
443     default:
444       this->MCountName = "__mcount";
445       break;
446     case llvm::Triple::mips64:
447     case llvm::Triple::mips64el:
448     case llvm::Triple::ppc:
449     case llvm::Triple::sparcv9:
450       this->MCountName = "_mcount";
451       break;
452     }
453   }
454 };
455
456 // PSP Target
457 template <typename Target>
458 class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
459 protected:
460   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
461                     MacroBuilder &Builder) const override {
462     // PSP defines; list based on the output of the pspdev gcc toolchain.
463     Builder.defineMacro("PSP");
464     Builder.defineMacro("_PSP");
465     Builder.defineMacro("__psp__");
466     Builder.defineMacro("__ELF__");
467   }
468
469 public:
470   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
471 };
472
473 // PS3 PPU Target
474 template <typename Target>
475 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
476 protected:
477   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
478                     MacroBuilder &Builder) const override {
479     // PS3 PPU defines.
480     Builder.defineMacro("__PPC__");
481     Builder.defineMacro("__PPU__");
482     Builder.defineMacro("__CELLOS_LV2__");
483     Builder.defineMacro("__ELF__");
484     Builder.defineMacro("__LP32__");
485     Builder.defineMacro("_ARCH_PPC64");
486     Builder.defineMacro("__powerpc64__");
487   }
488
489 public:
490   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
491       : OSTargetInfo<Target>(Triple, Opts) {
492     this->LongWidth = this->LongAlign = 32;
493     this->PointerWidth = this->PointerAlign = 32;
494     this->IntMaxType = TargetInfo::SignedLongLong;
495     this->Int64Type = TargetInfo::SignedLongLong;
496     this->SizeType = TargetInfo::UnsignedInt;
497     this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
498   }
499 };
500
501 template <typename Target>
502 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
503 protected:
504   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
505                     MacroBuilder &Builder) const override {
506     Builder.defineMacro("__FreeBSD__", "9");
507     Builder.defineMacro("__FreeBSD_cc_version", "900001");
508     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
509     DefineStd(Builder, "unix", Opts);
510     Builder.defineMacro("__ELF__");
511     Builder.defineMacro("__ORBIS__");
512   }
513
514 public:
515   PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
516       : OSTargetInfo<Target>(Triple, Opts) {
517     this->WCharType = TargetInfo::UnsignedShort;
518
519     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
520     this->MaxTLSAlign = 256;
521
522     // On PS4, do not honor explicit bit field alignment,
523     // as in "__attribute__((aligned(2))) int b : 1;".
524     this->UseExplicitBitFieldAlignment = false;
525
526     switch (Triple.getArch()) {
527     default:
528     case llvm::Triple::x86_64:
529       this->MCountName = ".mcount";
530       this->NewAlign = 256;
531       break;
532     }
533   }
534 };
535
536 // RTEMS Target
537 template <typename Target>
538 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> {
539 protected:
540   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
541                     MacroBuilder &Builder) const override {
542     // RTEMS defines; list based off of gcc output
543
544     Builder.defineMacro("__rtems__");
545     Builder.defineMacro("__ELF__");
546     if (Opts.CPlusPlus)
547       Builder.defineMacro("_GNU_SOURCE");
548   }
549
550 public:
551   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
552       : OSTargetInfo<Target>(Triple, Opts) {
553     switch (Triple.getArch()) {
554     default:
555     case llvm::Triple::x86:
556       // this->MCountName = ".mcount";
557       break;
558     case llvm::Triple::mips:
559     case llvm::Triple::mipsel:
560     case llvm::Triple::ppc:
561     case llvm::Triple::ppc64:
562     case llvm::Triple::ppc64le:
563       // this->MCountName = "_mcount";
564       break;
565     case llvm::Triple::arm:
566       // this->MCountName = "__mcount";
567       break;
568     }
569   }
570 };
571
572 // Solaris target
573 template <typename Target>
574 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> {
575 protected:
576   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
577                     MacroBuilder &Builder) const override {
578     DefineStd(Builder, "sun", Opts);
579     DefineStd(Builder, "unix", Opts);
580     Builder.defineMacro("__ELF__");
581     Builder.defineMacro("__svr4__");
582     Builder.defineMacro("__SVR4");
583     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
584     // newer, but to 500 for everything else.  feature_test.h has a check to
585     // ensure that you are not using C99 with an old version of X/Open or C89
586     // with a new version.
587     if (Opts.C99)
588       Builder.defineMacro("_XOPEN_SOURCE", "600");
589     else
590       Builder.defineMacro("_XOPEN_SOURCE", "500");
591     if (Opts.CPlusPlus)
592       Builder.defineMacro("__C99FEATURES__");
593     Builder.defineMacro("_LARGEFILE_SOURCE");
594     Builder.defineMacro("_LARGEFILE64_SOURCE");
595     Builder.defineMacro("__EXTENSIONS__");
596     if (Opts.POSIXThreads)
597       Builder.defineMacro("_REENTRANT");
598     if (this->HasFloat128)
599       Builder.defineMacro("__FLOAT128__");
600   }
601
602 public:
603   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
604       : OSTargetInfo<Target>(Triple, Opts) {
605     // FIXME: WIntType should be SignedLong
606     switch (Triple.getArch()) {
607     default:
608       break;
609     case llvm::Triple::x86:
610     case llvm::Triple::x86_64:
611       this->HasFloat128 = true;
612       break;
613     }
614   }
615 };
616
617 // Windows target
618 template <typename Target>
619 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
620 protected:
621   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
622                     MacroBuilder &Builder) const override {
623     Builder.defineMacro("_WIN32");
624     if (Triple.isArch64Bit())
625       Builder.defineMacro("_WIN64");
626     if (Triple.isWindowsGNUEnvironment())
627       addMinGWDefines(Triple, Opts, Builder);
628
629   }
630   void getVisualStudioDefines(const LangOptions &Opts,
631                               MacroBuilder &Builder) const {
632     if (Opts.CPlusPlus) {
633       if (Opts.RTTIData)
634         Builder.defineMacro("_CPPRTTI");
635
636       if (Opts.CXXExceptions)
637         Builder.defineMacro("_CPPUNWIND");
638     }
639
640     if (Opts.Bool)
641       Builder.defineMacro("__BOOL_DEFINED");
642
643     if (!Opts.CharIsSigned)
644       Builder.defineMacro("_CHAR_UNSIGNED");
645
646     // FIXME: POSIXThreads isn't exactly the option this should be defined for,
647     //        but it works for now.
648     if (Opts.POSIXThreads)
649       Builder.defineMacro("_MT");
650
651     if (Opts.MSCompatibilityVersion) {
652       Builder.defineMacro("_MSC_VER",
653                           Twine(Opts.MSCompatibilityVersion / 100000));
654       Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
655       // FIXME We cannot encode the revision information into 32-bits
656       Builder.defineMacro("_MSC_BUILD", Twine(1));
657
658       if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
659         Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
660
661       if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
662         if (Opts.CPlusPlus2a)
663           Builder.defineMacro("_MSVC_LANG", "201704L");
664         else if (Opts.CPlusPlus17)
665           Builder.defineMacro("_MSVC_LANG", "201703L");
666         else if (Opts.CPlusPlus14)
667           Builder.defineMacro("_MSVC_LANG", "201402L");
668       }
669     }
670
671     if (Opts.MicrosoftExt) {
672       Builder.defineMacro("_MSC_EXTENSIONS");
673
674       if (Opts.CPlusPlus11) {
675         Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
676         Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
677         Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
678       }
679     }
680
681     Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
682   }
683
684 public:
685   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
686       : OSTargetInfo<Target>(Triple, Opts) {
687     this->WCharType = TargetInfo::UnsignedShort;
688     this->WIntType = TargetInfo::UnsignedShort;
689   }
690 };
691
692 template <typename Target>
693 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
694 protected:
695   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
696                     MacroBuilder &Builder) const override {
697     if (Opts.POSIXThreads)
698       Builder.defineMacro("_REENTRANT");
699     if (Opts.CPlusPlus)
700       Builder.defineMacro("_GNU_SOURCE");
701
702     DefineStd(Builder, "unix", Opts);
703     Builder.defineMacro("__ELF__");
704     Builder.defineMacro("__native_client__");
705   }
706
707 public:
708   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
709       : OSTargetInfo<Target>(Triple, Opts) {
710     this->LongAlign = 32;
711     this->LongWidth = 32;
712     this->PointerAlign = 32;
713     this->PointerWidth = 32;
714     this->IntMaxType = TargetInfo::SignedLongLong;
715     this->Int64Type = TargetInfo::SignedLongLong;
716     this->DoubleAlign = 64;
717     this->LongDoubleWidth = 64;
718     this->LongDoubleAlign = 64;
719     this->LongLongWidth = 64;
720     this->LongLongAlign = 64;
721     this->SizeType = TargetInfo::UnsignedInt;
722     this->PtrDiffType = TargetInfo::SignedInt;
723     this->IntPtrType = TargetInfo::SignedInt;
724     // RegParmMax is inherited from the underlying architecture.
725     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
726     if (Triple.getArch() == llvm::Triple::arm) {
727       // Handled in ARM's setABI().
728     } else if (Triple.getArch() == llvm::Triple::x86) {
729       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128");
730     } else if (Triple.getArch() == llvm::Triple::x86_64) {
731       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128");
732     } else if (Triple.getArch() == llvm::Triple::mipsel) {
733       // Handled on mips' setDataLayout.
734     } else {
735       assert(Triple.getArch() == llvm::Triple::le32);
736       this->resetDataLayout("e-p:32:32-i64:64");
737     }
738   }
739 };
740
741 // Fuchsia Target
742 template <typename Target>
743 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> {
744 protected:
745   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
746                     MacroBuilder &Builder) const override {
747     Builder.defineMacro("__Fuchsia__");
748     Builder.defineMacro("__ELF__");
749     if (Opts.POSIXThreads)
750       Builder.defineMacro("_REENTRANT");
751     // Required by the libc++ locale support.
752     if (Opts.CPlusPlus)
753       Builder.defineMacro("_GNU_SOURCE");
754   }
755
756 public:
757   FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
758       : OSTargetInfo<Target>(Triple, Opts) {
759     this->MCountName = "__mcount";
760   }
761 };
762
763 // WebAssembly target
764 template <typename Target>
765 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
766     : public OSTargetInfo<Target> {
767   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
768                     MacroBuilder &Builder) const final {
769     // A common platform macro.
770     if (Opts.POSIXThreads)
771       Builder.defineMacro("_REENTRANT");
772     // Follow g++ convention and predefine _GNU_SOURCE for C++.
773     if (Opts.CPlusPlus)
774       Builder.defineMacro("_GNU_SOURCE");
775   }
776
777 public:
778   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
779                                    const TargetOptions &Opts)
780       : OSTargetInfo<Target>(Triple, Opts) {
781     this->MCountName = "__mcount";
782     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
783   }
784 };
785
786 } // namespace targets
787 } // namespace clang
788 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H