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