1 //===--- OSTargets.cpp - Implement OS target feature support --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements OS specific TargetInfo types. 11 //===----------------------------------------------------------------------===// 12 13 #include "OSTargets.h" 14 #include "clang/Basic/MacroBuilder.h" 15 #include "llvm/ADT/StringRef.h" 16 17 using namespace clang; 18 using namespace clang::targets; 19 20 namespace clang { 21 namespace targets { 22 23 void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 24 const llvm::Triple &Triple, StringRef &PlatformName, 25 VersionTuple &PlatformMinVersion) { 26 Builder.defineMacro("__APPLE_CC__", "6000"); 27 Builder.defineMacro("__APPLE__"); 28 Builder.defineMacro("__STDC_NO_THREADS__"); 29 Builder.defineMacro("OBJC_NEW_PROPERTIES"); 30 // AddressSanitizer doesn't play well with source fortification, which is on 31 // by default on Darwin. 32 if (Opts.Sanitize.has(SanitizerKind::Address)) 33 Builder.defineMacro("_FORTIFY_SOURCE", "0"); 34 35 // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode. 36 if (!Opts.ObjC1) { 37 // __weak is always defined, for use in blocks and with objc pointers. 38 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); 39 Builder.defineMacro("__strong", ""); 40 Builder.defineMacro("__unsafe_unretained", ""); 41 } 42 43 if (Opts.Static) 44 Builder.defineMacro("__STATIC__"); 45 else 46 Builder.defineMacro("__DYNAMIC__"); 47 48 if (Opts.POSIXThreads) 49 Builder.defineMacro("_REENTRANT"); 50 51 // Get the platform type and version number from the triple. 52 unsigned Maj, Min, Rev; 53 if (Triple.isMacOSX()) { 54 Triple.getMacOSXVersion(Maj, Min, Rev); 55 PlatformName = "macos"; 56 } else { 57 Triple.getOSVersion(Maj, Min, Rev); 58 PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); 59 } 60 61 // If -target arch-pc-win32-macho option specified, we're 62 // generating code for Win32 ABI. No need to emit 63 // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. 64 if (PlatformName == "win32") { 65 PlatformMinVersion = VersionTuple(Maj, Min, Rev); 66 return; 67 } 68 69 // Set the appropriate OS version define. 70 if (Triple.isiOS()) { 71 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 72 char Str[7]; 73 if (Maj < 10) { 74 Str[0] = '0' + Maj; 75 Str[1] = '0' + (Min / 10); 76 Str[2] = '0' + (Min % 10); 77 Str[3] = '0' + (Rev / 10); 78 Str[4] = '0' + (Rev % 10); 79 Str[5] = '\0'; 80 } else { 81 // Handle versions >= 10. 82 Str[0] = '0' + (Maj / 10); 83 Str[1] = '0' + (Maj % 10); 84 Str[2] = '0' + (Min / 10); 85 Str[3] = '0' + (Min % 10); 86 Str[4] = '0' + (Rev / 10); 87 Str[5] = '0' + (Rev % 10); 88 Str[6] = '\0'; 89 } 90 if (Triple.isTvOS()) 91 Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); 92 else 93 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", 94 Str); 95 96 } else if (Triple.isWatchOS()) { 97 assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); 98 char Str[6]; 99 Str[0] = '0' + Maj; 100 Str[1] = '0' + (Min / 10); 101 Str[2] = '0' + (Min % 10); 102 Str[3] = '0' + (Rev / 10); 103 Str[4] = '0' + (Rev % 10); 104 Str[5] = '\0'; 105 Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); 106 } else if (Triple.isMacOSX()) { 107 // Note that the Driver allows versions which aren't representable in the 108 // define (because we only get a single digit for the minor and micro 109 // revision numbers). So, we limit them to the maximum representable 110 // version. 111 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 112 char Str[7]; 113 if (Maj < 10 || (Maj == 10 && Min < 10)) { 114 Str[0] = '0' + (Maj / 10); 115 Str[1] = '0' + (Maj % 10); 116 Str[2] = '0' + std::min(Min, 9U); 117 Str[3] = '0' + std::min(Rev, 9U); 118 Str[4] = '\0'; 119 } else { 120 // Handle versions > 10.9. 121 Str[0] = '0' + (Maj / 10); 122 Str[1] = '0' + (Maj % 10); 123 Str[2] = '0' + (Min / 10); 124 Str[3] = '0' + (Min % 10); 125 Str[4] = '0' + (Rev / 10); 126 Str[5] = '0' + (Rev % 10); 127 Str[6] = '\0'; 128 } 129 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); 130 } 131 132 // Tell users about the kernel if there is one. 133 if (Triple.isOSDarwin()) 134 Builder.defineMacro("__MACH__"); 135 136 // The Watch ABI uses Dwarf EH. 137 if (Triple.isWatchABI()) 138 Builder.defineMacro("__ARM_DWARF_EH__"); 139 140 PlatformMinVersion = VersionTuple(Maj, Min, Rev); 141 } 142 } // namespace targets 143 } // namespace clang 144