diff options
Diffstat (limited to 'clang/include/clang/Basic/DarwinSDKInfo.h')
-rw-r--r-- | clang/include/clang/Basic/DarwinSDKInfo.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h new file mode 100644 index 000000000000..918dc7c8becc --- /dev/null +++ b/clang/include/clang/Basic/DarwinSDKInfo.h @@ -0,0 +1,157 @@ +//===--- 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_DARWIN_SDK_INFO_H +#define LLVM_CLANG_BASIC_DARWIN_SDK_INFO_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); + } + + 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_DARWIN_SDK_INFO_H |