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