1 //===--- OSTargets.h - Declare OS target feature support --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares OS specific TargetInfo types. 10 //===----------------------------------------------------------------------===// 11 12 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H 13 #define LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H 14 15 #include "Targets.h" 16 #include "llvm/MC/MCSectionMachO.h" 17 18 namespace clang { 19 namespace targets { 20 21 template <typename TgtInfo> 22 class LLVM_LIBRARY_VISIBILITY OSTargetInfo : public TgtInfo { 23 protected: 24 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 25 MacroBuilder &Builder) const = 0; 26 27 public: OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)28 OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 29 : TgtInfo(Triple, Opts) {} 30 getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)31 void getTargetDefines(const LangOptions &Opts, 32 MacroBuilder &Builder) const override { 33 TgtInfo::getTargetDefines(Opts, Builder); 34 getOSDefines(Opts, TgtInfo::getTriple(), Builder); 35 } 36 }; 37 38 // CloudABI Target 39 template <typename Target> 40 class LLVM_LIBRARY_VISIBILITY CloudABITargetInfo : public OSTargetInfo<Target> { 41 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)42 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 43 MacroBuilder &Builder) const override { 44 Builder.defineMacro("__CloudABI__"); 45 Builder.defineMacro("__ELF__"); 46 47 // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t. 48 Builder.defineMacro("__STDC_ISO_10646__", "201206L"); 49 Builder.defineMacro("__STDC_UTF_16__"); 50 Builder.defineMacro("__STDC_UTF_32__"); 51 } 52 53 public: CloudABITargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)54 CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 55 : OSTargetInfo<Target>(Triple, Opts) {} 56 }; 57 58 // Ananas target 59 template <typename Target> 60 class LLVM_LIBRARY_VISIBILITY AnanasTargetInfo : public OSTargetInfo<Target> { 61 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)62 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 63 MacroBuilder &Builder) const override { 64 // Ananas defines 65 Builder.defineMacro("__Ananas__"); 66 Builder.defineMacro("__ELF__"); 67 } 68 69 public: AnanasTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)70 AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 71 : OSTargetInfo<Target>(Triple, Opts) {} 72 }; 73 74 void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 75 const llvm::Triple &Triple, StringRef &PlatformName, 76 VersionTuple &PlatformMinVersion); 77 78 template <typename Target> 79 class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> { 80 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)81 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 82 MacroBuilder &Builder) const override { 83 getDarwinDefines(Builder, Opts, Triple, this->PlatformName, 84 this->PlatformMinVersion); 85 } 86 87 public: DarwinTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)88 DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 89 : OSTargetInfo<Target>(Triple, Opts) { 90 // By default, no TLS, and we list permitted architecture/OS 91 // combinations. 92 this->TLSSupported = false; 93 94 if (Triple.isMacOSX()) 95 this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7); 96 else if (Triple.isiOS()) { 97 // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards, 98 // 32-bit simulator from 10 onwards. 99 if (Triple.isArch64Bit()) 100 this->TLSSupported = !Triple.isOSVersionLT(8); 101 else if (Triple.isArch32Bit()) { 102 if (!Triple.isSimulatorEnvironment()) 103 this->TLSSupported = !Triple.isOSVersionLT(9); 104 else 105 this->TLSSupported = !Triple.isOSVersionLT(10); 106 } 107 } else if (Triple.isWatchOS()) { 108 if (!Triple.isSimulatorEnvironment()) 109 this->TLSSupported = !Triple.isOSVersionLT(2); 110 else 111 this->TLSSupported = !Triple.isOSVersionLT(3); 112 } 113 114 this->MCountName = "\01mcount"; 115 } 116 isValidSectionSpecifier(StringRef SR)117 std::string isValidSectionSpecifier(StringRef SR) const override { 118 // Let MCSectionMachO validate this. 119 StringRef Segment, Section; 120 unsigned TAA, StubSize; 121 bool HasTAA; 122 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, 123 TAA, HasTAA, StubSize); 124 } 125 getStaticInitSectionSpecifier()126 const char *getStaticInitSectionSpecifier() const override { 127 // FIXME: We should return 0 when building kexts. 128 return "__TEXT,__StaticInit,regular,pure_instructions"; 129 } 130 131 /// Darwin does not support protected visibility. Darwin's "default" 132 /// is very similar to ELF's "protected"; Darwin requires a "weak" 133 /// attribute on declarations that can be dynamically replaced. hasProtectedVisibility()134 bool hasProtectedVisibility() const override { return false; } 135 getExnObjectAlignment()136 unsigned getExnObjectAlignment() const override { 137 // Older versions of libc++abi guarantee an alignment of only 8-bytes for 138 // exception objects because of a bug in __cxa_exception that was 139 // eventually fixed in r319123. 140 llvm::VersionTuple MinVersion; 141 const llvm::Triple &T = this->getTriple(); 142 143 // Compute the earliest OS versions that have the fix to libc++abi. 144 switch (T.getOS()) { 145 case llvm::Triple::Darwin: 146 case llvm::Triple::MacOSX: // Earliest supporting version is 10.14. 147 MinVersion = llvm::VersionTuple(10U, 14U); 148 break; 149 case llvm::Triple::IOS: 150 case llvm::Triple::TvOS: // Earliest supporting version is 12.0.0. 151 MinVersion = llvm::VersionTuple(12U); 152 break; 153 case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0. 154 MinVersion = llvm::VersionTuple(5U); 155 break; 156 default: 157 // Conservatively return 8 bytes if OS is unknown. 158 return 64; 159 } 160 161 unsigned Major, Minor, Micro; 162 T.getOSVersion(Major, Minor, Micro); 163 if (llvm::VersionTuple(Major, Minor, Micro) < MinVersion) 164 return 64; 165 return OSTargetInfo<Target>::getExnObjectAlignment(); 166 } 167 getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned)168 TargetInfo::IntType getLeastIntTypeByWidth(unsigned BitWidth, 169 bool IsSigned) const final { 170 // Darwin uses `long long` for `int_least64_t` and `int_fast64_t`. 171 return BitWidth == 64 172 ? (IsSigned ? TargetInfo::SignedLongLong 173 : TargetInfo::UnsignedLongLong) 174 : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); 175 } 176 }; 177 178 // DragonFlyBSD Target 179 template <typename Target> 180 class LLVM_LIBRARY_VISIBILITY DragonFlyBSDTargetInfo 181 : public OSTargetInfo<Target> { 182 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)183 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 184 MacroBuilder &Builder) const override { 185 // DragonFly defines; list based off of gcc output 186 Builder.defineMacro("__DragonFly__"); 187 Builder.defineMacro("__DragonFly_cc_version", "100001"); 188 Builder.defineMacro("__ELF__"); 189 Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 190 Builder.defineMacro("__tune_i386__"); 191 DefineStd(Builder, "unix", Opts); 192 } 193 194 public: DragonFlyBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)195 DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 196 : OSTargetInfo<Target>(Triple, Opts) { 197 switch (Triple.getArch()) { 198 default: 199 case llvm::Triple::x86: 200 case llvm::Triple::x86_64: 201 this->MCountName = ".mcount"; 202 break; 203 } 204 } 205 }; 206 207 #ifndef FREEBSD_CC_VERSION 208 #define FREEBSD_CC_VERSION 0U 209 #endif 210 211 // FreeBSD Target 212 template <typename Target> 213 class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> { 214 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)215 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 216 MacroBuilder &Builder) const override { 217 // FreeBSD defines; list based off of gcc output 218 219 unsigned Release = Triple.getOSMajorVersion(); 220 if (Release == 0U) 221 Release = 8U; 222 unsigned CCVersion = FREEBSD_CC_VERSION; 223 if (CCVersion == 0U) 224 CCVersion = Release * 100000U + 1U; 225 226 Builder.defineMacro("__FreeBSD__", Twine(Release)); 227 Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion)); 228 Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 229 DefineStd(Builder, "unix", Opts); 230 Builder.defineMacro("__ELF__"); 231 232 // On FreeBSD, wchar_t contains the number of the code point as 233 // used by the character set of the locale. These character sets are 234 // not necessarily a superset of ASCII. 235 // 236 // FIXME: This is wrong; the macro refers to the numerical values 237 // of wchar_t *literals*, which are not locale-dependent. However, 238 // FreeBSD systems apparently depend on us getting this wrong, and 239 // setting this to 1 is conforming even if all the basic source 240 // character literals have the same encoding as char and wchar_t. 241 Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1"); 242 } 243 244 public: FreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)245 FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 246 : OSTargetInfo<Target>(Triple, Opts) { 247 switch (Triple.getArch()) { 248 default: 249 case llvm::Triple::x86: 250 case llvm::Triple::x86_64: 251 this->MCountName = ".mcount"; 252 break; 253 case llvm::Triple::mips: 254 case llvm::Triple::mipsel: 255 case llvm::Triple::ppc: 256 case llvm::Triple::ppc64: 257 case llvm::Triple::ppc64le: 258 this->MCountName = "_mcount"; 259 break; 260 case llvm::Triple::arm: 261 this->MCountName = "__mcount"; 262 break; 263 } 264 } 265 }; 266 267 // GNU/kFreeBSD Target 268 template <typename Target> 269 class LLVM_LIBRARY_VISIBILITY KFreeBSDTargetInfo : public OSTargetInfo<Target> { 270 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)271 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 272 MacroBuilder &Builder) const override { 273 // GNU/kFreeBSD defines; list based off of gcc output 274 275 DefineStd(Builder, "unix", Opts); 276 Builder.defineMacro("__FreeBSD_kernel__"); 277 Builder.defineMacro("__GLIBC__"); 278 Builder.defineMacro("__ELF__"); 279 if (Opts.POSIXThreads) 280 Builder.defineMacro("_REENTRANT"); 281 if (Opts.CPlusPlus) 282 Builder.defineMacro("_GNU_SOURCE"); 283 } 284 285 public: KFreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)286 KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 287 : OSTargetInfo<Target>(Triple, Opts) {} 288 }; 289 290 // Haiku Target 291 template <typename Target> 292 class LLVM_LIBRARY_VISIBILITY HaikuTargetInfo : public OSTargetInfo<Target> { 293 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)294 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 295 MacroBuilder &Builder) const override { 296 // Haiku defines; list based off of gcc output 297 Builder.defineMacro("__HAIKU__"); 298 Builder.defineMacro("__ELF__"); 299 DefineStd(Builder, "unix", Opts); 300 if (this->HasFloat128) 301 Builder.defineMacro("__FLOAT128__"); 302 } 303 304 public: HaikuTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)305 HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 306 : OSTargetInfo<Target>(Triple, Opts) { 307 this->SizeType = TargetInfo::UnsignedLong; 308 this->IntPtrType = TargetInfo::SignedLong; 309 this->PtrDiffType = TargetInfo::SignedLong; 310 this->ProcessIDType = TargetInfo::SignedLong; 311 this->TLSSupported = false; 312 switch (Triple.getArch()) { 313 default: 314 break; 315 case llvm::Triple::x86: 316 case llvm::Triple::x86_64: 317 this->HasFloat128 = true; 318 break; 319 } 320 } 321 }; 322 323 // Hurd target 324 template <typename Target> 325 class LLVM_LIBRARY_VISIBILITY HurdTargetInfo : public OSTargetInfo<Target> { 326 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)327 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 328 MacroBuilder &Builder) const override { 329 // Hurd defines; list based off of gcc output. 330 DefineStd(Builder, "unix", Opts); 331 Builder.defineMacro("__GNU__"); 332 Builder.defineMacro("__gnu_hurd__"); 333 Builder.defineMacro("__MACH__"); 334 Builder.defineMacro("__GLIBC__"); 335 Builder.defineMacro("__ELF__"); 336 if (Opts.POSIXThreads) 337 Builder.defineMacro("_REENTRANT"); 338 if (Opts.CPlusPlus) 339 Builder.defineMacro("_GNU_SOURCE"); 340 } 341 public: HurdTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)342 HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 343 : OSTargetInfo<Target>(Triple, Opts) {} 344 }; 345 346 // Minix Target 347 template <typename Target> 348 class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> { 349 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)350 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 351 MacroBuilder &Builder) const override { 352 // Minix defines 353 354 Builder.defineMacro("__minix", "3"); 355 Builder.defineMacro("_EM_WSIZE", "4"); 356 Builder.defineMacro("_EM_PSIZE", "4"); 357 Builder.defineMacro("_EM_SSIZE", "2"); 358 Builder.defineMacro("_EM_LSIZE", "4"); 359 Builder.defineMacro("_EM_FSIZE", "4"); 360 Builder.defineMacro("_EM_DSIZE", "8"); 361 Builder.defineMacro("__ELF__"); 362 DefineStd(Builder, "unix", Opts); 363 } 364 365 public: MinixTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)366 MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 367 : OSTargetInfo<Target>(Triple, Opts) {} 368 }; 369 370 // Linux target 371 template <typename Target> 372 class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> { 373 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)374 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 375 MacroBuilder &Builder) const override { 376 // Linux defines; list based off of gcc output 377 DefineStd(Builder, "unix", Opts); 378 DefineStd(Builder, "linux", Opts); 379 Builder.defineMacro("__ELF__"); 380 if (Triple.isAndroid()) { 381 Builder.defineMacro("__ANDROID__", "1"); 382 unsigned Maj, Min, Rev; 383 Triple.getEnvironmentVersion(Maj, Min, Rev); 384 this->PlatformName = "android"; 385 this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); 386 if (Maj) { 387 Builder.defineMacro("__ANDROID_MIN_SDK_VERSION__", Twine(Maj)); 388 // This historical but ambiguous name for the minSdkVersion macro. Keep 389 // defined for compatibility. 390 Builder.defineMacro("__ANDROID_API__", "__ANDROID_MIN_SDK_VERSION__"); 391 } 392 } else { 393 Builder.defineMacro("__gnu_linux__"); 394 } 395 if (Opts.POSIXThreads) 396 Builder.defineMacro("_REENTRANT"); 397 if (Opts.CPlusPlus) 398 Builder.defineMacro("_GNU_SOURCE"); 399 if (this->HasFloat128) 400 Builder.defineMacro("__FLOAT128__"); 401 } 402 403 public: LinuxTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)404 LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 405 : OSTargetInfo<Target>(Triple, Opts) { 406 this->WIntType = TargetInfo::UnsignedInt; 407 408 switch (Triple.getArch()) { 409 default: 410 break; 411 case llvm::Triple::mips: 412 case llvm::Triple::mipsel: 413 case llvm::Triple::mips64: 414 case llvm::Triple::mips64el: 415 case llvm::Triple::ppc: 416 case llvm::Triple::ppc64: 417 case llvm::Triple::ppc64le: 418 this->MCountName = "_mcount"; 419 break; 420 case llvm::Triple::x86: 421 case llvm::Triple::x86_64: 422 this->HasFloat128 = true; 423 break; 424 } 425 } 426 getStaticInitSectionSpecifier()427 const char *getStaticInitSectionSpecifier() const override { 428 return ".text.startup"; 429 } 430 }; 431 432 // NetBSD Target 433 template <typename Target> 434 class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> { 435 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)436 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 437 MacroBuilder &Builder) const override { 438 // NetBSD defines; list based off of gcc output 439 Builder.defineMacro("__NetBSD__"); 440 Builder.defineMacro("__unix__"); 441 Builder.defineMacro("__ELF__"); 442 if (Opts.POSIXThreads) 443 Builder.defineMacro("_REENTRANT"); 444 } 445 446 public: NetBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)447 NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 448 : OSTargetInfo<Target>(Triple, Opts) { 449 this->MCountName = "__mcount"; 450 } 451 }; 452 453 // OpenBSD Target 454 template <typename Target> 455 class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> { 456 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)457 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 458 MacroBuilder &Builder) const override { 459 // OpenBSD defines; list based off of gcc output 460 461 Builder.defineMacro("__OpenBSD__"); 462 DefineStd(Builder, "unix", Opts); 463 Builder.defineMacro("__ELF__"); 464 if (Opts.POSIXThreads) 465 Builder.defineMacro("_REENTRANT"); 466 if (this->HasFloat128) 467 Builder.defineMacro("__FLOAT128__"); 468 } 469 470 public: OpenBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)471 OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 472 : OSTargetInfo<Target>(Triple, Opts) { 473 this->WCharType = this->WIntType = this->SignedInt; 474 this->IntMaxType = TargetInfo::SignedLongLong; 475 this->Int64Type = TargetInfo::SignedLongLong; 476 switch (Triple.getArch()) { 477 case llvm::Triple::x86: 478 case llvm::Triple::x86_64: 479 this->HasFloat128 = true; 480 LLVM_FALLTHROUGH; 481 default: 482 this->MCountName = "__mcount"; 483 break; 484 case llvm::Triple::mips64: 485 case llvm::Triple::mips64el: 486 case llvm::Triple::ppc: 487 case llvm::Triple::ppc64: 488 case llvm::Triple::ppc64le: 489 case llvm::Triple::sparcv9: 490 this->MCountName = "_mcount"; 491 break; 492 } 493 } 494 }; 495 496 // PSP Target 497 template <typename Target> 498 class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> { 499 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)500 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 501 MacroBuilder &Builder) const override { 502 // PSP defines; list based on the output of the pspdev gcc toolchain. 503 Builder.defineMacro("PSP"); 504 Builder.defineMacro("_PSP"); 505 Builder.defineMacro("__psp__"); 506 Builder.defineMacro("__ELF__"); 507 } 508 509 public: PSPTargetInfo(const llvm::Triple & Triple)510 PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {} 511 }; 512 513 // PS3 PPU Target 514 template <typename Target> 515 class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> { 516 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)517 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 518 MacroBuilder &Builder) const override { 519 // PS3 PPU defines. 520 Builder.defineMacro("__PPC__"); 521 Builder.defineMacro("__PPU__"); 522 Builder.defineMacro("__CELLOS_LV2__"); 523 Builder.defineMacro("__ELF__"); 524 Builder.defineMacro("__LP32__"); 525 Builder.defineMacro("_ARCH_PPC64"); 526 Builder.defineMacro("__powerpc64__"); 527 } 528 529 public: PS3PPUTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)530 PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 531 : OSTargetInfo<Target>(Triple, Opts) { 532 this->LongWidth = this->LongAlign = 32; 533 this->PointerWidth = this->PointerAlign = 32; 534 this->IntMaxType = TargetInfo::SignedLongLong; 535 this->Int64Type = TargetInfo::SignedLongLong; 536 this->SizeType = TargetInfo::UnsignedInt; 537 this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64"); 538 } 539 }; 540 541 template <typename Target> 542 class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> { 543 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)544 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 545 MacroBuilder &Builder) const override { 546 Builder.defineMacro("__FreeBSD__", "9"); 547 Builder.defineMacro("__FreeBSD_cc_version", "900001"); 548 Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 549 DefineStd(Builder, "unix", Opts); 550 Builder.defineMacro("__ELF__"); 551 Builder.defineMacro("__SCE__"); 552 Builder.defineMacro("__ORBIS__"); 553 } 554 555 public: PS4OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)556 PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 557 : OSTargetInfo<Target>(Triple, Opts) { 558 this->WCharType = TargetInfo::UnsignedShort; 559 560 // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits). 561 this->MaxTLSAlign = 256; 562 563 // On PS4, do not honor explicit bit field alignment, 564 // as in "__attribute__((aligned(2))) int b : 1;". 565 this->UseExplicitBitFieldAlignment = false; 566 567 switch (Triple.getArch()) { 568 default: 569 case llvm::Triple::x86_64: 570 this->MCountName = ".mcount"; 571 this->NewAlign = 256; 572 break; 573 } 574 } 575 TargetInfo::CallingConvCheckResult checkCallingConvention(CallingConv CC)576 checkCallingConvention(CallingConv CC) const override { 577 return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error; 578 } 579 }; 580 581 // RTEMS Target 582 template <typename Target> 583 class LLVM_LIBRARY_VISIBILITY RTEMSTargetInfo : public OSTargetInfo<Target> { 584 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)585 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 586 MacroBuilder &Builder) const override { 587 // RTEMS defines; list based off of gcc output 588 589 Builder.defineMacro("__rtems__"); 590 Builder.defineMacro("__ELF__"); 591 if (Opts.CPlusPlus) 592 Builder.defineMacro("_GNU_SOURCE"); 593 } 594 595 public: RTEMSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)596 RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 597 : OSTargetInfo<Target>(Triple, Opts) { 598 switch (Triple.getArch()) { 599 default: 600 case llvm::Triple::x86: 601 // this->MCountName = ".mcount"; 602 break; 603 case llvm::Triple::mips: 604 case llvm::Triple::mipsel: 605 case llvm::Triple::ppc: 606 case llvm::Triple::ppc64: 607 case llvm::Triple::ppc64le: 608 // this->MCountName = "_mcount"; 609 break; 610 case llvm::Triple::arm: 611 // this->MCountName = "__mcount"; 612 break; 613 } 614 } 615 }; 616 617 // Solaris target 618 template <typename Target> 619 class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : public OSTargetInfo<Target> { 620 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)621 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 622 MacroBuilder &Builder) const override { 623 DefineStd(Builder, "sun", Opts); 624 DefineStd(Builder, "unix", Opts); 625 Builder.defineMacro("__ELF__"); 626 Builder.defineMacro("__svr4__"); 627 Builder.defineMacro("__SVR4"); 628 // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and 629 // newer, but to 500 for everything else. feature_test.h has a check to 630 // ensure that you are not using C99 with an old version of X/Open or C89 631 // with a new version. 632 if (Opts.C99) 633 Builder.defineMacro("_XOPEN_SOURCE", "600"); 634 else 635 Builder.defineMacro("_XOPEN_SOURCE", "500"); 636 if (Opts.CPlusPlus) { 637 Builder.defineMacro("__C99FEATURES__"); 638 Builder.defineMacro("_FILE_OFFSET_BITS", "64"); 639 } 640 // GCC restricts the next two to C++. 641 Builder.defineMacro("_LARGEFILE_SOURCE"); 642 Builder.defineMacro("_LARGEFILE64_SOURCE"); 643 Builder.defineMacro("__EXTENSIONS__"); 644 if (Opts.POSIXThreads) 645 Builder.defineMacro("_REENTRANT"); 646 if (this->HasFloat128) 647 Builder.defineMacro("__FLOAT128__"); 648 } 649 650 public: SolarisTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)651 SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 652 : OSTargetInfo<Target>(Triple, Opts) { 653 if (this->PointerWidth == 64) { 654 this->WCharType = this->WIntType = this->SignedInt; 655 } else { 656 this->WCharType = this->WIntType = this->SignedLong; 657 } 658 switch (Triple.getArch()) { 659 default: 660 break; 661 case llvm::Triple::x86: 662 case llvm::Triple::x86_64: 663 this->HasFloat128 = true; 664 break; 665 } 666 } 667 }; 668 669 // AIX Target 670 template <typename Target> 671 class AIXTargetInfo : public OSTargetInfo<Target> { 672 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)673 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 674 MacroBuilder &Builder) const override { 675 DefineStd(Builder, "unix", Opts); 676 Builder.defineMacro("_IBMR2"); 677 Builder.defineMacro("_POWER"); 678 679 Builder.defineMacro("_AIX"); 680 681 if (Opts.EnableAIXExtendedAltivecABI) 682 Builder.defineMacro("__EXTABI__"); 683 684 unsigned Major, Minor, Micro; 685 Triple.getOSVersion(Major, Minor, Micro); 686 687 // Define AIX OS-Version Macros. 688 // Includes logic for legacy versions of AIX; no specific intent to support. 689 std::pair<int, int> OsVersion = {Major, Minor}; 690 if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32"); 691 if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41"); 692 if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43"); 693 if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50"); 694 if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51"); 695 if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52"); 696 if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53"); 697 if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61"); 698 if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71"); 699 if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72"); 700 701 // FIXME: Do not define _LONG_LONG when -fno-long-long is specified. 702 Builder.defineMacro("_LONG_LONG"); 703 704 if (Opts.POSIXThreads) { 705 Builder.defineMacro("_THREAD_SAFE"); 706 } 707 708 if (this->PointerWidth == 64) { 709 Builder.defineMacro("__64BIT__"); 710 } 711 712 // Define _WCHAR_T when it is a fundamental type 713 // (i.e., for C++ without -fno-wchar). 714 if (Opts.CPlusPlus && Opts.WChar) { 715 Builder.defineMacro("_WCHAR_T"); 716 } 717 } 718 719 public: AIXTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)720 AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 721 : OSTargetInfo<Target>(Triple, Opts) { 722 this->TheCXXABI.set(TargetCXXABI::XL); 723 724 if (this->PointerWidth == 64) { 725 this->WCharType = this->UnsignedInt; 726 } else { 727 this->WCharType = this->UnsignedShort; 728 } 729 this->UseZeroLengthBitfieldAlignment = true; 730 } 731 732 // AIX sets FLT_EVAL_METHOD to be 1. getFloatEvalMethod()733 unsigned getFloatEvalMethod() const override { return 1; } hasInt128Type()734 bool hasInt128Type() const override { return false; } 735 defaultsToAIXPowerAlignment()736 bool defaultsToAIXPowerAlignment() const override { return true; } 737 }; 738 739 // z/OS target 740 template <typename Target> 741 class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> { 742 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)743 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 744 MacroBuilder &Builder) const override { 745 // FIXME: _LONG_LONG should not be defined under -std=c89. 746 Builder.defineMacro("_LONG_LONG"); 747 Builder.defineMacro("_OPEN_DEFAULT"); 748 // _UNIX03_WITHDRAWN is required to build libcxx. 749 Builder.defineMacro("_UNIX03_WITHDRAWN"); 750 Builder.defineMacro("__370__"); 751 Builder.defineMacro("__BFP__"); 752 // FIXME: __BOOL__ should not be defined under -std=c89. 753 Builder.defineMacro("__BOOL__"); 754 Builder.defineMacro("__LONGNAME__"); 755 Builder.defineMacro("__MVS__"); 756 Builder.defineMacro("__THW_370__"); 757 Builder.defineMacro("__THW_BIG_ENDIAN__"); 758 Builder.defineMacro("__TOS_390__"); 759 Builder.defineMacro("__TOS_MVS__"); 760 Builder.defineMacro("__XPLINK__"); 761 762 if (this->PointerWidth == 64) 763 Builder.defineMacro("__64BIT__"); 764 765 if (Opts.CPlusPlus) { 766 Builder.defineMacro("__DLL__"); 767 // _XOPEN_SOURCE=600 is required to build libcxx. 768 Builder.defineMacro("_XOPEN_SOURCE", "600"); 769 } 770 771 if (Opts.GNUMode) { 772 Builder.defineMacro("_MI_BUILTIN"); 773 Builder.defineMacro("_EXT"); 774 } 775 776 if (Opts.CPlusPlus && Opts.WChar) { 777 // Macro __wchar_t is defined so that the wchar_t data 778 // type is not declared as a typedef in system headers. 779 Builder.defineMacro("__wchar_t"); 780 } 781 782 this->PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); 783 } 784 785 public: ZOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)786 ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 787 : OSTargetInfo<Target>(Triple, Opts) { 788 this->WCharType = TargetInfo::UnsignedInt; 789 this->UseBitFieldTypeAlignment = false; 790 this->UseZeroLengthBitfieldAlignment = true; 791 this->ZeroLengthBitfieldBoundary = 32; 792 this->MinGlobalAlign = 0; 793 this->DefaultAlignForAttributeAligned = 128; 794 } 795 }; 796 797 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, 798 MacroBuilder &Builder); 799 800 // Windows target 801 template <typename Target> 802 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> { 803 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)804 void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 805 MacroBuilder &Builder) const override { 806 addWindowsDefines(Triple, Opts, Builder); 807 } 808 809 public: WindowsTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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 817 template <typename Target> 818 class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> { 819 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)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 832 public: NaClTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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 869 template <typename Target> 870 class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo<Target> { 871 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)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 883 public: FuchsiaTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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 892 template <typename Target> 893 class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo 894 : public OSTargetInfo<Target> { 895 protected: getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)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 908 public: WebAssemblyOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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 919 template <typename Target> 920 class LLVM_LIBRARY_VISIBILITY WASITargetInfo 921 : public WebAssemblyOSTargetInfo<Target> { getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)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 928 public: WASITargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)929 explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 930 : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {} 931 }; 932 933 // Emscripten target 934 template <typename Target> 935 class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo 936 : public WebAssemblyOSTargetInfo<Target> { getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder)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 } 942 943 public: EmscriptenTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)944 explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 945 : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {} 946 }; 947 948 } // namespace targets 949 } // namespace clang 950 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H 951