clang  15.0.0git
DarwinSDKInfo.cpp
Go to the documentation of this file.
1 //===--- DarwinSDKInfo.cpp - SDK Information parser for darwin - ----------===//
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 
10 #include "llvm/Support/ErrorOr.h"
11 #include "llvm/Support/JSON.h"
12 #include "llvm/Support/MemoryBuffer.h"
13 #include "llvm/Support/Path.h"
14 
15 using namespace clang;
16 
18  const VersionTuple &Key, const VersionTuple &MinimumValue,
19  Optional<VersionTuple> MaximumValue) const {
20  if (Key < MinimumKeyVersion)
21  return MinimumValue;
22  if (Key > MaximumKeyVersion)
23  return MaximumValue;
24  auto KV = Mapping.find(Key.normalize());
25  if (KV != Mapping.end())
26  return KV->getSecond();
27  // If no exact entry found, try just the major key version. Only do so when
28  // a minor version number is present, to avoid recursing indefinitely into
29  // the major-only check.
30  if (Key.getMinor())
31  return map(VersionTuple(Key.getMajor()), MinimumValue, MaximumValue);
32  // If this a major only key, return None for a missing entry.
33  return None;
34 }
35 
38  const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget) {
39  VersionTuple Min = VersionTuple(std::numeric_limits<unsigned>::max());
40  VersionTuple Max = VersionTuple(0);
41  VersionTuple MinValue = Min;
42  llvm::DenseMap<VersionTuple, VersionTuple> Mapping;
43  for (const auto &KV : Obj) {
44  if (auto Val = KV.getSecond().getAsString()) {
45  llvm::VersionTuple KeyVersion;
46  llvm::VersionTuple ValueVersion;
47  if (KeyVersion.tryParse(KV.getFirst()) || ValueVersion.tryParse(*Val))
48  return None;
49  Mapping[KeyVersion.normalize()] = ValueVersion;
50  if (KeyVersion < Min)
51  Min = KeyVersion;
52  if (KeyVersion > Max)
53  Max = KeyVersion;
54  if (ValueVersion < MinValue)
55  MinValue = ValueVersion;
56  }
57  }
58  if (Mapping.empty())
59  return None;
61  Min, Max, MinValue, MaximumDeploymentTarget, std::move(Mapping));
62 }
63 
64 static Optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj,
65  StringRef Key) {
66  auto Value = Obj.getString(Key);
67  if (!Value)
68  return None;
69  VersionTuple Version;
70  if (Version.tryParse(*Value))
71  return None;
72  return Version;
73 }
74 
76 DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
77  auto Version = getVersionKey(*Obj, "Version");
78  if (!Version)
79  return None;
80  auto MaximumDeploymentVersion =
81  getVersionKey(*Obj, "MaximumDeploymentTarget");
82  if (!MaximumDeploymentVersion)
83  return None;
84  llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>>
85  VersionMappings;
86  if (const auto *VM = Obj->getObject("VersionMap")) {
87  // FIXME: Generalize this out beyond iOS-deriving targets.
88  // Look for ios_<targetos> version mapping for targets that derive from ios.
89  for (const auto &KV : *VM) {
90  auto Pair = StringRef(KV.getFirst()).split("_");
91  if (Pair.first.compare_insensitive("ios") == 0) {
92  llvm::Triple TT(llvm::Twine("--") + Pair.second.lower());
93  if (TT.getOS() != llvm::Triple::UnknownOS) {
95  *KV.getSecond().getAsObject(), *MaximumDeploymentVersion);
96  if (Mapping)
97  VersionMappings[OSEnvPair(llvm::Triple::IOS,
98  llvm::Triple::UnknownEnvironment,
99  TT.getOS(),
100  llvm::Triple::UnknownEnvironment)
101  .Value] = std::move(Mapping);
102  }
103  }
104  }
105 
106  if (const auto *Mapping = VM->getObject("macOS_iOSMac")) {
107  auto VersionMap = RelatedTargetVersionMapping::parseJSON(
108  *Mapping, *MaximumDeploymentVersion);
109  if (!VersionMap)
110  return None;
111  VersionMappings[OSEnvPair::macOStoMacCatalystPair().Value] =
112  std::move(VersionMap);
113  }
114  if (const auto *Mapping = VM->getObject("iOSMac_macOS")) {
115  auto VersionMap = RelatedTargetVersionMapping::parseJSON(
116  *Mapping, *MaximumDeploymentVersion);
117  if (!VersionMap)
118  return None;
119  VersionMappings[OSEnvPair::macCatalystToMacOSPair().Value] =
120  std::move(VersionMap);
121  }
122  }
123 
124  return DarwinSDKInfo(std::move(*Version),
125  std::move(*MaximumDeploymentVersion),
126  std::move(VersionMappings));
127 }
128 
130 clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) {
131  llvm::SmallString<256> Filepath = SDKRootPath;
132  llvm::sys::path::append(Filepath, "SDKSettings.json");
133  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
134  VFS.getBufferForFile(Filepath);
135  if (!File) {
136  // If the file couldn't be read, assume it just doesn't exist.
137  return None;
138  }
140  llvm::json::parse(File.get()->getBuffer());
141  if (!Result)
142  return Result.takeError();
143 
144  if (const auto *Obj = Result->getAsObject()) {
145  if (auto SDKInfo = DarwinSDKInfo::parseDarwinSDKSettingsJSON(Obj))
146  return std::move(SDKInfo);
147  }
148  return llvm::make_error<llvm::StringError>("invalid SDKSettings.json",
149  llvm::inconvertibleErrorCode());
150 }
clang::DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON
static Optional< RelatedTargetVersionMapping > parseJSON(const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget)
Definition: DarwinSDKInfo.cpp:37
clang::DarwinSDKInfo::RelatedTargetVersionMapping::map
Optional< VersionTuple > map(const VersionTuple &Key, const VersionTuple &MinimumValue, Optional< VersionTuple > MaximumValue) const
Returns the mapped key, or the appropriate Minimum / MaximumValue if they key is outside of the mappi...
Definition: DarwinSDKInfo.cpp:17
max
__DEVICE__ int max(int __a, int __b)
Definition: __clang_cuda_math.h:196
clang::DeclaratorContext::File
@ File
getVersionKey
static Optional< VersionTuple > getVersionKey(const llvm::json::Object &Obj, StringRef Key)
Definition: DarwinSDKInfo.cpp:64
clang::DarwinSDKInfo::DarwinSDKInfo
DarwinSDKInfo(VersionTuple Version, VersionTuple MaximumDeploymentTarget, llvm::DenseMap< OSEnvPair::StorageType, Optional< RelatedTargetVersionMapping >> VersionMappings=llvm::DenseMap< OSEnvPair::StorageType, Optional< RelatedTargetVersionMapping >>())
Definition: DarwinSDKInfo.h:119
llvm::Optional< VersionTuple >
clang::DarwinSDKInfo::OSEnvPair
A value that describes two os-environment pairs that can be used as a key to the version map in the S...
Definition: DarwinSDKInfo.h:32
llvm::Expected
Definition: LLVM.h:41
clang::DarwinSDKInfo::RelatedTargetVersionMapping
Represents a version mapping that maps from a version of one target to a version of a related target.
Definition: DarwinSDKInfo.h:85
llvm::SmallString
Definition: LLVM.h:37
clang::DarwinSDKInfo::parseDarwinSDKSettingsJSON
static Optional< DarwinSDKInfo > parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj)
Definition: DarwinSDKInfo.cpp:76
Value
Value
Definition: UninitializedValues.cpp:102
clang::DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair
static constexpr OSEnvPair macOStoMacCatalystPair()
Returns the os-environment mapping pair that's used to represent the macOS -> Mac Catalyst version ma...
Definition: DarwinSDKInfo.h:48
clang::DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair
static constexpr OSEnvPair macCatalystToMacOSPair()
Returns the os-environment mapping pair that's used to represent the Mac Catalyst -> macOS version ma...
Definition: DarwinSDKInfo.h:55
clang
Definition: CalledOnceCheck.h:17
DarwinSDKInfo.h
clang::parseDarwinSDKInfo
Expected< Optional< DarwinSDKInfo > > parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath)
Parse the SDK information from the SDKSettings.json file.
Definition: DarwinSDKInfo.cpp:130