1*0b57cec5SDimitry Andric //===--- OSTargets.cpp - Implement OS target feature support --------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements OS specific TargetInfo types. 10*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "OSTargets.h" 13*0b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric using namespace clang; 17*0b57cec5SDimitry Andric using namespace clang::targets; 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric namespace clang { 20*0b57cec5SDimitry Andric namespace targets { 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 23*0b57cec5SDimitry Andric const llvm::Triple &Triple, StringRef &PlatformName, 24*0b57cec5SDimitry Andric VersionTuple &PlatformMinVersion) { 25*0b57cec5SDimitry Andric Builder.defineMacro("__APPLE_CC__", "6000"); 26*0b57cec5SDimitry Andric Builder.defineMacro("__APPLE__"); 27*0b57cec5SDimitry Andric Builder.defineMacro("__STDC_NO_THREADS__"); 28*0b57cec5SDimitry Andric Builder.defineMacro("OBJC_NEW_PROPERTIES"); 29*0b57cec5SDimitry Andric // AddressSanitizer doesn't play well with source fortification, which is on 30*0b57cec5SDimitry Andric // by default on Darwin. 31*0b57cec5SDimitry Andric if (Opts.Sanitize.has(SanitizerKind::Address)) 32*0b57cec5SDimitry Andric Builder.defineMacro("_FORTIFY_SOURCE", "0"); 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode. 35*0b57cec5SDimitry Andric if (!Opts.ObjC) { 36*0b57cec5SDimitry Andric // __weak is always defined, for use in blocks and with objc pointers. 37*0b57cec5SDimitry Andric Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); 38*0b57cec5SDimitry Andric Builder.defineMacro("__strong", ""); 39*0b57cec5SDimitry Andric Builder.defineMacro("__unsafe_unretained", ""); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric if (Opts.Static) 43*0b57cec5SDimitry Andric Builder.defineMacro("__STATIC__"); 44*0b57cec5SDimitry Andric else 45*0b57cec5SDimitry Andric Builder.defineMacro("__DYNAMIC__"); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric if (Opts.POSIXThreads) 48*0b57cec5SDimitry Andric Builder.defineMacro("_REENTRANT"); 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric // Get the platform type and version number from the triple. 51*0b57cec5SDimitry Andric unsigned Maj, Min, Rev; 52*0b57cec5SDimitry Andric if (Triple.isMacOSX()) { 53*0b57cec5SDimitry Andric Triple.getMacOSXVersion(Maj, Min, Rev); 54*0b57cec5SDimitry Andric PlatformName = "macos"; 55*0b57cec5SDimitry Andric } else { 56*0b57cec5SDimitry Andric Triple.getOSVersion(Maj, Min, Rev); 57*0b57cec5SDimitry Andric PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric // If -target arch-pc-win32-macho option specified, we're 61*0b57cec5SDimitry Andric // generating code for Win32 ABI. No need to emit 62*0b57cec5SDimitry Andric // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. 63*0b57cec5SDimitry Andric if (PlatformName == "win32") { 64*0b57cec5SDimitry Andric PlatformMinVersion = VersionTuple(Maj, Min, Rev); 65*0b57cec5SDimitry Andric return; 66*0b57cec5SDimitry Andric } 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric // Set the appropriate OS version define. 69*0b57cec5SDimitry Andric if (Triple.isiOS()) { 70*0b57cec5SDimitry Andric assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 71*0b57cec5SDimitry Andric char Str[7]; 72*0b57cec5SDimitry Andric if (Maj < 10) { 73*0b57cec5SDimitry Andric Str[0] = '0' + Maj; 74*0b57cec5SDimitry Andric Str[1] = '0' + (Min / 10); 75*0b57cec5SDimitry Andric Str[2] = '0' + (Min % 10); 76*0b57cec5SDimitry Andric Str[3] = '0' + (Rev / 10); 77*0b57cec5SDimitry Andric Str[4] = '0' + (Rev % 10); 78*0b57cec5SDimitry Andric Str[5] = '\0'; 79*0b57cec5SDimitry Andric } else { 80*0b57cec5SDimitry Andric // Handle versions >= 10. 81*0b57cec5SDimitry Andric Str[0] = '0' + (Maj / 10); 82*0b57cec5SDimitry Andric Str[1] = '0' + (Maj % 10); 83*0b57cec5SDimitry Andric Str[2] = '0' + (Min / 10); 84*0b57cec5SDimitry Andric Str[3] = '0' + (Min % 10); 85*0b57cec5SDimitry Andric Str[4] = '0' + (Rev / 10); 86*0b57cec5SDimitry Andric Str[5] = '0' + (Rev % 10); 87*0b57cec5SDimitry Andric Str[6] = '\0'; 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric if (Triple.isTvOS()) 90*0b57cec5SDimitry Andric Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); 91*0b57cec5SDimitry Andric else 92*0b57cec5SDimitry Andric Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", 93*0b57cec5SDimitry Andric Str); 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric } else if (Triple.isWatchOS()) { 96*0b57cec5SDimitry Andric assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); 97*0b57cec5SDimitry Andric char Str[6]; 98*0b57cec5SDimitry Andric Str[0] = '0' + Maj; 99*0b57cec5SDimitry Andric Str[1] = '0' + (Min / 10); 100*0b57cec5SDimitry Andric Str[2] = '0' + (Min % 10); 101*0b57cec5SDimitry Andric Str[3] = '0' + (Rev / 10); 102*0b57cec5SDimitry Andric Str[4] = '0' + (Rev % 10); 103*0b57cec5SDimitry Andric Str[5] = '\0'; 104*0b57cec5SDimitry Andric Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); 105*0b57cec5SDimitry Andric } else if (Triple.isMacOSX()) { 106*0b57cec5SDimitry Andric // Note that the Driver allows versions which aren't representable in the 107*0b57cec5SDimitry Andric // define (because we only get a single digit for the minor and micro 108*0b57cec5SDimitry Andric // revision numbers). So, we limit them to the maximum representable 109*0b57cec5SDimitry Andric // version. 110*0b57cec5SDimitry Andric assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 111*0b57cec5SDimitry Andric char Str[7]; 112*0b57cec5SDimitry Andric if (Maj < 10 || (Maj == 10 && Min < 10)) { 113*0b57cec5SDimitry Andric Str[0] = '0' + (Maj / 10); 114*0b57cec5SDimitry Andric Str[1] = '0' + (Maj % 10); 115*0b57cec5SDimitry Andric Str[2] = '0' + std::min(Min, 9U); 116*0b57cec5SDimitry Andric Str[3] = '0' + std::min(Rev, 9U); 117*0b57cec5SDimitry Andric Str[4] = '\0'; 118*0b57cec5SDimitry Andric } else { 119*0b57cec5SDimitry Andric // Handle versions > 10.9. 120*0b57cec5SDimitry Andric Str[0] = '0' + (Maj / 10); 121*0b57cec5SDimitry Andric Str[1] = '0' + (Maj % 10); 122*0b57cec5SDimitry Andric Str[2] = '0' + (Min / 10); 123*0b57cec5SDimitry Andric Str[3] = '0' + (Min % 10); 124*0b57cec5SDimitry Andric Str[4] = '0' + (Rev / 10); 125*0b57cec5SDimitry Andric Str[5] = '0' + (Rev % 10); 126*0b57cec5SDimitry Andric Str[6] = '\0'; 127*0b57cec5SDimitry Andric } 128*0b57cec5SDimitry Andric Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); 129*0b57cec5SDimitry Andric } 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric // Tell users about the kernel if there is one. 132*0b57cec5SDimitry Andric if (Triple.isOSDarwin()) 133*0b57cec5SDimitry Andric Builder.defineMacro("__MACH__"); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric PlatformMinVersion = VersionTuple(Maj, Min, Rev); 136*0b57cec5SDimitry Andric } 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts, 139*0b57cec5SDimitry Andric MacroBuilder &Builder) { 140*0b57cec5SDimitry Andric DefineStd(Builder, "WIN32", Opts); 141*0b57cec5SDimitry Andric DefineStd(Builder, "WINNT", Opts); 142*0b57cec5SDimitry Andric if (Triple.isArch64Bit()) { 143*0b57cec5SDimitry Andric DefineStd(Builder, "WIN64", Opts); 144*0b57cec5SDimitry Andric Builder.defineMacro("__MINGW64__"); 145*0b57cec5SDimitry Andric } 146*0b57cec5SDimitry Andric Builder.defineMacro("__MSVCRT__"); 147*0b57cec5SDimitry Andric Builder.defineMacro("__MINGW32__"); 148*0b57cec5SDimitry Andric addCygMingDefines(Opts, Builder); 149*0b57cec5SDimitry Andric } 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { 152*0b57cec5SDimitry Andric if (Opts.CPlusPlus) { 153*0b57cec5SDimitry Andric if (Opts.RTTIData) 154*0b57cec5SDimitry Andric Builder.defineMacro("_CPPRTTI"); 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric if (Opts.CXXExceptions) 157*0b57cec5SDimitry Andric Builder.defineMacro("_CPPUNWIND"); 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric if (Opts.Bool) 161*0b57cec5SDimitry Andric Builder.defineMacro("__BOOL_DEFINED"); 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric if (!Opts.CharIsSigned) 164*0b57cec5SDimitry Andric Builder.defineMacro("_CHAR_UNSIGNED"); 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric // FIXME: POSIXThreads isn't exactly the option this should be defined for, 167*0b57cec5SDimitry Andric // but it works for now. 168*0b57cec5SDimitry Andric if (Opts.POSIXThreads) 169*0b57cec5SDimitry Andric Builder.defineMacro("_MT"); 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric if (Opts.MSCompatibilityVersion) { 172*0b57cec5SDimitry Andric Builder.defineMacro("_MSC_VER", 173*0b57cec5SDimitry Andric Twine(Opts.MSCompatibilityVersion / 100000)); 174*0b57cec5SDimitry Andric Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion)); 175*0b57cec5SDimitry Andric // FIXME We cannot encode the revision information into 32-bits 176*0b57cec5SDimitry Andric Builder.defineMacro("_MSC_BUILD", Twine(1)); 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) 179*0b57cec5SDimitry Andric Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { 182*0b57cec5SDimitry Andric if (Opts.CPlusPlus2a) 183*0b57cec5SDimitry Andric Builder.defineMacro("_MSVC_LANG", "201704L"); 184*0b57cec5SDimitry Andric else if (Opts.CPlusPlus17) 185*0b57cec5SDimitry Andric Builder.defineMacro("_MSVC_LANG", "201703L"); 186*0b57cec5SDimitry Andric else if (Opts.CPlusPlus14) 187*0b57cec5SDimitry Andric Builder.defineMacro("_MSVC_LANG", "201402L"); 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric if (Opts.MicrosoftExt) { 192*0b57cec5SDimitry Andric Builder.defineMacro("_MSC_EXTENSIONS"); 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric if (Opts.CPlusPlus11) { 195*0b57cec5SDimitry Andric Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED"); 196*0b57cec5SDimitry Andric Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED"); 197*0b57cec5SDimitry Andric Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED"); 198*0b57cec5SDimitry Andric } 199*0b57cec5SDimitry Andric } 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); 202*0b57cec5SDimitry Andric } 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, 205*0b57cec5SDimitry Andric MacroBuilder &Builder) { 206*0b57cec5SDimitry Andric Builder.defineMacro("_WIN32"); 207*0b57cec5SDimitry Andric if (Triple.isArch64Bit()) 208*0b57cec5SDimitry Andric Builder.defineMacro("_WIN64"); 209*0b57cec5SDimitry Andric if (Triple.isWindowsGNUEnvironment()) 210*0b57cec5SDimitry Andric addMinGWDefines(Triple, Opts, Builder); 211*0b57cec5SDimitry Andric else if (Triple.isKnownWindowsMSVCEnvironment() || 212*0b57cec5SDimitry Andric (Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat)) 213*0b57cec5SDimitry Andric addVisualCDefines(Opts, Builder); 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric } // namespace targets 217*0b57cec5SDimitry Andric } // namespace clang 218