xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===--- OSTargets.cpp - Implement OS target feature support --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements OS specific TargetInfo types.
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "OSTargets.h"
130b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric using namespace clang;
170b57cec5SDimitry Andric using namespace clang::targets;
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace clang {
200b57cec5SDimitry Andric namespace targets {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
230b57cec5SDimitry Andric                       const llvm::Triple &Triple, StringRef &PlatformName,
240b57cec5SDimitry Andric                       VersionTuple &PlatformMinVersion) {
250b57cec5SDimitry Andric   Builder.defineMacro("__APPLE_CC__", "6000");
260b57cec5SDimitry Andric   Builder.defineMacro("__APPLE__");
270b57cec5SDimitry Andric   Builder.defineMacro("__STDC_NO_THREADS__");
285ffd83dbSDimitry Andric 
290b57cec5SDimitry Andric   // AddressSanitizer doesn't play well with source fortification, which is on
300b57cec5SDimitry Andric   // by default on Darwin.
310b57cec5SDimitry Andric   if (Opts.Sanitize.has(SanitizerKind::Address))
320b57cec5SDimitry Andric     Builder.defineMacro("_FORTIFY_SOURCE", "0");
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.
350b57cec5SDimitry Andric   if (!Opts.ObjC) {
360b57cec5SDimitry Andric     // __weak is always defined, for use in blocks and with objc pointers.
370b57cec5SDimitry Andric     Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
380b57cec5SDimitry Andric     Builder.defineMacro("__strong", "");
390b57cec5SDimitry Andric     Builder.defineMacro("__unsafe_unretained", "");
400b57cec5SDimitry Andric   }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   if (Opts.Static)
430b57cec5SDimitry Andric     Builder.defineMacro("__STATIC__");
440b57cec5SDimitry Andric   else
450b57cec5SDimitry Andric     Builder.defineMacro("__DYNAMIC__");
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   if (Opts.POSIXThreads)
480b57cec5SDimitry Andric     Builder.defineMacro("_REENTRANT");
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   // Get the platform type and version number from the triple.
510eae32dcSDimitry Andric   VersionTuple OsVersion;
520b57cec5SDimitry Andric   if (Triple.isMacOSX()) {
530eae32dcSDimitry Andric     Triple.getMacOSXVersion(OsVersion);
540b57cec5SDimitry Andric     PlatformName = "macos";
550b57cec5SDimitry Andric   } else {
560eae32dcSDimitry Andric     OsVersion = Triple.getOSVersion();
570b57cec5SDimitry Andric     PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
58fe6060f1SDimitry Andric     if (PlatformName == "ios" && Triple.isMacCatalystEnvironment())
59fe6060f1SDimitry Andric       PlatformName = "maccatalyst";
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   // If -target arch-pc-win32-macho option specified, we're
630b57cec5SDimitry Andric   // generating code for Win32 ABI. No need to emit
640b57cec5SDimitry Andric   // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
650b57cec5SDimitry Andric   if (PlatformName == "win32") {
660eae32dcSDimitry Andric     PlatformMinVersion = OsVersion;
670b57cec5SDimitry Andric     return;
680b57cec5SDimitry Andric   }
690b57cec5SDimitry Andric 
700eae32dcSDimitry Andric   assert(OsVersion < VersionTuple(100) && "Invalid version!");
710b57cec5SDimitry Andric   char Str[7];
72bdd1243dSDimitry Andric   if (Triple.isMacOSX() && OsVersion < VersionTuple(10, 10)) {
73bdd1243dSDimitry Andric     Str[0] = '0' + (OsVersion.getMajor() / 10);
74bdd1243dSDimitry Andric     Str[1] = '0' + (OsVersion.getMajor() % 10);
75bdd1243dSDimitry Andric     Str[2] = '0' + std::min(OsVersion.getMinor().value_or(0), 9U);
76bdd1243dSDimitry Andric     Str[3] = '0' + std::min(OsVersion.getSubminor().value_or(0), 9U);
77bdd1243dSDimitry Andric     Str[4] = '\0';
78bdd1243dSDimitry Andric   } else if (!Triple.isMacOSX() && OsVersion.getMajor() < 10) {
790eae32dcSDimitry Andric     Str[0] = '0' + OsVersion.getMajor();
8081ad6265SDimitry Andric     Str[1] = '0' + (OsVersion.getMinor().value_or(0) / 10);
8181ad6265SDimitry Andric     Str[2] = '0' + (OsVersion.getMinor().value_or(0) % 10);
8281ad6265SDimitry Andric     Str[3] = '0' + (OsVersion.getSubminor().value_or(0) / 10);
8381ad6265SDimitry Andric     Str[4] = '0' + (OsVersion.getSubminor().value_or(0) % 10);
840b57cec5SDimitry Andric     Str[5] = '\0';
850b57cec5SDimitry Andric   } else {
860b57cec5SDimitry Andric     // Handle versions >= 10.
870eae32dcSDimitry Andric     Str[0] = '0' + (OsVersion.getMajor() / 10);
880eae32dcSDimitry Andric     Str[1] = '0' + (OsVersion.getMajor() % 10);
8981ad6265SDimitry Andric     Str[2] = '0' + (OsVersion.getMinor().value_or(0) / 10);
9081ad6265SDimitry Andric     Str[3] = '0' + (OsVersion.getMinor().value_or(0) % 10);
9181ad6265SDimitry Andric     Str[4] = '0' + (OsVersion.getSubminor().value_or(0) / 10);
9281ad6265SDimitry Andric     Str[5] = '0' + (OsVersion.getSubminor().value_or(0) % 10);
930b57cec5SDimitry Andric     Str[6] = '\0';
940b57cec5SDimitry Andric   }
950b57cec5SDimitry Andric 
96bdd1243dSDimitry Andric   // Set the appropriate OS version define.
97bdd1243dSDimitry Andric   if (Triple.isTvOS()) {
98bdd1243dSDimitry Andric     Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
99bdd1243dSDimitry Andric   } else if (Triple.isiOS()) {
100bdd1243dSDimitry Andric     Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
1010b57cec5SDimitry Andric   } else if (Triple.isWatchOS()) {
1020b57cec5SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);
10381ad6265SDimitry Andric   } else if (Triple.isDriverKit()) {
104bdd1243dSDimitry Andric     assert(OsVersion.getMinor().value_or(0) < 100 &&
10581ad6265SDimitry Andric            OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");
10681ad6265SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str);
1070b57cec5SDimitry Andric   } else if (Triple.isMacOSX()) {
1080b57cec5SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric 
11106c3fb27SDimitry Andric   if (Triple.isOSDarwin()) {
11206c3fb27SDimitry Andric     // Any darwin OS defines a general darwin OS version macro in addition
11306c3fb27SDimitry Andric     // to the other OS specific macros.
11406c3fb27SDimitry Andric     assert(OsVersion.getMinor().value_or(0) < 100 &&
11506c3fb27SDimitry Andric            OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");
11606c3fb27SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__", Str);
11706c3fb27SDimitry Andric 
1180b57cec5SDimitry Andric     // Tell users about the kernel if there is one.
1190b57cec5SDimitry Andric     Builder.defineMacro("__MACH__");
12006c3fb27SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220eae32dcSDimitry Andric   PlatformMinVersion = OsVersion;
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,
1260b57cec5SDimitry Andric                             MacroBuilder &Builder) {
1270b57cec5SDimitry Andric   DefineStd(Builder, "WIN32", Opts);
1280b57cec5SDimitry Andric   DefineStd(Builder, "WINNT", Opts);
1290b57cec5SDimitry Andric   if (Triple.isArch64Bit()) {
1300b57cec5SDimitry Andric     DefineStd(Builder, "WIN64", Opts);
1310b57cec5SDimitry Andric     Builder.defineMacro("__MINGW64__");
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric   Builder.defineMacro("__MSVCRT__");
1340b57cec5SDimitry Andric   Builder.defineMacro("__MINGW32__");
1350b57cec5SDimitry Andric   addCygMingDefines(Opts, Builder);
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
1390b57cec5SDimitry Andric   if (Opts.CPlusPlus) {
1400b57cec5SDimitry Andric     if (Opts.RTTIData)
1410b57cec5SDimitry Andric       Builder.defineMacro("_CPPRTTI");
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric     if (Opts.CXXExceptions)
1440b57cec5SDimitry Andric       Builder.defineMacro("_CPPUNWIND");
1450b57cec5SDimitry Andric   }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   if (Opts.Bool)
1480b57cec5SDimitry Andric     Builder.defineMacro("__BOOL_DEFINED");
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   if (!Opts.CharIsSigned)
1510b57cec5SDimitry Andric     Builder.defineMacro("_CHAR_UNSIGNED");
1520b57cec5SDimitry Andric 
153bdd1243dSDimitry Andric   // "The /fp:contract option allows the compiler to generate floating-point
154bdd1243dSDimitry Andric   // contractions [...]"
155bdd1243dSDimitry Andric   if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off)
156bdd1243dSDimitry Andric     Builder.defineMacro("_M_FP_CONTRACT");
157bdd1243dSDimitry Andric 
158bdd1243dSDimitry Andric   // "The /fp:except option generates code to ensures that any unmasked
159bdd1243dSDimitry Andric   // floating-point exceptions are raised at the exact point at which they
160bdd1243dSDimitry Andric   // occur, and that no other floating-point exceptions are raised."
161bdd1243dSDimitry Andric   if (Opts.getDefaultExceptionMode() ==
162bdd1243dSDimitry Andric       LangOptions::FPExceptionModeKind::FPE_Strict)
163bdd1243dSDimitry Andric     Builder.defineMacro("_M_FP_EXCEPT");
164bdd1243dSDimitry Andric 
165bdd1243dSDimitry Andric   // "The /fp:fast option allows the compiler to reorder, combine, or simplify
166bdd1243dSDimitry Andric   // floating-point operations to optimize floating-point code for speed and
167bdd1243dSDimitry Andric   // space. The compiler may omit rounding at assignment statements,
168bdd1243dSDimitry Andric   // typecasts, or function calls. It may reorder operations or make algebraic
169bdd1243dSDimitry Andric   // transforms, for example, by use of associative and distributive laws. It
170bdd1243dSDimitry Andric   // may reorder code even if such transformations result in observably
171bdd1243dSDimitry Andric   // different rounding behavior."
172bdd1243dSDimitry Andric   //
173bdd1243dSDimitry Andric   // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical
174bdd1243dSDimitry Andric   // transformation unless the transformation is guaranteed to produce a bitwise
175bdd1243dSDimitry Andric   // identical result."
176bdd1243dSDimitry Andric   const bool any_imprecise_flags =
177bdd1243dSDimitry Andric       Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath ||
178bdd1243dSDimitry Andric       Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs ||
179bdd1243dSDimitry Andric       Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc;
180bdd1243dSDimitry Andric 
181bdd1243dSDimitry Andric   // "Under both /fp:precise and /fp:fast, the compiler generates code intended
182bdd1243dSDimitry Andric   // to run in the default floating-point environment."
183bdd1243dSDimitry Andric   //
184bdd1243dSDimitry Andric   // "[The] default floating point environment [...] sets the rounding mode
185bdd1243dSDimitry Andric   // to round to nearest."
186bdd1243dSDimitry Andric   if (Opts.getDefaultRoundingMode() ==
187bdd1243dSDimitry Andric       LangOptions::RoundingMode::NearestTiesToEven) {
188bdd1243dSDimitry Andric     if (any_imprecise_flags) {
189bdd1243dSDimitry Andric       Builder.defineMacro("_M_FP_FAST");
190bdd1243dSDimitry Andric     } else {
191bdd1243dSDimitry Andric       Builder.defineMacro("_M_FP_PRECISE");
192bdd1243dSDimitry Andric     }
193bdd1243dSDimitry Andric   } else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() ==
194bdd1243dSDimitry Andric                                          LangOptions::RoundingMode::Dynamic) {
195bdd1243dSDimitry Andric     // "Under /fp:strict, the compiler generates code that allows the
196bdd1243dSDimitry Andric     // program to safely unmask floating-point exceptions, read or write
197bdd1243dSDimitry Andric     // floating-point status registers, or change rounding modes."
198bdd1243dSDimitry Andric     Builder.defineMacro("_M_FP_STRICT");
199bdd1243dSDimitry Andric   }
200bdd1243dSDimitry Andric 
2010b57cec5SDimitry Andric   // FIXME: POSIXThreads isn't exactly the option this should be defined for,
2020b57cec5SDimitry Andric   //        but it works for now.
2030b57cec5SDimitry Andric   if (Opts.POSIXThreads)
2040b57cec5SDimitry Andric     Builder.defineMacro("_MT");
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   if (Opts.MSCompatibilityVersion) {
2070b57cec5SDimitry Andric     Builder.defineMacro("_MSC_VER",
2080b57cec5SDimitry Andric                         Twine(Opts.MSCompatibilityVersion / 100000));
2090b57cec5SDimitry Andric     Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
2100b57cec5SDimitry Andric     // FIXME We cannot encode the revision information into 32-bits
2110b57cec5SDimitry Andric     Builder.defineMacro("_MSC_BUILD", Twine(1));
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric     if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
2140b57cec5SDimitry Andric       Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric     if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
21706c3fb27SDimitry Andric       if (Opts.CPlusPlus23)
21806c3fb27SDimitry Andric         // TODO update to the proper value.
2194824e7fdSDimitry Andric         Builder.defineMacro("_MSVC_LANG", "202004L");
2204824e7fdSDimitry Andric       else if (Opts.CPlusPlus20)
2214824e7fdSDimitry Andric         Builder.defineMacro("_MSVC_LANG", "202002L");
2220b57cec5SDimitry Andric       else if (Opts.CPlusPlus17)
2230b57cec5SDimitry Andric         Builder.defineMacro("_MSVC_LANG", "201703L");
2240b57cec5SDimitry Andric       else if (Opts.CPlusPlus14)
2250b57cec5SDimitry Andric         Builder.defineMacro("_MSVC_LANG", "201402L");
2260b57cec5SDimitry Andric     }
227*5f757f3fSDimitry Andric 
228*5f757f3fSDimitry Andric     if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3))
229*5f757f3fSDimitry Andric       Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE");
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   if (Opts.MicrosoftExt) {
2330b57cec5SDimitry Andric     Builder.defineMacro("_MSC_EXTENSIONS");
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     if (Opts.CPlusPlus11) {
2360b57cec5SDimitry Andric       Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
2370b57cec5SDimitry Andric       Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
2380b57cec5SDimitry Andric       Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
2390b57cec5SDimitry Andric     }
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric 
242bdd1243dSDimitry Andric   if (!Opts.MSVolatile)
243bdd1243dSDimitry Andric     Builder.defineMacro("_ISO_VOLATILE");
244bdd1243dSDimitry Andric 
24581ad6265SDimitry Andric   if (Opts.Kernel)
24681ad6265SDimitry Andric     Builder.defineMacro("_KERNEL_MODE");
24781ad6265SDimitry Andric 
2480b57cec5SDimitry Andric   Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
2490eae32dcSDimitry Andric   Builder.defineMacro("__STDC_NO_THREADS__");
2504824e7fdSDimitry Andric 
2514824e7fdSDimitry Andric   // Starting with VS 2022 17.1, MSVC predefines the below macro to inform
2524824e7fdSDimitry Andric   // users of the execution character set defined at compile time.
2534824e7fdSDimitry Andric   // The value given is the Windows Code Page Identifier:
2544824e7fdSDimitry Andric   // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
2554824e7fdSDimitry Andric   //
2564824e7fdSDimitry Andric   // Clang currently only supports UTF-8, so we'll use 65001
2574824e7fdSDimitry Andric   Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001");
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
2610b57cec5SDimitry Andric                        MacroBuilder &Builder) {
2620b57cec5SDimitry Andric   Builder.defineMacro("_WIN32");
2630b57cec5SDimitry Andric   if (Triple.isArch64Bit())
2640b57cec5SDimitry Andric     Builder.defineMacro("_WIN64");
2650b57cec5SDimitry Andric   if (Triple.isWindowsGNUEnvironment())
2660b57cec5SDimitry Andric     addMinGWDefines(Triple, Opts, Builder);
2670b57cec5SDimitry Andric   else if (Triple.isKnownWindowsMSVCEnvironment() ||
2680b57cec5SDimitry Andric            (Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat))
2690b57cec5SDimitry Andric     addVisualCDefines(Opts, Builder);
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric } // namespace targets
2730b57cec5SDimitry Andric } // namespace clang
274