diff --git a/clang/lib/Basic/DarwinSDKInfo.cpp b/clang/lib/Basic/DarwinSDKInfo.cpp --- a/clang/lib/Basic/DarwinSDKInfo.cpp +++ b/clang/lib/Basic/DarwinSDKInfo.cpp @@ -84,6 +84,25 @@ llvm::DenseMap> VersionMappings; if (const auto *VM = Obj->getObject("VersionMap")) { + // FIXME: Generalize this out beyond iOS-deriving targets. + // Look for ios_ 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 --- a/clang/unittests/Basic/DarwinSDKInfoTest.cpp +++ b/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 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 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";