clang 24.0.0git
DarwinSDKInfo.h
Go to the documentation of this file.
1//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===//
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#ifndef LLVM_CLANG_BASIC_DARWINSDKINFO_H
10#define LLVM_CLANG_BASIC_DARWINSDKINFO_H
11
12#include "clang/Basic/LLVM.h"
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Error.h"
18#include "llvm/Support/VersionTuple.h"
19#include "llvm/Support/VirtualFileSystem.h"
20#include "llvm/TargetParser/Triple.h"
21#include <cassert>
22#include <optional>
23#include <string>
24
25namespace llvm {
26namespace json {
27class Object;
28} // end namespace json
29} // end namespace llvm
30
31namespace clang {
32
33/// The information about the darwin SDK that was used during this compilation.
35public:
36 /// Information about the supported platforms, derived from the target triple
37 /// definitions, in the SDK.
39 public:
41
42 SDKPlatformInfo(TripleStorageType Triples, StringRef PlatformPrefix)
43 : Triples(std::move(Triples)), PlatformPrefix(PlatformPrefix) {
44 assert(!this->Triples.empty() && "Triples cannot be empty");
45 }
46
47 const TripleStorageType &getTriples() const { return Triples; }
48 StringRef getPlatformPrefix() const { return PlatformPrefix; }
49
50 private:
51 TripleStorageType Triples;
52 std::string PlatformPrefix;
53 };
54
55 /// A value that describes two os-environment pairs that can be used as a key
56 /// to the version map in the SDK.
57 struct OSEnvPair {
58 public:
59 using StorageType = uint64_t;
60
61 constexpr OSEnvPair(llvm::Triple::OSType FromOS,
62 llvm::Triple::EnvironmentType FromEnv,
63 llvm::Triple::OSType ToOS,
64 llvm::Triple::EnvironmentType ToEnv)
65 : Value(((StorageType(FromOS) * StorageType(llvm::Triple::LastOSType) +
66 StorageType(FromEnv))
67 << 32ull) |
68 (StorageType(ToOS) * StorageType(llvm::Triple::LastOSType) +
69 StorageType(ToEnv))) {}
70
71 /// Returns the os-environment mapping pair that's used to represent the
72 /// macOS -> Mac Catalyst version mapping.
73 static inline constexpr OSEnvPair macOStoMacCatalystPair() {
74 return OSEnvPair(llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment,
75 llvm::Triple::IOS, llvm::Triple::MacABI);
76 }
77
78 /// Returns the os-environment mapping pair that's used to represent the
79 /// Mac Catalyst -> macOS version mapping.
80 static inline constexpr OSEnvPair macCatalystToMacOSPair() {
81 return OSEnvPair(llvm::Triple::IOS, llvm::Triple::MacABI,
82 llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
83 }
84
85 /// Returns the os-environment mapping pair that's used to represent the
86 /// iOS -> watchOS version mapping.
87 static inline constexpr OSEnvPair iOStoWatchOSPair() {
88 return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
89 llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment);
90 }
91
92 /// Returns the os-environment mapping pair that's used to represent the
93 /// iOS -> tvOS version mapping.
94 static inline constexpr OSEnvPair iOStoTvOSPair() {
95 return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
96 llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
97 }
98
99 private:
101
102 friend class DarwinSDKInfo;
103 };
104
105 /// Represents a version mapping that maps from a version of one target to a
106 /// version of a related target.
107 ///
108 /// e.g. "macOS_iOSMac":{"10.15":"13.1"} is an example of a macOS -> Mac
109 /// Catalyst version map.
111 public:
113 VersionTuple MinimumKeyVersion, VersionTuple MaximumKeyVersion,
114 VersionTuple MinimumValue, VersionTuple MaximumValue,
115 llvm::DenseMap<VersionTuple, VersionTuple> Mapping)
116 : MinimumKeyVersion(MinimumKeyVersion),
117 MaximumKeyVersion(MaximumKeyVersion), MinimumValue(MinimumValue),
118 MaximumValue(MaximumValue), Mapping(Mapping) {
119 assert(!this->Mapping.empty() && "unexpected empty mapping");
120 }
121
122 /// Returns the value with the lowest version in the mapping.
123 const VersionTuple &getMinimumValue() const { return MinimumValue; }
124
125 /// Returns the mapped key, or the appropriate Minimum / MaximumValue if
126 /// they key is outside of the mapping bounds. If they key isn't mapped, but
127 /// within the minimum and maximum bounds, std::nullopt is returned.
128 std::optional<VersionTuple>
129 map(const VersionTuple &Key, const VersionTuple &MinimumValue,
130 std::optional<VersionTuple> MaximumValue) const;
131
132 /// Remap the 'introduced' availability version.
133 /// If None is returned, the 'unavailable' availability should be used
134 /// instead.
135 std::optional<VersionTuple>
136 mapIntroducedAvailabilityVersion(const VersionTuple &Key) const {
137 // API_TO_BE_DEPRECATED is 100000.
138 if (Key.getMajor() == 100000)
139 return VersionTuple(100000);
140 // Use None for maximum to force unavailable behavior for
141 return map(Key, MinimumValue, std::nullopt);
142 }
143
144 /// Remap the 'deprecated' and 'obsoleted' availability version.
145 /// If None is returned for 'obsoleted', the 'unavailable' availability
146 /// should be used instead. If None is returned for 'deprecated', the
147 /// 'deprecated' version should be dropped.
148 std::optional<VersionTuple>
149 mapDeprecatedObsoletedAvailabilityVersion(const VersionTuple &Key) const {
150 // API_TO_BE_DEPRECATED is 100000.
151 if (Key.getMajor() == 100000)
152 return VersionTuple(100000);
153 return map(Key, MinimumValue, MaximumValue);
154 }
155
156 static std::optional<RelatedTargetVersionMapping>
157 parseJSON(const llvm::json::Object &Obj,
158 VersionTuple MaximumDeploymentTarget);
159
160 private:
161 VersionTuple MinimumKeyVersion;
162 VersionTuple MaximumKeyVersion;
163 VersionTuple MinimumValue;
164 VersionTuple MaximumValue;
165 llvm::DenseMap<VersionTuple, VersionTuple> Mapping;
166 };
167
169
171 std::string FilePath, llvm::Triple::OSType OS,
172 llvm::Triple::EnvironmentType Environment, VersionTuple Version,
173 StringRef DisplayName, VersionTuple DefaultDeploymentTarget,
174 VersionTuple MaximumDeploymentTarget,
175 PlatformInfoStorageType PlatformInfos,
176 llvm::DenseMap<OSEnvPair::StorageType,
177 std::optional<RelatedTargetVersionMapping>>
178 VersionMappings =
179 llvm::DenseMap<OSEnvPair::StorageType,
180 std::optional<RelatedTargetVersionMapping>>())
181 : FilePath(std::move(FilePath)), OS(OS), Environment(Environment),
182 Version(Version), DisplayName(DisplayName),
183 DefaultDeploymentTarget(DefaultDeploymentTarget),
184 MaximumDeploymentTarget(MaximumDeploymentTarget),
185 PlatformInfos(std::move(PlatformInfos)),
186 VersionMappings(std::move(VersionMappings)) {
187 assert(!this->PlatformInfos.empty() && "PlatformInfos cannot be empty");
188 }
189
190 /// Construct SDK Info inferred from the parameters rather than read from
191 /// SDKSettings.json.
192 ///
193 /// This will infer \c PlatformInfos from an SDK for the OS/Environment that
194 /// predates the introduction of SDKSettings.json, and will not infer version
195 /// mappings.
196 DarwinSDKInfo(llvm::Triple::OSType OS,
197 llvm::Triple::EnvironmentType Environment, VersionTuple Version,
198 StringRef DisplayName, VersionTuple MaximumDeploymentTarget);
199
200 StringRef getFilePath() const { return FilePath; }
201
202 llvm::Triple::OSType getOS() const { return OS; }
203
204 llvm::Triple::EnvironmentType getEnvironment() const { return Environment; }
205
206 const llvm::VersionTuple &getVersion() const { return Version; }
207
208 const llvm::VersionTuple &getDefaultDeploymentTarget() const {
209 return DefaultDeploymentTarget;
210 }
211
212 const StringRef getDisplayName() const { return DisplayName; }
213
214 const llvm::Triple &getCanonicalPlatformTriple() const {
215 return PlatformInfos[0].getTriples()[0];
216 }
217
218 bool supportsTriple(const llvm::Triple &Triple) const;
219
220 StringRef getPlatformPrefix(const llvm::Triple &Triple) const;
221
222 // Returns the optional, target-specific version mapping that maps from one
223 // target to another target.
224 //
225 // This mapping is constructed from an appropriate mapping in the SDKSettings,
226 // for instance, when building for Mac Catalyst, the mapping would contain the
227 // "macOS_iOSMac" mapping as it maps the macOS versions to the Mac Catalyst
228 // versions.
229 //
230 // This mapping does not exist when the target doesn't have an appropriate
231 // related version mapping, or when there was an error reading the mapping
232 // from the SDKSettings, or when it's missing in the SDKSettings.
234 auto Mapping = VersionMappings.find(Kind.Value);
235 if (Mapping == VersionMappings.end())
236 return nullptr;
237 return Mapping->getSecond() ? &*Mapping->getSecond() : nullptr;
238 }
239
240 static std::optional<DarwinSDKInfo>
241 parseDarwinSDKSettingsJSON(std::string FilePath,
242 const llvm::json::Object *Obj);
243
244private:
245 std::string FilePath;
246 llvm::Triple::OSType OS;
247 llvm::Triple::EnvironmentType Environment;
248 VersionTuple Version;
249 std::string DisplayName;
250 VersionTuple DefaultDeploymentTarget;
251 VersionTuple MaximumDeploymentTarget;
252 PlatformInfoStorageType PlatformInfos;
253 // Need to wrap the value in an optional here as the value has to be default
254 // constructible, and std::unique_ptr doesn't like DarwinSDKInfo being
255 // Optional as Optional is trying to copy it in emplace.
256 llvm::DenseMap<OSEnvPair::StorageType,
257 std::optional<RelatedTargetVersionMapping>>
258 VersionMappings;
259};
260
261/// Parse the SDK information from the SDKSettings.json file.
262///
263/// \returns an error if the SDKSettings.json file is invalid, std::nullopt if
264/// the SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
266parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath);
267
268} // end namespace clang
269
270#endif // LLVM_CLANG_BASIC_DARWINSDKINFO_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::json::Object Object
Represents a version mapping that maps from a version of one target to a version of a related target.
const VersionTuple & getMinimumValue() const
Returns the value with the lowest version in the mapping.
std::optional< VersionTuple > mapIntroducedAvailabilityVersion(const VersionTuple &Key) const
Remap the 'introduced' availability version.
std::optional< VersionTuple > map(const VersionTuple &Key, const VersionTuple &MinimumValue, std::optional< VersionTuple > MaximumValue) const
Returns the mapped key, or the appropriate Minimum / MaximumValue if they key is outside of the mappi...
RelatedTargetVersionMapping(VersionTuple MinimumKeyVersion, VersionTuple MaximumKeyVersion, VersionTuple MinimumValue, VersionTuple MaximumValue, llvm::DenseMap< VersionTuple, VersionTuple > Mapping)
std::optional< VersionTuple > mapDeprecatedObsoletedAvailabilityVersion(const VersionTuple &Key) const
Remap the 'deprecated' and 'obsoleted' availability version.
static std::optional< RelatedTargetVersionMapping > parseJSON(const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget)
static std::optional< DarwinSDKInfo > parseDarwinSDKSettingsJSON(std::string FilePath, const llvm::json::Object *Obj)
SmallVector< SDKPlatformInfo, 2 > PlatformInfoStorageType
const RelatedTargetVersionMapping * getVersionMapping(OSEnvPair Kind) const
StringRef getFilePath() const
llvm::Triple::EnvironmentType getEnvironment() const
const StringRef getDisplayName() const
const llvm::VersionTuple & getVersion() const
llvm::Triple::OSType getOS() const
DarwinSDKInfo(std::string FilePath, llvm::Triple::OSType OS, llvm::Triple::EnvironmentType Environment, VersionTuple Version, StringRef DisplayName, VersionTuple DefaultDeploymentTarget, VersionTuple MaximumDeploymentTarget, PlatformInfoStorageType PlatformInfos, llvm::DenseMap< OSEnvPair::StorageType, std::optional< RelatedTargetVersionMapping > > VersionMappings=llvm::DenseMap< OSEnvPair::StorageType, std::optional< RelatedTargetVersionMapping > >())
StringRef getPlatformPrefix(const llvm::Triple &Triple) const
const llvm::VersionTuple & getDefaultDeploymentTarget() const
bool supportsTriple(const llvm::Triple &Triple) const
const llvm::Triple & getCanonicalPlatformTriple() const
Top level wrappers for InstallAPI frontend operations.
Expected< std::optional< DarwinSDKInfo > > parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath)
Parse the SDK information from the SDKSettings.json file.
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
A value that describes two os-environment pairs that can be used as a key to the version map in the S...
static constexpr OSEnvPair macCatalystToMacOSPair()
Returns the os-environment mapping pair that's used to represent the Mac Catalyst -> macOS version ma...
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
static constexpr OSEnvPair iOStoWatchOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> watchOS version mapping.
static constexpr OSEnvPair iOStoTvOSPair()
Returns the os-environment mapping pair that's used to represent the iOS -> tvOS version mapping.
constexpr OSEnvPair(llvm::Triple::OSType FromOS, llvm::Triple::EnvironmentType FromEnv, llvm::Triple::OSType ToOS, llvm::Triple::EnvironmentType ToEnv)
const TripleStorageType & getTriples() const
SmallVector< llvm::Triple, 5 > TripleStorageType
SDKPlatformInfo(TripleStorageType Triples, StringRef PlatformPrefix)