1326941Sdim//===--- OSTargets.cpp - Implement OS target feature support --------------===// 2326941Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326941Sdim// 7326941Sdim//===----------------------------------------------------------------------===// 8326941Sdim// 9326941Sdim// This file implements OS specific TargetInfo types. 10326941Sdim//===----------------------------------------------------------------------===// 11326941Sdim 12326941Sdim#include "OSTargets.h" 13326941Sdim#include "clang/Basic/MacroBuilder.h" 14326941Sdim#include "llvm/ADT/StringRef.h" 15326941Sdim 16326941Sdimusing namespace clang; 17326941Sdimusing namespace clang::targets; 18326941Sdim 19326941Sdimnamespace clang { 20326941Sdimnamespace targets { 21326941Sdim 22326941Sdimvoid getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 23326941Sdim const llvm::Triple &Triple, StringRef &PlatformName, 24326941Sdim VersionTuple &PlatformMinVersion) { 25326941Sdim Builder.defineMacro("__APPLE_CC__", "6000"); 26326941Sdim Builder.defineMacro("__APPLE__"); 27326941Sdim Builder.defineMacro("__STDC_NO_THREADS__"); 28326941Sdim Builder.defineMacro("OBJC_NEW_PROPERTIES"); 29326941Sdim // AddressSanitizer doesn't play well with source fortification, which is on 30326941Sdim // by default on Darwin. 31326941Sdim if (Opts.Sanitize.has(SanitizerKind::Address)) 32326941Sdim Builder.defineMacro("_FORTIFY_SOURCE", "0"); 33326941Sdim 34326941Sdim // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode. 35344779Sdim if (!Opts.ObjC) { 36326941Sdim // __weak is always defined, for use in blocks and with objc pointers. 37326941Sdim Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); 38326941Sdim Builder.defineMacro("__strong", ""); 39326941Sdim Builder.defineMacro("__unsafe_unretained", ""); 40326941Sdim } 41326941Sdim 42326941Sdim if (Opts.Static) 43326941Sdim Builder.defineMacro("__STATIC__"); 44326941Sdim else 45326941Sdim Builder.defineMacro("__DYNAMIC__"); 46326941Sdim 47326941Sdim if (Opts.POSIXThreads) 48326941Sdim Builder.defineMacro("_REENTRANT"); 49326941Sdim 50326941Sdim // Get the platform type and version number from the triple. 51326941Sdim unsigned Maj, Min, Rev; 52326941Sdim if (Triple.isMacOSX()) { 53326941Sdim Triple.getMacOSXVersion(Maj, Min, Rev); 54326941Sdim PlatformName = "macos"; 55326941Sdim } else { 56326941Sdim Triple.getOSVersion(Maj, Min, Rev); 57326941Sdim PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); 58326941Sdim } 59326941Sdim 60326941Sdim // If -target arch-pc-win32-macho option specified, we're 61326941Sdim // generating code for Win32 ABI. No need to emit 62326941Sdim // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. 63326941Sdim if (PlatformName == "win32") { 64326941Sdim PlatformMinVersion = VersionTuple(Maj, Min, Rev); 65326941Sdim return; 66326941Sdim } 67326941Sdim 68326941Sdim // Set the appropriate OS version define. 69326941Sdim if (Triple.isiOS()) { 70326941Sdim assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 71326941Sdim char Str[7]; 72326941Sdim if (Maj < 10) { 73326941Sdim Str[0] = '0' + Maj; 74326941Sdim Str[1] = '0' + (Min / 10); 75326941Sdim Str[2] = '0' + (Min % 10); 76326941Sdim Str[3] = '0' + (Rev / 10); 77326941Sdim Str[4] = '0' + (Rev % 10); 78326941Sdim Str[5] = '\0'; 79326941Sdim } else { 80326941Sdim // Handle versions >= 10. 81326941Sdim Str[0] = '0' + (Maj / 10); 82326941Sdim Str[1] = '0' + (Maj % 10); 83326941Sdim Str[2] = '0' + (Min / 10); 84326941Sdim Str[3] = '0' + (Min % 10); 85326941Sdim Str[4] = '0' + (Rev / 10); 86326941Sdim Str[5] = '0' + (Rev % 10); 87326941Sdim Str[6] = '\0'; 88326941Sdim } 89326941Sdim if (Triple.isTvOS()) 90326941Sdim Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); 91326941Sdim else 92326941Sdim Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", 93326941Sdim Str); 94326941Sdim 95326941Sdim } else if (Triple.isWatchOS()) { 96326941Sdim assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); 97326941Sdim char Str[6]; 98326941Sdim Str[0] = '0' + Maj; 99326941Sdim Str[1] = '0' + (Min / 10); 100326941Sdim Str[2] = '0' + (Min % 10); 101326941Sdim Str[3] = '0' + (Rev / 10); 102326941Sdim Str[4] = '0' + (Rev % 10); 103326941Sdim Str[5] = '\0'; 104326941Sdim Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); 105326941Sdim } else if (Triple.isMacOSX()) { 106326941Sdim // Note that the Driver allows versions which aren't representable in the 107326941Sdim // define (because we only get a single digit for the minor and micro 108326941Sdim // revision numbers). So, we limit them to the maximum representable 109326941Sdim // version. 110326941Sdim assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 111326941Sdim char Str[7]; 112326941Sdim if (Maj < 10 || (Maj == 10 && Min < 10)) { 113326941Sdim Str[0] = '0' + (Maj / 10); 114326941Sdim Str[1] = '0' + (Maj % 10); 115326941Sdim Str[2] = '0' + std::min(Min, 9U); 116326941Sdim Str[3] = '0' + std::min(Rev, 9U); 117326941Sdim Str[4] = '\0'; 118326941Sdim } else { 119326941Sdim // Handle versions > 10.9. 120326941Sdim Str[0] = '0' + (Maj / 10); 121326941Sdim Str[1] = '0' + (Maj % 10); 122326941Sdim Str[2] = '0' + (Min / 10); 123326941Sdim Str[3] = '0' + (Min % 10); 124326941Sdim Str[4] = '0' + (Rev / 10); 125326941Sdim Str[5] = '0' + (Rev % 10); 126326941Sdim Str[6] = '\0'; 127326941Sdim } 128326941Sdim Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); 129326941Sdim } 130326941Sdim 131326941Sdim // Tell users about the kernel if there is one. 132326941Sdim if (Triple.isOSDarwin()) 133326941Sdim Builder.defineMacro("__MACH__"); 134326941Sdim 135326941Sdim PlatformMinVersion = VersionTuple(Maj, Min, Rev); 136326941Sdim} 137353358Sdim 138353358Sdimstatic void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts, 139353358Sdim MacroBuilder &Builder) { 140353358Sdim DefineStd(Builder, "WIN32", Opts); 141353358Sdim DefineStd(Builder, "WINNT", Opts); 142353358Sdim if (Triple.isArch64Bit()) { 143353358Sdim DefineStd(Builder, "WIN64", Opts); 144353358Sdim Builder.defineMacro("__MINGW64__"); 145353358Sdim } 146353358Sdim Builder.defineMacro("__MSVCRT__"); 147353358Sdim Builder.defineMacro("__MINGW32__"); 148353358Sdim addCygMingDefines(Opts, Builder); 149353358Sdim} 150353358Sdim 151353358Sdimstatic void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { 152353358Sdim if (Opts.CPlusPlus) { 153353358Sdim if (Opts.RTTIData) 154353358Sdim Builder.defineMacro("_CPPRTTI"); 155353358Sdim 156353358Sdim if (Opts.CXXExceptions) 157353358Sdim Builder.defineMacro("_CPPUNWIND"); 158353358Sdim } 159353358Sdim 160353358Sdim if (Opts.Bool) 161353358Sdim Builder.defineMacro("__BOOL_DEFINED"); 162353358Sdim 163353358Sdim if (!Opts.CharIsSigned) 164353358Sdim Builder.defineMacro("_CHAR_UNSIGNED"); 165353358Sdim 166353358Sdim // FIXME: POSIXThreads isn't exactly the option this should be defined for, 167353358Sdim // but it works for now. 168353358Sdim if (Opts.POSIXThreads) 169353358Sdim Builder.defineMacro("_MT"); 170353358Sdim 171353358Sdim if (Opts.MSCompatibilityVersion) { 172353358Sdim Builder.defineMacro("_MSC_VER", 173353358Sdim Twine(Opts.MSCompatibilityVersion / 100000)); 174353358Sdim Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion)); 175353358Sdim // FIXME We cannot encode the revision information into 32-bits 176353358Sdim Builder.defineMacro("_MSC_BUILD", Twine(1)); 177353358Sdim 178353358Sdim if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) 179353358Sdim Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); 180353358Sdim 181353358Sdim if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { 182353358Sdim if (Opts.CPlusPlus2a) 183360784Sdim Builder.defineMacro("_MSVC_LANG", "201705L"); 184353358Sdim else if (Opts.CPlusPlus17) 185353358Sdim Builder.defineMacro("_MSVC_LANG", "201703L"); 186353358Sdim else if (Opts.CPlusPlus14) 187353358Sdim Builder.defineMacro("_MSVC_LANG", "201402L"); 188353358Sdim } 189353358Sdim } 190353358Sdim 191353358Sdim if (Opts.MicrosoftExt) { 192353358Sdim Builder.defineMacro("_MSC_EXTENSIONS"); 193353358Sdim 194353358Sdim if (Opts.CPlusPlus11) { 195353358Sdim Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED"); 196353358Sdim Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED"); 197353358Sdim Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED"); 198353358Sdim } 199353358Sdim } 200353358Sdim 201353358Sdim Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); 202353358Sdim} 203353358Sdim 204353358Sdimvoid addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts, 205353358Sdim MacroBuilder &Builder) { 206353358Sdim Builder.defineMacro("_WIN32"); 207353358Sdim if (Triple.isArch64Bit()) 208353358Sdim Builder.defineMacro("_WIN64"); 209353358Sdim if (Triple.isWindowsGNUEnvironment()) 210353358Sdim addMinGWDefines(Triple, Opts, Builder); 211353358Sdim else if (Triple.isKnownWindowsMSVCEnvironment() || 212353358Sdim (Triple.isWindowsItaniumEnvironment() && Opts.MSVCCompat)) 213353358Sdim addVisualCDefines(Opts, Builder); 214353358Sdim} 215353358Sdim 216326941Sdim} // namespace targets 217326941Sdim} // namespace clang 218