Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp
35294 views
//===--- OSTargets.cpp - Implement OS target feature support --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements OS specific TargetInfo types.9//===----------------------------------------------------------------------===//1011#include "OSTargets.h"12#include "clang/Basic/MacroBuilder.h"13#include "llvm/ADT/StringRef.h"1415using namespace clang;16using namespace clang::targets;1718namespace clang {19namespace targets {2021void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,22const llvm::Triple &Triple, StringRef &PlatformName,23VersionTuple &PlatformMinVersion) {24Builder.defineMacro("__APPLE_CC__", "6000");25Builder.defineMacro("__APPLE__");26Builder.defineMacro("__STDC_NO_THREADS__");2728// AddressSanitizer doesn't play well with source fortification, which is on29// by default on Darwin.30if (Opts.Sanitize.has(SanitizerKind::Address))31Builder.defineMacro("_FORTIFY_SOURCE", "0");3233// Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.34if (!Opts.ObjC) {35// __weak is always defined, for use in blocks and with objc pointers.36Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");37Builder.defineMacro("__strong", "");38Builder.defineMacro("__unsafe_unretained", "");39}4041if (Opts.Static)42Builder.defineMacro("__STATIC__");43else44Builder.defineMacro("__DYNAMIC__");4546if (Opts.POSIXThreads)47Builder.defineMacro("_REENTRANT");4849// Get the platform type and version number from the triple.50VersionTuple OsVersion;51if (Triple.isMacOSX()) {52Triple.getMacOSXVersion(OsVersion);53PlatformName = "macos";54} else {55OsVersion = Triple.getOSVersion();56PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());57if (PlatformName == "ios" && Triple.isMacCatalystEnvironment())58PlatformName = "maccatalyst";59}6061// If -target arch-pc-win32-macho option specified, we're62// generating code for Win32 ABI. No need to emit63// __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.64if (PlatformName == "win32") {65PlatformMinVersion = OsVersion;66return;67}6869assert(OsVersion < VersionTuple(100) && "Invalid version!");70char Str[7];71if (Triple.isMacOSX() && OsVersion < VersionTuple(10, 10)) {72Str[0] = '0' + (OsVersion.getMajor() / 10);73Str[1] = '0' + (OsVersion.getMajor() % 10);74Str[2] = '0' + std::min(OsVersion.getMinor().value_or(0), 9U);75Str[3] = '0' + std::min(OsVersion.getSubminor().value_or(0), 9U);76Str[4] = '\0';77} else if (!Triple.isMacOSX() && OsVersion.getMajor() < 10) {78Str[0] = '0' + OsVersion.getMajor();79Str[1] = '0' + (OsVersion.getMinor().value_or(0) / 10);80Str[2] = '0' + (OsVersion.getMinor().value_or(0) % 10);81Str[3] = '0' + (OsVersion.getSubminor().value_or(0) / 10);82Str[4] = '0' + (OsVersion.getSubminor().value_or(0) % 10);83Str[5] = '\0';84} else {85// Handle versions >= 10.86Str[0] = '0' + (OsVersion.getMajor() / 10);87Str[1] = '0' + (OsVersion.getMajor() % 10);88Str[2] = '0' + (OsVersion.getMinor().value_or(0) / 10);89Str[3] = '0' + (OsVersion.getMinor().value_or(0) % 10);90Str[4] = '0' + (OsVersion.getSubminor().value_or(0) / 10);91Str[5] = '0' + (OsVersion.getSubminor().value_or(0) % 10);92Str[6] = '\0';93}9495// Set the appropriate OS version define.96if (Triple.isTvOS()) {97Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);98} else if (Triple.isiOS()) {99Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);100} else if (Triple.isWatchOS()) {101Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);102} else if (Triple.isDriverKit()) {103assert(OsVersion.getMinor().value_or(0) < 100 &&104OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");105Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str);106} else if (Triple.isMacOSX()) {107Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);108}109110if (Triple.isOSDarwin()) {111// Any darwin OS defines a general darwin OS version macro in addition112// to the other OS specific macros.113assert(OsVersion.getMinor().value_or(0) < 100 &&114OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");115Builder.defineMacro("__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__", Str);116117// Tell users about the kernel if there is one.118Builder.defineMacro("__MACH__");119}120121PlatformMinVersion = OsVersion;122}123124static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,125MacroBuilder &Builder) {126DefineStd(Builder, "WIN32", Opts);127DefineStd(Builder, "WINNT", Opts);128if (Triple.isArch64Bit()) {129DefineStd(Builder, "WIN64", Opts);130Builder.defineMacro("__MINGW64__");131}132Builder.defineMacro("__MSVCRT__");133Builder.defineMacro("__MINGW32__");134addCygMingDefines(Opts, Builder);135}136137static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {138if (Opts.CPlusPlus) {139if (Opts.RTTIData)140Builder.defineMacro("_CPPRTTI");141142if (Opts.CXXExceptions)143Builder.defineMacro("_CPPUNWIND");144}145146if (Opts.Bool)147Builder.defineMacro("__BOOL_DEFINED");148149if (!Opts.CharIsSigned)150Builder.defineMacro("_CHAR_UNSIGNED");151152// "The /fp:contract option allows the compiler to generate floating-point153// contractions [...]"154if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off)155Builder.defineMacro("_M_FP_CONTRACT");156157// "The /fp:except option generates code to ensures that any unmasked158// floating-point exceptions are raised at the exact point at which they159// occur, and that no other floating-point exceptions are raised."160if (Opts.getDefaultExceptionMode() ==161LangOptions::FPExceptionModeKind::FPE_Strict)162Builder.defineMacro("_M_FP_EXCEPT");163164// "The /fp:fast option allows the compiler to reorder, combine, or simplify165// floating-point operations to optimize floating-point code for speed and166// space. The compiler may omit rounding at assignment statements,167// typecasts, or function calls. It may reorder operations or make algebraic168// transforms, for example, by use of associative and distributive laws. It169// may reorder code even if such transformations result in observably170// different rounding behavior."171//172// "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical173// transformation unless the transformation is guaranteed to produce a bitwise174// identical result."175const bool any_imprecise_flags =176Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath ||177Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs ||178Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc;179180// "Under both /fp:precise and /fp:fast, the compiler generates code intended181// to run in the default floating-point environment."182//183// "[The] default floating point environment [...] sets the rounding mode184// to round to nearest."185if (Opts.getDefaultRoundingMode() ==186LangOptions::RoundingMode::NearestTiesToEven) {187if (any_imprecise_flags) {188Builder.defineMacro("_M_FP_FAST");189} else {190Builder.defineMacro("_M_FP_PRECISE");191}192} else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() ==193LangOptions::RoundingMode::Dynamic) {194// "Under /fp:strict, the compiler generates code that allows the195// program to safely unmask floating-point exceptions, read or write196// floating-point status registers, or change rounding modes."197Builder.defineMacro("_M_FP_STRICT");198}199200// FIXME: POSIXThreads isn't exactly the option this should be defined for,201// but it works for now.202if (Opts.POSIXThreads)203Builder.defineMacro("_MT");204205if (Opts.MSCompatibilityVersion) {206Builder.defineMacro("_MSC_VER",207Twine(Opts.MSCompatibilityVersion / 100000));208Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));209// FIXME We cannot encode the revision information into 32-bits210Builder.defineMacro("_MSC_BUILD", Twine(1));211212if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))213Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));214215if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {216if (Opts.CPlusPlus23)217// TODO update to the proper value.218Builder.defineMacro("_MSVC_LANG", "202004L");219else if (Opts.CPlusPlus20)220Builder.defineMacro("_MSVC_LANG", "202002L");221else if (Opts.CPlusPlus17)222Builder.defineMacro("_MSVC_LANG", "201703L");223else if (Opts.CPlusPlus14)224Builder.defineMacro("_MSVC_LANG", "201402L");225}226227if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3))228Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE");229}230231if (Opts.MicrosoftExt) {232Builder.defineMacro("_MSC_EXTENSIONS");233234if (Opts.CPlusPlus11) {235Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");236Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");237Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");238}239}240241if (!Opts.MSVolatile)242Builder.defineMacro("_ISO_VOLATILE");243244if (Opts.Kernel)245Builder.defineMacro("_KERNEL_MODE");246247Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");248Builder.defineMacro("__STDC_NO_THREADS__");249250// Starting with VS 2022 17.1, MSVC predefines the below macro to inform251// users of the execution character set defined at compile time.252// The value given is the Windows Code Page Identifier:253// https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers254//255// Clang currently only supports UTF-8, so we'll use 65001256Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001");257}258259void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,260MacroBuilder &Builder) {261Builder.defineMacro("_WIN32");262if (Triple.isArch64Bit())263Builder.defineMacro("_WIN64");264if (Triple.isWindowsGNUEnvironment())265addMinGWDefines(Triple, Opts, Builder);266else if (Triple.isKnownWindowsMSVCEnvironment() ||267(Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat))268addVisualCDefines(Opts, Builder);269}270271} // namespace targets272} // namespace clang273274275