[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