xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp (revision 4824e7fd18a1223177218d4aec1b3c6c5c4a444e)
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.
510b57cec5SDimitry Andric   unsigned Maj, Min, Rev;
520b57cec5SDimitry Andric   if (Triple.isMacOSX()) {
530b57cec5SDimitry Andric     Triple.getMacOSXVersion(Maj, Min, Rev);
540b57cec5SDimitry Andric     PlatformName = "macos";
550b57cec5SDimitry Andric   } else {
560b57cec5SDimitry Andric     Triple.getOSVersion(Maj, Min, Rev);
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") {
660b57cec5SDimitry Andric     PlatformMinVersion = VersionTuple(Maj, Min, Rev);
670b57cec5SDimitry Andric     return;
680b57cec5SDimitry Andric   }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   // Set the appropriate OS version define.
710b57cec5SDimitry Andric   if (Triple.isiOS()) {
720b57cec5SDimitry Andric     assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
730b57cec5SDimitry Andric     char Str[7];
740b57cec5SDimitry Andric     if (Maj < 10) {
750b57cec5SDimitry Andric       Str[0] = '0' + Maj;
760b57cec5SDimitry Andric       Str[1] = '0' + (Min / 10);
770b57cec5SDimitry Andric       Str[2] = '0' + (Min % 10);
780b57cec5SDimitry Andric       Str[3] = '0' + (Rev / 10);
790b57cec5SDimitry Andric       Str[4] = '0' + (Rev % 10);
800b57cec5SDimitry Andric       Str[5] = '\0';
810b57cec5SDimitry Andric     } else {
820b57cec5SDimitry Andric       // Handle versions >= 10.
830b57cec5SDimitry Andric       Str[0] = '0' + (Maj / 10);
840b57cec5SDimitry Andric       Str[1] = '0' + (Maj % 10);
850b57cec5SDimitry Andric       Str[2] = '0' + (Min / 10);
860b57cec5SDimitry Andric       Str[3] = '0' + (Min % 10);
870b57cec5SDimitry Andric       Str[4] = '0' + (Rev / 10);
880b57cec5SDimitry Andric       Str[5] = '0' + (Rev % 10);
890b57cec5SDimitry Andric       Str[6] = '\0';
900b57cec5SDimitry Andric     }
910b57cec5SDimitry Andric     if (Triple.isTvOS())
920b57cec5SDimitry Andric       Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
930b57cec5SDimitry Andric     else
940b57cec5SDimitry Andric       Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
950b57cec5SDimitry Andric                           Str);
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   } else if (Triple.isWatchOS()) {
980b57cec5SDimitry Andric     assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
990b57cec5SDimitry Andric     char Str[6];
1000b57cec5SDimitry Andric     Str[0] = '0' + Maj;
1010b57cec5SDimitry Andric     Str[1] = '0' + (Min / 10);
1020b57cec5SDimitry Andric     Str[2] = '0' + (Min % 10);
1030b57cec5SDimitry Andric     Str[3] = '0' + (Rev / 10);
1040b57cec5SDimitry Andric     Str[4] = '0' + (Rev % 10);
1050b57cec5SDimitry Andric     Str[5] = '\0';
1060b57cec5SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);
1070b57cec5SDimitry Andric   } else if (Triple.isMacOSX()) {
1080b57cec5SDimitry Andric     // Note that the Driver allows versions which aren't representable in the
1090b57cec5SDimitry Andric     // define (because we only get a single digit for the minor and micro
1100b57cec5SDimitry Andric     // revision numbers). So, we limit them to the maximum representable
1110b57cec5SDimitry Andric     // version.
1120b57cec5SDimitry Andric     assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
1130b57cec5SDimitry Andric     char Str[7];
1140b57cec5SDimitry Andric     if (Maj < 10 || (Maj == 10 && Min < 10)) {
1150b57cec5SDimitry Andric       Str[0] = '0' + (Maj / 10);
1160b57cec5SDimitry Andric       Str[1] = '0' + (Maj % 10);
1170b57cec5SDimitry Andric       Str[2] = '0' + std::min(Min, 9U);
1180b57cec5SDimitry Andric       Str[3] = '0' + std::min(Rev, 9U);
1190b57cec5SDimitry Andric       Str[4] = '\0';
1200b57cec5SDimitry Andric     } else {
1210b57cec5SDimitry Andric       // Handle versions > 10.9.
1220b57cec5SDimitry Andric       Str[0] = '0' + (Maj / 10);
1230b57cec5SDimitry Andric       Str[1] = '0' + (Maj % 10);
1240b57cec5SDimitry Andric       Str[2] = '0' + (Min / 10);
1250b57cec5SDimitry Andric       Str[3] = '0' + (Min % 10);
1260b57cec5SDimitry Andric       Str[4] = '0' + (Rev / 10);
1270b57cec5SDimitry Andric       Str[5] = '0' + (Rev % 10);
1280b57cec5SDimitry Andric       Str[6] = '\0';
1290b57cec5SDimitry Andric     }
1300b57cec5SDimitry Andric     Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   // Tell users about the kernel if there is one.
1340b57cec5SDimitry Andric   if (Triple.isOSDarwin())
1350b57cec5SDimitry Andric     Builder.defineMacro("__MACH__");
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   PlatformMinVersion = VersionTuple(Maj, Min, Rev);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,
1410b57cec5SDimitry Andric                             MacroBuilder &Builder) {
1420b57cec5SDimitry Andric   DefineStd(Builder, "WIN32", Opts);
1430b57cec5SDimitry Andric   DefineStd(Builder, "WINNT", Opts);
1440b57cec5SDimitry Andric   if (Triple.isArch64Bit()) {
1450b57cec5SDimitry Andric     DefineStd(Builder, "WIN64", Opts);
1460b57cec5SDimitry Andric     Builder.defineMacro("__MINGW64__");
1470b57cec5SDimitry Andric   }
1480b57cec5SDimitry Andric   Builder.defineMacro("__MSVCRT__");
1490b57cec5SDimitry Andric   Builder.defineMacro("__MINGW32__");
1500b57cec5SDimitry Andric   addCygMingDefines(Opts, Builder);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
1540b57cec5SDimitry Andric   if (Opts.CPlusPlus) {
1550b57cec5SDimitry Andric     if (Opts.RTTIData)
1560b57cec5SDimitry Andric       Builder.defineMacro("_CPPRTTI");
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric     if (Opts.CXXExceptions)
1590b57cec5SDimitry Andric       Builder.defineMacro("_CPPUNWIND");
1600b57cec5SDimitry Andric   }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   if (Opts.Bool)
1630b57cec5SDimitry Andric     Builder.defineMacro("__BOOL_DEFINED");
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   if (!Opts.CharIsSigned)
1660b57cec5SDimitry Andric     Builder.defineMacro("_CHAR_UNSIGNED");
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   // FIXME: POSIXThreads isn't exactly the option this should be defined for,
1690b57cec5SDimitry Andric   //        but it works for now.
1700b57cec5SDimitry Andric   if (Opts.POSIXThreads)
1710b57cec5SDimitry Andric     Builder.defineMacro("_MT");
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   if (Opts.MSCompatibilityVersion) {
1740b57cec5SDimitry Andric     Builder.defineMacro("_MSC_VER",
1750b57cec5SDimitry Andric                         Twine(Opts.MSCompatibilityVersion / 100000));
1760b57cec5SDimitry Andric     Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
1770b57cec5SDimitry Andric     // FIXME We cannot encode the revision information into 32-bits
1780b57cec5SDimitry Andric     Builder.defineMacro("_MSC_BUILD", Twine(1));
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric     if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
1810b57cec5SDimitry Andric       Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric     if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
184*4824e7fdSDimitry Andric       if (Opts.CPlusPlus2b)
185*4824e7fdSDimitry Andric         Builder.defineMacro("_MSVC_LANG", "202004L");
186*4824e7fdSDimitry Andric       else if (Opts.CPlusPlus20)
187*4824e7fdSDimitry Andric         Builder.defineMacro("_MSVC_LANG", "202002L");
1880b57cec5SDimitry Andric       else if (Opts.CPlusPlus17)
1890b57cec5SDimitry Andric         Builder.defineMacro("_MSVC_LANG", "201703L");
1900b57cec5SDimitry Andric       else if (Opts.CPlusPlus14)
1910b57cec5SDimitry Andric         Builder.defineMacro("_MSVC_LANG", "201402L");
1920b57cec5SDimitry Andric     }
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   if (Opts.MicrosoftExt) {
1960b57cec5SDimitry Andric     Builder.defineMacro("_MSC_EXTENSIONS");
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric     if (Opts.CPlusPlus11) {
1990b57cec5SDimitry Andric       Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
2000b57cec5SDimitry Andric       Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
2010b57cec5SDimitry Andric       Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
2020b57cec5SDimitry Andric     }
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
206*4824e7fdSDimitry Andric 
207*4824e7fdSDimitry Andric   // Starting with VS 2022 17.1, MSVC predefines the below macro to inform
208*4824e7fdSDimitry Andric   // users of the execution character set defined at compile time.
209*4824e7fdSDimitry Andric   // The value given is the Windows Code Page Identifier:
210*4824e7fdSDimitry Andric   // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
211*4824e7fdSDimitry Andric   //
212*4824e7fdSDimitry Andric   // Clang currently only supports UTF-8, so we'll use 65001
213*4824e7fdSDimitry Andric   Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001");
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
2170b57cec5SDimitry Andric                        MacroBuilder &Builder) {
2180b57cec5SDimitry Andric   Builder.defineMacro("_WIN32");
2190b57cec5SDimitry Andric   if (Triple.isArch64Bit())
2200b57cec5SDimitry Andric     Builder.defineMacro("_WIN64");
2210b57cec5SDimitry Andric   if (Triple.isWindowsGNUEnvironment())
2220b57cec5SDimitry Andric     addMinGWDefines(Triple, Opts, Builder);
2230b57cec5SDimitry Andric   else if (Triple.isKnownWindowsMSVCEnvironment() ||
2240b57cec5SDimitry Andric            (Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat))
2250b57cec5SDimitry Andric     addVisualCDefines(Opts, Builder);
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric } // namespace targets
2290b57cec5SDimitry Andric } // namespace clang
230