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