Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:48

0001 //===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_BASIC_DARWINSDKINFO_H
0010 #define LLVM_CLANG_BASIC_DARWINSDKINFO_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "llvm/ADT/DenseMap.h"
0014 #include "llvm/Support/Error.h"
0015 #include "llvm/Support/VersionTuple.h"
0016 #include "llvm/Support/VirtualFileSystem.h"
0017 #include "llvm/TargetParser/Triple.h"
0018 #include <optional>
0019 
0020 namespace llvm {
0021 namespace json {
0022 class Object;
0023 } // end namespace json
0024 } // end namespace llvm
0025 
0026 namespace clang {
0027 
0028 /// The information about the darwin SDK that was used during this compilation.
0029 class DarwinSDKInfo {
0030 public:
0031   /// A value that describes two os-environment pairs that can be used as a key
0032   /// to the version map in the SDK.
0033   struct OSEnvPair {
0034   public:
0035     using StorageType = uint64_t;
0036 
0037     constexpr OSEnvPair(llvm::Triple::OSType FromOS,
0038                         llvm::Triple::EnvironmentType FromEnv,
0039                         llvm::Triple::OSType ToOS,
0040                         llvm::Triple::EnvironmentType ToEnv)
0041         : Value(((StorageType(FromOS) * StorageType(llvm::Triple::LastOSType) +
0042                   StorageType(FromEnv))
0043                  << 32ull) |
0044                 (StorageType(ToOS) * StorageType(llvm::Triple::LastOSType) +
0045                  StorageType(ToEnv))) {}
0046 
0047     /// Returns the os-environment mapping pair that's used to represent the
0048     /// macOS -> Mac Catalyst version mapping.
0049     static inline constexpr OSEnvPair macOStoMacCatalystPair() {
0050       return OSEnvPair(llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment,
0051                        llvm::Triple::IOS, llvm::Triple::MacABI);
0052     }
0053 
0054     /// Returns the os-environment mapping pair that's used to represent the
0055     /// Mac Catalyst -> macOS version mapping.
0056     static inline constexpr OSEnvPair macCatalystToMacOSPair() {
0057       return OSEnvPair(llvm::Triple::IOS, llvm::Triple::MacABI,
0058                        llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
0059     }
0060 
0061     /// Returns the os-environment mapping pair that's used to represent the
0062     /// iOS -> watchOS version mapping.
0063     static inline constexpr OSEnvPair iOStoWatchOSPair() {
0064       return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
0065                        llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment);
0066     }
0067 
0068     /// Returns the os-environment mapping pair that's used to represent the
0069     /// iOS -> tvOS version mapping.
0070     static inline constexpr OSEnvPair iOStoTvOSPair() {
0071       return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
0072                        llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
0073     }
0074 
0075   private:
0076     StorageType Value;
0077 
0078     friend class DarwinSDKInfo;
0079   };
0080 
0081   /// Represents a version mapping that maps from a version of one target to a
0082   /// version of a related target.
0083   ///
0084   /// e.g. "macOS_iOSMac":{"10.15":"13.1"} is an example of a macOS -> Mac
0085   /// Catalyst version map.
0086   class RelatedTargetVersionMapping {
0087   public:
0088     RelatedTargetVersionMapping(
0089         VersionTuple MinimumKeyVersion, VersionTuple MaximumKeyVersion,
0090         VersionTuple MinimumValue, VersionTuple MaximumValue,
0091         llvm::DenseMap<VersionTuple, VersionTuple> Mapping)
0092         : MinimumKeyVersion(MinimumKeyVersion),
0093           MaximumKeyVersion(MaximumKeyVersion), MinimumValue(MinimumValue),
0094           MaximumValue(MaximumValue), Mapping(Mapping) {
0095       assert(!this->Mapping.empty() && "unexpected empty mapping");
0096     }
0097 
0098     /// Returns the value with the lowest version in the mapping.
0099     const VersionTuple &getMinimumValue() const { return MinimumValue; }
0100 
0101     /// Returns the mapped key, or the appropriate Minimum / MaximumValue if
0102     /// they key is outside of the mapping bounds. If they key isn't mapped, but
0103     /// within the minimum and maximum bounds, std::nullopt is returned.
0104     std::optional<VersionTuple>
0105     map(const VersionTuple &Key, const VersionTuple &MinimumValue,
0106         std::optional<VersionTuple> MaximumValue) const;
0107 
0108     /// Remap the 'introduced' availability version.
0109     /// If None is returned, the 'unavailable' availability should be used
0110     /// instead.
0111     std::optional<VersionTuple>
0112     mapIntroducedAvailabilityVersion(const VersionTuple &Key) const {
0113       // API_TO_BE_DEPRECATED is 100000.
0114       if (Key.getMajor() == 100000)
0115         return VersionTuple(100000);
0116       // Use None for maximum to force unavailable behavior for
0117       return map(Key, MinimumValue, std::nullopt);
0118     }
0119 
0120     /// Remap the 'deprecated' and 'obsoleted' availability version.
0121     /// If None is returned for 'obsoleted', the 'unavailable' availability
0122     /// should be used instead. If None is returned for 'deprecated', the
0123     /// 'deprecated' version should be dropped.
0124     std::optional<VersionTuple>
0125     mapDeprecatedObsoletedAvailabilityVersion(const VersionTuple &Key) const {
0126       // API_TO_BE_DEPRECATED is 100000.
0127       if (Key.getMajor() == 100000)
0128         return VersionTuple(100000);
0129       return map(Key, MinimumValue, MaximumValue);
0130     }
0131 
0132     static std::optional<RelatedTargetVersionMapping>
0133     parseJSON(const llvm::json::Object &Obj,
0134               VersionTuple MaximumDeploymentTarget);
0135 
0136   private:
0137     VersionTuple MinimumKeyVersion;
0138     VersionTuple MaximumKeyVersion;
0139     VersionTuple MinimumValue;
0140     VersionTuple MaximumValue;
0141     llvm::DenseMap<VersionTuple, VersionTuple> Mapping;
0142   };
0143 
0144   DarwinSDKInfo(
0145       VersionTuple Version, VersionTuple MaximumDeploymentTarget,
0146       llvm::DenseMap<OSEnvPair::StorageType,
0147                      std::optional<RelatedTargetVersionMapping>>
0148           VersionMappings =
0149               llvm::DenseMap<OSEnvPair::StorageType,
0150                              std::optional<RelatedTargetVersionMapping>>())
0151       : Version(Version), MaximumDeploymentTarget(MaximumDeploymentTarget),
0152         VersionMappings(std::move(VersionMappings)) {}
0153 
0154   const llvm::VersionTuple &getVersion() const { return Version; }
0155 
0156   // Returns the optional, target-specific version mapping that maps from one
0157   // target to another target.
0158   //
0159   // This mapping is constructed from an appropriate mapping in the SDKSettings,
0160   // for instance, when building for Mac Catalyst, the mapping would contain the
0161   // "macOS_iOSMac" mapping as it maps the macOS versions to the Mac Catalyst
0162   // versions.
0163   //
0164   // This mapping does not exist when the target doesn't have an appropriate
0165   // related version mapping, or when there was an error reading the mapping
0166   // from the SDKSettings, or when it's missing in the SDKSettings.
0167   const RelatedTargetVersionMapping *getVersionMapping(OSEnvPair Kind) const {
0168     auto Mapping = VersionMappings.find(Kind.Value);
0169     if (Mapping == VersionMappings.end())
0170       return nullptr;
0171     return Mapping->getSecond() ? &*Mapping->getSecond() : nullptr;
0172   }
0173 
0174   static std::optional<DarwinSDKInfo>
0175   parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj);
0176 
0177 private:
0178   VersionTuple Version;
0179   VersionTuple MaximumDeploymentTarget;
0180   // Need to wrap the value in an optional here as the value has to be default
0181   // constructible, and std::unique_ptr doesn't like DarwinSDKInfo being
0182   // Optional as Optional is trying to copy it in emplace.
0183   llvm::DenseMap<OSEnvPair::StorageType,
0184                  std::optional<RelatedTargetVersionMapping>>
0185       VersionMappings;
0186 };
0187 
0188 /// Parse the SDK information from the SDKSettings.json file.
0189 ///
0190 /// \returns an error if the SDKSettings.json file is invalid, std::nullopt if
0191 /// the SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
0192 Expected<std::optional<DarwinSDKInfo>>
0193 parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath);
0194 
0195 } // end namespace clang
0196 
0197 #endif // LLVM_CLANG_BASIC_DARWINSDKINFO_H