egorzhdan created this revision.
Herald added a subscriber: dexonsmith.
egorzhdan requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116615

Files:
  clang/lib/Basic/DarwinSDKInfo.cpp
  clang/unittests/Basic/DarwinSDKInfoTest.cpp

Index: clang/unittests/Basic/DarwinSDKInfoTest.cpp
===================================================================
--- clang/unittests/Basic/DarwinSDKInfoTest.cpp
+++ clang/unittests/Basic/DarwinSDKInfoTest.cpp
@@ -13,6 +13,67 @@
 using namespace llvm;
 using namespace clang;
 
+// 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, ParseAndTestMapping) {
   llvm::json::Object Obj;
   Obj["Version"] = "11.0";
Index: clang/lib/Basic/DarwinSDKInfo.cpp
===================================================================
--- clang/lib/Basic/DarwinSDKInfo.cpp
+++ clang/lib/Basic/DarwinSDKInfo.cpp
@@ -84,6 +84,25 @@
   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);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to