[clang] 809c6a5 - [Clang] Extract availability mapping from VersionMap for watchOS/tvOS
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 5 17:00:31 PST 2022
Author: Egor Zhdan
Date: 2022-01-05T17:00:03-08:00
New Revision: 809c6a5a1d2f4366ab0e602c9d963b73f380b74e
URL: https://github.com/llvm/llvm-project/commit/809c6a5a1d2f4366ab0e602c9d963b73f380b74e
DIFF: https://github.com/llvm/llvm-project/commit/809c6a5a1d2f4366ab0e602c9d963b73f380b74e.diff
LOG: [Clang] Extract availability mapping from VersionMap for watchOS/tvOS
This change makes it possible to extract iOS-to-another-platform version mappings from `VersionMap` in the `SDKSettings.json` file in Darwin SDKs, for example, `iOS_watchOS` and `iOS_tvOS`.
This code was originally authored by Alex Lorenz.
rdar://81491680
Differential Revision: https://reviews.llvm.org/D116615
Added:
Modified:
clang/lib/Basic/DarwinSDKInfo.cpp
clang/unittests/Basic/DarwinSDKInfoTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Basic/DarwinSDKInfo.cpp b/clang/lib/Basic/DarwinSDKInfo.cpp
index fe35f77782c92..64bcb45a4cd85 100644
--- a/clang/lib/Basic/DarwinSDKInfo.cpp
+++ b/clang/lib/Basic/DarwinSDKInfo.cpp
@@ -84,6 +84,25 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>>
VersionMappings;
if (const auto *VM = Obj->getObject("VersionMap")) {
+ // FIXME: Generalize this out beyond iOS-deriving targets.
+ // Look for ios_<targetos> version mapping for targets that derive from ios.
+ for (const auto &KV : *VM) {
+ auto Pair = StringRef(KV.getFirst()).split("_");
+ if (Pair.first.compare_insensitive("ios") == 0) {
+ llvm::Triple TT(llvm::Twine("--") + Pair.second.lower());
+ if (TT.getOS() != llvm::Triple::UnknownOS) {
+ auto Mapping = RelatedTargetVersionMapping::parseJSON(
+ *KV.getSecond().getAsObject(), *MaximumDeploymentVersion);
+ if (Mapping)
+ VersionMappings[OSEnvPair(llvm::Triple::IOS,
+ llvm::Triple::UnknownEnvironment,
+ TT.getOS(),
+ llvm::Triple::UnknownEnvironment)
+ .Value] = std::move(Mapping);
+ }
+ }
+ }
+
if (const auto *Mapping = VM->getObject("macOS_iOSMac")) {
auto VersionMap = RelatedTargetVersionMapping::parseJSON(
*Mapping, *MaximumDeploymentVersion);
diff --git a/clang/unittests/Basic/DarwinSDKInfoTest.cpp b/clang/unittests/Basic/DarwinSDKInfoTest.cpp
index f845e1536da8a..aa1feeb293c0e 100644
--- a/clang/unittests/Basic/DarwinSDKInfoTest.cpp
+++ b/clang/unittests/Basic/DarwinSDKInfoTest.cpp
@@ -13,7 +13,68 @@
using namespace llvm;
using namespace clang;
-TEST(DarwinSDKInfoTest, ParseAndTestMapping) {
+// Check the version mapping logic in DarwinSDKInfo.
+TEST(DarwinSDKInfo, VersionMapping) {
+ llvm::json::Object Obj({{"3.0", "1.0"}, {"3.1", "1.2"}});
+ Optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping =
+ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj,
+ VersionTuple());
+ EXPECT_TRUE(Mapping.hasValue());
+ EXPECT_EQ(Mapping->getMinimumValue(), VersionTuple(1));
+
+ // Exact mapping.
+ EXPECT_EQ(Mapping->map(VersionTuple(3), VersionTuple(0, 1), None),
+ VersionTuple(1));
+ EXPECT_EQ(Mapping->map(VersionTuple(3, 0), VersionTuple(0, 1), None),
+ VersionTuple(1));
+ EXPECT_EQ(Mapping->map(VersionTuple(3, 0, 0), VersionTuple(0, 1), None),
+ VersionTuple(1));
+ EXPECT_EQ(Mapping->map(VersionTuple(3, 1), VersionTuple(0, 1), None),
+ VersionTuple(1, 2));
+ EXPECT_EQ(Mapping->map(VersionTuple(3, 1, 0), VersionTuple(0, 1), None),
+ VersionTuple(1, 2));
+
+ // Missing mapping - fallback to major.
+ EXPECT_EQ(Mapping->map(VersionTuple(3, 0, 1), VersionTuple(0, 1), None),
+ VersionTuple(1));
+
+ // Minimum
+ EXPECT_EQ(Mapping->map(VersionTuple(2), VersionTuple(0, 1), None),
+ VersionTuple(0, 1));
+
+ // Maximum
+ EXPECT_EQ(
+ Mapping->map(VersionTuple(4), VersionTuple(0, 1), VersionTuple(100)),
+ VersionTuple(100));
+}
+
+// Check the version mapping logic in DarwinSDKInfo.
+TEST(DarwinSDKInfo, VersionMappingMissingKey) {
+ llvm::json::Object Obj({{"3.0", "1.0"}, {"5.0", "1.2"}});
+ Optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping =
+ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj,
+ VersionTuple());
+ EXPECT_TRUE(Mapping.hasValue());
+ EXPECT_EQ(
+ Mapping->map(VersionTuple(4), VersionTuple(0, 1), VersionTuple(100)),
+ None);
+}
+
+TEST(DarwinSDKInfo, VersionMappingParseEmpty) {
+ llvm::json::Object Obj({});
+ EXPECT_FALSE(
+ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, VersionTuple())
+ .hasValue());
+}
+
+TEST(DarwinSDKInfo, VersionMappingParseError) {
+ llvm::json::Object Obj({{"test", "1.2"}});
+ EXPECT_FALSE(
+ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, VersionTuple())
+ .hasValue());
+}
+
+TEST(DarwinSDKInfoTest, ParseAndTestMappingMacCatalyst) {
llvm::json::Object Obj;
Obj["Version"] = "11.0";
Obj["MaximumDeploymentTarget"] = "11.99";
@@ -58,6 +119,51 @@ TEST(DarwinSDKInfoTest, ParseAndTestMapping) {
VersionTuple(99, 99));
}
+TEST(DarwinSDKInfoTest, ParseAndTestMappingIOSDerived) {
+ llvm::json::Object Obj;
+ Obj["Version"] = "15.0";
+ Obj["MaximumDeploymentTarget"] = "15.0.99";
+ llvm::json::Object VersionMap;
+ VersionMap["10.0"] = "10.0";
+ VersionMap["10.3.1"] = "10.2";
+ VersionMap["11.0"] = "11.0";
+ llvm::json::Object IOSToTvOS;
+ IOSToTvOS["iOS_tvOS"] = std::move(VersionMap);
+ Obj["VersionMap"] = std::move(IOSToTvOS);
+
+ auto SDKInfo = DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj);
+ ASSERT_TRUE(SDKInfo);
+ EXPECT_EQ(SDKInfo->getVersion(), VersionTuple(15, 0));
+
+ // Verify that mapping is present for platforms that derive from iOS.
+ const auto *Mapping = SDKInfo->getVersionMapping(DarwinSDKInfo::OSEnvPair(
+ llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, llvm::Triple::TvOS,
+ llvm::Triple::UnknownEnvironment));
+ ASSERT_TRUE(Mapping);
+
+ // Verify that the iOS versions that are present in the map are translated
+ // directly to their corresponding tvOS versions.
+ EXPECT_EQ(*Mapping->map(VersionTuple(10, 0), VersionTuple(), None),
+ VersionTuple(10, 0));
+ EXPECT_EQ(*Mapping->map(VersionTuple(10, 3, 1), VersionTuple(), None),
+ VersionTuple(10, 2));
+ EXPECT_EQ(*Mapping->map(VersionTuple(11, 0), VersionTuple(), None),
+ VersionTuple(11, 0));
+
+ // Verify that an iOS version that's not present in the map is translated
+ // like the nearest major OS version.
+ EXPECT_EQ(*Mapping->map(VersionTuple(10, 1), VersionTuple(), None),
+ VersionTuple(10, 0));
+
+ // Verify that the iOS versions that are outside of the mapped version
+ // range map to the min/max values passed to the `map` call.
+ EXPECT_EQ(*Mapping->map(VersionTuple(9, 0), VersionTuple(99, 99), None),
+ VersionTuple(99, 99));
+ EXPECT_EQ(
+ *Mapping->map(VersionTuple(13, 0), VersionTuple(), VersionTuple(99, 99)),
+ VersionTuple(99, 99));
+}
+
TEST(DarwinSDKInfoTest, MissingKeys) {
llvm::json::Object Obj;
ASSERT_FALSE(DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj));
More information about the cfe-commits
mailing list