brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · e99bbd1 Raw
292 lines · cpp
1//===--- OSTargets.cpp - Implement OS target feature support --------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements OS specific TargetInfo types.10//===----------------------------------------------------------------------===//11 12#include "OSTargets.h"13#include "AArch64.h"14#include "clang/Basic/MacroBuilder.h"15#include "llvm/ADT/StringRef.h"16 17using namespace clang;18using namespace clang::targets;19 20namespace clang {21namespace targets {22 23void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,24                          const llvm::Triple &Triple) {25  Builder.defineMacro("__APPLE_CC__", "6000");26  Builder.defineMacro("__APPLE__");27 28  // AddressSanitizer doesn't play well with source fortification, which is on29  // by default on Apple platforms.30  if (Opts.Sanitize.has(SanitizerKind::Address))31    Builder.defineMacro("_FORTIFY_SOURCE", "0");32 33  // Apple defines __weak, __strong, and __unsafe_unretained even in C mode.34  if (!Opts.ObjC) {35    // __weak is always defined, for use in blocks and with objc pointers.36    Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");37    Builder.defineMacro("__strong", "");38    Builder.defineMacro("__unsafe_unretained", "");39  }40 41  if (Opts.Static)42    Builder.defineMacro("__STATIC__");43  else44    Builder.defineMacro("__DYNAMIC__");45 46  if (Opts.POSIXThreads)47    Builder.defineMacro("_REENTRANT");48 49  // __MACH__ originally meant "will run in a Mach kernel based OS", but it has50  // come to also mean "uses Apple Mach-O linking/symbol visibility semantics".51  // Notably libc++'s __configuration/platform.h and Swift's shims/Visibility.h52  // take __MACH__ for the more general meaning.53  if (Triple.isAppleMachO() || Triple.isOSDarwin())54    Builder.defineMacro("__MACH__");55}56 57void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,58                      const llvm::Triple &Triple, StringRef &PlatformName,59                      VersionTuple &PlatformMinVersion) {60  getAppleMachODefines(Builder, Opts, Triple);61 62  // Darwin's libc doesn't have threads.h63  Builder.defineMacro("__STDC_NO_THREADS__");64 65  // Get the platform type and version number from the triple.66  VersionTuple OsVersion;67  if (Triple.isMacOSX()) {68    Triple.getMacOSXVersion(OsVersion);69    PlatformName = "macos";70  } else {71    OsVersion = Triple.getOSVersion();72    PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());73    if (PlatformName == "ios" && Triple.isMacCatalystEnvironment())74      PlatformName = "maccatalyst";75  }76 77  // If -target arch-pc-win32-macho option specified, we're78  // generating code for Win32 ABI. No need to emit79  // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.80  if (PlatformName == "win32") {81    PlatformMinVersion = OsVersion;82    return;83  }84 85  assert(OsVersion < VersionTuple(100) && "Invalid version!");86  char Str[7];87  if (Triple.isMacOSX() && OsVersion < VersionTuple(10, 10)) {88    Str[0] = '0' + (OsVersion.getMajor() / 10);89    Str[1] = '0' + (OsVersion.getMajor() % 10);90    Str[2] = '0' + std::min(OsVersion.getMinor().value_or(0), 9U);91    Str[3] = '0' + std::min(OsVersion.getSubminor().value_or(0), 9U);92    Str[4] = '\0';93  } else if (!Triple.isMacOSX() && OsVersion.getMajor() < 10) {94    Str[0] = '0' + OsVersion.getMajor();95    Str[1] = '0' + (OsVersion.getMinor().value_or(0) / 10);96    Str[2] = '0' + (OsVersion.getMinor().value_or(0) % 10);97    Str[3] = '0' + (OsVersion.getSubminor().value_or(0) / 10);98    Str[4] = '0' + (OsVersion.getSubminor().value_or(0) % 10);99    Str[5] = '\0';100  } else {101    // Handle versions >= 10.102    Str[0] = '0' + (OsVersion.getMajor() / 10);103    Str[1] = '0' + (OsVersion.getMajor() % 10);104    Str[2] = '0' + (OsVersion.getMinor().value_or(0) / 10);105    Str[3] = '0' + (OsVersion.getMinor().value_or(0) % 10);106    Str[4] = '0' + (OsVersion.getSubminor().value_or(0) / 10);107    Str[5] = '0' + (OsVersion.getSubminor().value_or(0) % 10);108    Str[6] = '\0';109  }110 111  // Set the appropriate OS version define.112  if (Triple.isTvOS()) {113    Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);114  } else if (Triple.isiOS()) {115    Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);116  } else if (Triple.isWatchOS()) {117    Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);118  } else if (Triple.isDriverKit()) {119    assert(OsVersion.getMinor().value_or(0) < 100 &&120           OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");121    Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str);122  } else if (Triple.isMacOSX()) {123    Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);124  }125 126  if (Triple.isOSDarwin()) {127    // Any darwin OS defines a general darwin OS version macro in addition128    // to the other OS specific macros.129    assert(OsVersion.getMinor().value_or(0) < 100 &&130           OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");131    Builder.defineMacro("__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__", Str);132  }133 134  PlatformMinVersion = OsVersion;135}136 137static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,138                            MacroBuilder &Builder) {139  DefineStd(Builder, "WIN32", Opts);140  DefineStd(Builder, "WINNT", Opts);141  if (Triple.isArch64Bit()) {142    DefineStd(Builder, "WIN64", Opts);143    Builder.defineMacro("__MINGW64__");144  }145  Builder.defineMacro("__MSVCRT__");146  Builder.defineMacro("__MINGW32__");147  addCygMingDefines(Opts, Builder);148}149 150static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {151  if (Opts.CPlusPlus) {152    if (Opts.RTTIData)153      Builder.defineMacro("_CPPRTTI");154 155    if (Opts.CXXExceptions)156      Builder.defineMacro("_CPPUNWIND");157  }158 159  if (Opts.Bool)160    Builder.defineMacro("__BOOL_DEFINED");161 162  if (!Opts.CharIsSigned)163    Builder.defineMacro("_CHAR_UNSIGNED");164 165  // "The /fp:contract option allows the compiler to generate floating-point166  // contractions [...]"167  if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off)168    Builder.defineMacro("_M_FP_CONTRACT");169 170  // "The /fp:except option generates code to ensures that any unmasked171  // floating-point exceptions are raised at the exact point at which they172  // occur, and that no other floating-point exceptions are raised."173  if (Opts.getDefaultExceptionMode() ==174      LangOptions::FPExceptionModeKind::FPE_Strict)175    Builder.defineMacro("_M_FP_EXCEPT");176 177  // "The /fp:fast option allows the compiler to reorder, combine, or simplify178  // floating-point operations to optimize floating-point code for speed and179  // space. The compiler may omit rounding at assignment statements,180  // typecasts, or function calls. It may reorder operations or make algebraic181  // transforms, for example, by use of associative and distributive laws. It182  // may reorder code even if such transformations result in observably183  // different rounding behavior."184  //185  // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical186  // transformation unless the transformation is guaranteed to produce a bitwise187  // identical result."188  const bool any_imprecise_flags = Opts.FastMath || Opts.UnsafeFPMath ||189                                   Opts.AllowFPReassoc || Opts.NoHonorNaNs ||190                                   Opts.NoHonorInfs || Opts.NoSignedZero ||191                                   Opts.AllowRecip || Opts.ApproxFunc;192 193  // "Under both /fp:precise and /fp:fast, the compiler generates code intended194  // to run in the default floating-point environment."195  //196  // "[The] default floating point environment [...] sets the rounding mode197  // to round to nearest."198  if (Opts.getDefaultRoundingMode() ==199      LangOptions::RoundingMode::NearestTiesToEven) {200    if (any_imprecise_flags) {201      Builder.defineMacro("_M_FP_FAST");202    } else {203      Builder.defineMacro("_M_FP_PRECISE");204    }205  } else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() ==206                                         LangOptions::RoundingMode::Dynamic) {207    // "Under /fp:strict, the compiler generates code that allows the208    // program to safely unmask floating-point exceptions, read or write209    // floating-point status registers, or change rounding modes."210    Builder.defineMacro("_M_FP_STRICT");211  }212 213  // FIXME: POSIXThreads isn't exactly the option this should be defined for,214  //        but it works for now.215  if (Opts.POSIXThreads)216    Builder.defineMacro("_MT");217 218  if (Opts.MSCompatibilityVersion) {219    Builder.defineMacro("_MSC_VER",220                        Twine(Opts.MSCompatibilityVersion / 100000));221    Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));222    // FIXME We cannot encode the revision information into 32-bits223    Builder.defineMacro("_MSC_BUILD", Twine(1));224    // Exposed by MSVC, used in their stddef.h.225    Builder.defineMacro("_CRT_USE_BUILTIN_OFFSETOF", Twine(1));226 227    if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))228      Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));229 230    if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {231      if (Opts.CPlusPlus26)232        // TODO update to the proper value.233        Builder.defineMacro("_MSVC_LANG", "202400L");234      else if (Opts.CPlusPlus23)235        Builder.defineMacro("_MSVC_LANG", "202302L");236      else if (Opts.CPlusPlus20)237        Builder.defineMacro("_MSVC_LANG", "202002L");238      else if (Opts.CPlusPlus17)239        Builder.defineMacro("_MSVC_LANG", "201703L");240      else if (Opts.CPlusPlus14)241        Builder.defineMacro("_MSVC_LANG", "201402L");242    }243 244    if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3))245      Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE");246  }247 248  if (Opts.MicrosoftExt) {249    Builder.defineMacro("_MSC_EXTENSIONS");250 251    if (Opts.CPlusPlus11) {252      Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");253      Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");254      Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");255    }256  }257 258  if (!Opts.MSVolatile)259    Builder.defineMacro("_ISO_VOLATILE");260 261  if (Opts.Kernel)262    Builder.defineMacro("_KERNEL_MODE");263 264  Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");265  // Define __STDC_NO_THREADS__ based on MSVC version, threads.h availability,266  // and language standard.267  if (!(Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_9) && Opts.C11))268    Builder.defineMacro("__STDC_NO_THREADS__");269  // Starting with VS 2022 17.1, MSVC predefines the below macro to inform270  // users of the execution character set defined at compile time.271  // The value given is the Windows Code Page Identifier:272  // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers273  //274  // Clang currently only supports UTF-8, so we'll use 65001275  Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001");276}277 278void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,279                       MacroBuilder &Builder) {280  Builder.defineMacro("_WIN32");281  if (Triple.isArch64Bit())282    Builder.defineMacro("_WIN64");283  if (Triple.isWindowsGNUEnvironment())284    addMinGWDefines(Triple, Opts, Builder);285  else if (Triple.isKnownWindowsMSVCEnvironment() ||286           (Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat))287    addVisualCDefines(Opts, Builder);288}289 290} // namespace targets291} // namespace clang292