blob: df16827debfc072fbb368d8d479c240088c7b8f4 [file] [log] [blame]
//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_DARWINSDKINFO_H
#define LLVM_CLANG_BASIC_DARWINSDKINFO_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
namespace llvm {
namespace json {
class Object;
} // end namespace json
} // end namespace llvm
namespace clang {
/// The information about the darwin SDK that was used during this compilation.
class DarwinSDKInfo {
public:
/// A value that describes two os-environment pairs that can be used as a key
/// to the version map in the SDK.
struct OSEnvPair {
public:
using StorageType = uint64_t;
constexpr OSEnvPair(llvm::Triple::OSType FromOS,
llvm::Triple::EnvironmentType FromEnv,
llvm::Triple::OSType ToOS,
llvm::Triple::EnvironmentType ToEnv)
: Value(((StorageType(FromOS) * StorageType(llvm::Triple::LastOSType) +
StorageType(FromEnv))
<< 32ull) |
(StorageType(ToOS) * StorageType(llvm::Triple::LastOSType) +
StorageType(ToEnv))) {}
/// Returns the os-environment mapping pair that's used to represent the
/// macOS -> Mac Catalyst version mapping.
static inline constexpr OSEnvPair macOStoMacCatalystPair() {
return OSEnvPair(llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment,
llvm::Triple::IOS, llvm::Triple::MacABI);
}
/// Returns the os-environment mapping pair that's used to represent the
/// Mac Catalyst -> macOS version mapping.
static inline constexpr OSEnvPair macCatalystToMacOSPair() {
return OSEnvPair(llvm::Triple::IOS, llvm::Triple::MacABI,
llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
}
/// Returns the os-environment mapping pair that's used to represent the
/// iOS -> watchOS version mapping.
static inline constexpr OSEnvPair iOStoWatchOSPair() {
return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment);
}
/// Returns the os-environment mapping pair that's used to represent the
/// iOS -> tvOS version mapping.
static inline constexpr OSEnvPair iOStoTvOSPair() {
return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
}
private:
StorageType Value;
friend class DarwinSDKInfo;
};
/// Represents a version mapping that maps from a version of one target to a
/// version of a related target.
///
/// e.g. "macOS_iOSMac":{"10.15":"13.1"} is an example of a macOS -> Mac
/// Catalyst version map.
class RelatedTargetVersionMapping {
public:
RelatedTargetVersionMapping(
VersionTuple MinimumKeyVersion, VersionTuple MaximumKeyVersion,
VersionTuple MinimumValue, VersionTuple MaximumValue,
llvm::DenseMap<VersionTuple, VersionTuple> Mapping)
: MinimumKeyVersion(MinimumKeyVersion),
MaximumKeyVersion(MaximumKeyVersion), MinimumValue(MinimumValue),
MaximumValue(MaximumValue), Mapping(Mapping) {
assert(!this->Mapping.empty() && "unexpected empty mapping");
}
/// Returns the value with the lowest version in the mapping.
const VersionTuple &getMinimumValue() const { return MinimumValue; }
/// Returns the mapped key, or the appropriate Minimum / MaximumValue if
/// they key is outside of the mapping bounds. If they key isn't mapped, but
/// within the minimum and maximum bounds, None is returned.
Optional<VersionTuple> map(const VersionTuple &Key,
const VersionTuple &MinimumValue,
Optional<VersionTuple> MaximumValue) const;
static Optional<RelatedTargetVersionMapping>
parseJSON(const llvm::json::Object &Obj,
VersionTuple MaximumDeploymentTarget);
private:
VersionTuple MinimumKeyVersion;
VersionTuple MaximumKeyVersion;
VersionTuple MinimumValue;
VersionTuple MaximumValue;
llvm::DenseMap<VersionTuple, VersionTuple> Mapping;
};
DarwinSDKInfo(VersionTuple Version, VersionTuple MaximumDeploymentTarget,
llvm::DenseMap<OSEnvPair::StorageType,
Optional<RelatedTargetVersionMapping>>
VersionMappings =
llvm::DenseMap<OSEnvPair::StorageType,
Optional<RelatedTargetVersionMapping>>())
: Version(Version), MaximumDeploymentTarget(MaximumDeploymentTarget),
VersionMappings(std::move(VersionMappings)) {}
const llvm::VersionTuple &getVersion() const { return Version; }
// Returns the optional, target-specific version mapping that maps from one
// target to another target.
//
// This mapping is constructed from an appropriate mapping in the SDKSettings,
// for instance, when building for Mac Catalyst, the mapping would contain the
// "macOS_iOSMac" mapping as it maps the macOS versions to the Mac Catalyst
// versions.
//
// This mapping does not exist when the target doesn't have an appropriate
// related version mapping, or when there was an error reading the mapping
// from the SDKSettings, or when it's missing in the SDKSettings.
const RelatedTargetVersionMapping *getVersionMapping(OSEnvPair Kind) const {
auto Mapping = VersionMappings.find(Kind.Value);
if (Mapping == VersionMappings.end())
return nullptr;
return Mapping->getSecond().hasValue() ? Mapping->getSecond().getPointer()
: nullptr;
}
static Optional<DarwinSDKInfo>
parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj);
private:
VersionTuple Version;
VersionTuple MaximumDeploymentTarget;
// Need to wrap the value in an optional here as the value has to be default
// constructible, and std::unique_ptr doesn't like DarwinSDKInfo being
// Optional as Optional is trying to copy it in emplace.
llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>>
VersionMappings;
};
/// Parse the SDK information from the SDKSettings.json file.
///
/// \returns an error if the SDKSettings.json file is invalid, None if the
/// SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS,
StringRef SDKRootPath);
} // end namespace clang
#endif // LLVM_CLANG_BASIC_DARWINSDKINFO_H