diff --git a/llvm/include/llvm/TextAPI/Platform.h b/llvm/include/llvm/TextAPI/Platform.h --- a/llvm/include/llvm/TextAPI/Platform.h +++ b/llvm/include/llvm/TextAPI/Platform.h @@ -14,6 +14,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/Support/VersionTuple.h" namespace llvm { namespace MachO { @@ -27,6 +28,7 @@ PlatformType getPlatformFromName(StringRef Name); std::string getOSAndEnvironmentName(PlatformType Platform, std::string Version = ""); +VersionTuple mapToSupportedOSVersion(const Triple &Triple); } // end namespace MachO. } // end namespace llvm. diff --git a/llvm/include/llvm/TextAPI/Target.h b/llvm/include/llvm/TextAPI/Target.h --- a/llvm/include/llvm/TextAPI/Target.h +++ b/llvm/include/llvm/TextAPI/Target.h @@ -33,7 +33,7 @@ : Arch(Arch), Platform(Platform), MinDeployment(MinDeployment) {} explicit Target(const llvm::Triple &Triple) : Arch(mapToArchitecture(Triple)), Platform(mapToPlatformType(Triple)), - MinDeployment(Triple.getOSVersion()) {} + MinDeployment(mapToSupportedOSVersion(Triple)) {} static llvm::Expected create(StringRef Target); diff --git a/llvm/lib/TextAPI/Platform.cpp b/llvm/lib/TextAPI/Platform.cpp --- a/llvm/lib/TextAPI/Platform.cpp +++ b/llvm/lib/TextAPI/Platform.cpp @@ -132,5 +132,12 @@ llvm_unreachable("Unknown llvm::MachO::PlatformType enum"); } +VersionTuple mapToSupportedOSVersion(const Triple &Triple) { + const VersionTuple MinSupportedOS = Triple.getMinimumSupportedOSVersion(); + if (MinSupportedOS > Triple.getOSVersion()) + return MinSupportedOS; + return Triple.getOSVersion(); +} + } // end namespace MachO. } // end namespace llvm. diff --git a/llvm/lib/TextAPI/TextStubV5.cpp b/llvm/lib/TextAPI/TextStubV5.cpp --- a/llvm/lib/TextAPI/TextStubV5.cpp +++ b/llvm/lib/TextAPI/TextStubV5.cpp @@ -293,8 +293,10 @@ if (!TargetOrErr) return make_error(getParseErrorMsg(TBDKey::Target)); TargetOrErr->MinDeployment = Version; - - IFTargets.push_back(*TargetOrErr); + // Convert to LLVM::Triple to accurately compute minOS + platform + arch + // pairing. + IFTargets.push_back( + MachO::Target(Triple(getTargetTripleName(*TargetOrErr)))); } return std::move(IFTargets); } diff --git a/llvm/unittests/TextAPI/TextStubV5Tests.cpp b/llvm/unittests/TextAPI/TextStubV5Tests.cpp --- a/llvm/unittests/TextAPI/TextStubV5Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV5Tests.cpp @@ -944,6 +944,50 @@ EXPECT_EQ(*File, *WriteResultFile); } +TEST(TBDv5, Target_UnsupportedMinOS) { + static const char TBDv5File[] = R"({ +"tapi_tbd_version": 5, +"main_library": { + "target_info": [ + { + "target": "arm64-macos", + "min_deployment": "10.14" + }, + { + "target": "x86_64-macos", + "min_deployment": "10.14" + } + ], + "install_names":[ + { "name":"/S/L/F/Foo.framework/Foo" } + ] +}})"; + + Expected Result = + TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd")); + EXPECT_TRUE(!!Result); + TBDFile File = std::move(Result.get()); + EXPECT_EQ(FileType::TBD_V5, File->getFileType()); + TargetList ExpectedTargets = { + Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)), + Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0)), + }; + TargetList Targets{File->targets().begin(), File->targets().end()}; + llvm::sort(Targets); + EXPECT_EQ(Targets, ExpectedTargets); + + SmallString<4096> Buffer; + raw_svector_ostream OS(Buffer); + Error WriteResult = TextAPIWriter::writeToStream(OS, *File); + EXPECT_TRUE(!WriteResult); + + Expected Output = + TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd")); + EXPECT_TRUE(!!Output); + TBDFile WriteResultFile = std::move(Output.get()); + EXPECT_EQ(*File, *WriteResultFile); +} + TEST(TBDv5, MisspelledKey) { static const char TBDv5File[] = R"({ "tapi_tbd_version": 5,