diff options
Diffstat (limited to 'lib/Basic/Targets/OSTargets.cpp')
-rw-r--r-- | lib/Basic/Targets/OSTargets.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/Basic/Targets/OSTargets.cpp b/lib/Basic/Targets/OSTargets.cpp new file mode 100644 index 000000000000..50abd4ce0c8c --- /dev/null +++ b/lib/Basic/Targets/OSTargets.cpp @@ -0,0 +1,139 @@ +//===--- OSTargets.cpp - Implement OS target feature support --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements OS specific TargetInfo types. +//===----------------------------------------------------------------------===// + +#include "OSTargets.h" +#include "clang/Basic/MacroBuilder.h" +#include "llvm/ADT/StringRef.h" + +using namespace clang; +using namespace clang::targets; + +namespace clang { +namespace targets { + +void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, + const llvm::Triple &Triple, StringRef &PlatformName, + VersionTuple &PlatformMinVersion) { + Builder.defineMacro("__APPLE_CC__", "6000"); + Builder.defineMacro("__APPLE__"); + Builder.defineMacro("__STDC_NO_THREADS__"); + Builder.defineMacro("OBJC_NEW_PROPERTIES"); + // AddressSanitizer doesn't play well with source fortification, which is on + // by default on Darwin. + if (Opts.Sanitize.has(SanitizerKind::Address)) + Builder.defineMacro("_FORTIFY_SOURCE", "0"); + + // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode. + if (!Opts.ObjC1) { + // __weak is always defined, for use in blocks and with objc pointers. + Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); + Builder.defineMacro("__strong", ""); + Builder.defineMacro("__unsafe_unretained", ""); + } + + if (Opts.Static) + Builder.defineMacro("__STATIC__"); + else + Builder.defineMacro("__DYNAMIC__"); + + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + + // Get the platform type and version number from the triple. + unsigned Maj, Min, Rev; + if (Triple.isMacOSX()) { + Triple.getMacOSXVersion(Maj, Min, Rev); + PlatformName = "macos"; + } else { + Triple.getOSVersion(Maj, Min, Rev); + PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); + } + + // If -target arch-pc-win32-macho option specified, we're + // generating code for Win32 ABI. No need to emit + // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. + if (PlatformName == "win32") { + PlatformMinVersion = VersionTuple(Maj, Min, Rev); + return; + } + + // Set the appropriate OS version define. + if (Triple.isiOS()) { + assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[7]; + if (Maj < 10) { + Str[0] = '0' + Maj; + Str[1] = '0' + (Min / 10); + Str[2] = '0' + (Min % 10); + Str[3] = '0' + (Rev / 10); + Str[4] = '0' + (Rev % 10); + Str[5] = '\0'; + } else { + // Handle versions >= 10. + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + (Min / 10); + Str[3] = '0' + (Min % 10); + Str[4] = '0' + (Rev / 10); + Str[5] = '0' + (Rev % 10); + Str[6] = '\0'; + } + if (Triple.isTvOS()) + Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); + else + Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", + Str); + + } else if (Triple.isWatchOS()) { + assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[6]; + Str[0] = '0' + Maj; + Str[1] = '0' + (Min / 10); + Str[2] = '0' + (Min % 10); + Str[3] = '0' + (Rev / 10); + Str[4] = '0' + (Rev % 10); + Str[5] = '\0'; + Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); + } else if (Triple.isMacOSX()) { + // Note that the Driver allows versions which aren't representable in the + // define (because we only get a single digit for the minor and micro + // revision numbers). So, we limit them to the maximum representable + // version. + assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[7]; + if (Maj < 10 || (Maj == 10 && Min < 10)) { + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + std::min(Min, 9U); + Str[3] = '0' + std::min(Rev, 9U); + Str[4] = '\0'; + } else { + // Handle versions > 10.9. + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + (Min / 10); + Str[3] = '0' + (Min % 10); + Str[4] = '0' + (Rev / 10); + Str[5] = '0' + (Rev % 10); + Str[6] = '\0'; + } + Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); + } + + // Tell users about the kernel if there is one. + if (Triple.isOSDarwin()) + Builder.defineMacro("__MACH__"); + + PlatformMinVersion = VersionTuple(Maj, Min, Rev); +} +} // namespace targets +} // namespace clang |