Clang Project

clang_source_code/lib/Basic/Targets/OSTargets.cpp
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
16using namespace clang;
17using namespace clang::targets;
18
19namespace clang {
20namespace targets {
21
22void getDarwinDefines(MacroBuilder &Builderconst LangOptions &Opts,
23                      const llvm::Triple &TripleStringRef &PlatformName,
24                      VersionTuple &PlatformMinVersion) {
25  Builder.defineMacro("__APPLE_CC__""6000");
26  Builder.defineMacro("__APPLE__");
27  Builder.defineMacro("__STDC_NO_THREADS__");
28  Builder.defineMacro("OBJC_NEW_PROPERTIES");
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 MajMinRev;
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(MajMinRev);
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(MajMinRev);
136}
137// namespace targets
138// namespace clang
139