diff --git a/llvm/include/llvm/TextAPI/InterfaceFile.h b/llvm/include/llvm/TextAPI/InterfaceFile.h --- a/llvm/include/llvm/TextAPI/InterfaceFile.h +++ b/llvm/include/llvm/TextAPI/InterfaceFile.h @@ -254,6 +254,12 @@ /// Check if the library is application extension safe. bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; } + /// Check if the library has simulator support. + bool hasSimulatorSupport() const { return HasSimSupport; } + + /// Specify if the library has simulator support. + void setSimulatorSupport(bool V = true) { HasSimSupport = V; } + /// Set the Objective-C constraint. void setObjCConstraint(ObjCConstraintType Constraint) { ObjcConstraint = Constraint; @@ -451,6 +457,7 @@ uint8_t SwiftABIVersion{0}; bool IsTwoLevelNamespace{false}; bool IsAppExtensionSafe{false}; + bool HasSimSupport{false}; ObjCConstraintType ObjcConstraint = ObjCConstraintType::None; std::vector> ParentUmbrellas; std::vector AllowableClients; diff --git a/llvm/lib/TextAPI/InterfaceFile.cpp b/llvm/lib/TextAPI/InterfaceFile.cpp --- a/llvm/lib/TextAPI/InterfaceFile.cpp +++ b/llvm/lib/TextAPI/InterfaceFile.cpp @@ -361,6 +361,8 @@ return false; if (IsAppExtensionSafe != O.IsAppExtensionSafe) return false; + if (HasSimSupport != O.HasSimSupport) + return false; if (ParentUmbrellas != O.ParentUmbrellas) return false; if (AllowableClients != O.AllowableClients) diff --git a/llvm/lib/TextAPI/TextStubCommon.h b/llvm/lib/TextAPI/TextStubCommon.h --- a/llvm/lib/TextAPI/TextStubCommon.h +++ b/llvm/lib/TextAPI/TextStubCommon.h @@ -28,7 +28,8 @@ FlatNamespace = 1U << 0, NotApplicationExtensionSafe = 1U << 1, InstallAPI = 1U << 2, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI), + SimulatorSupport = 1U << 3, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SimulatorSupport), }; // clang-format on 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 @@ -547,11 +547,11 @@ Expected getFlags(const Object *File) { TBDFlags Flags = TBDFlags::None; const Array *Section = File->getArray(Keys[TBDKey::Flags]); - if (!Section) + if (!Section || Section->empty()) return Flags; for (auto &Val : *Section) { - // TODO: Just take first for now. + // FIXME: Flags currently apply to all target triples. const auto *Obj = Val.getAsObject(); if (!Obj) return make_error(getParseErrorMsg(TBDKey::Flags)); @@ -563,6 +563,7 @@ .Case("flat_namespace", TBDFlags::FlatNamespace) .Case("not_app_extension_safe", TBDFlags::NotApplicationExtensionSafe) + .Case("sim_support", TBDFlags::SimulatorSupport) .Default(TBDFlags::None); Flags |= TBDFlag; }); @@ -653,6 +654,7 @@ F->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace)); F->setApplicationExtensionSafe( !(Flags & TBDFlags::NotApplicationExtensionSafe)); + F->setSimulatorSupport((Flags & TBDFlags::SimulatorSupport)); for (auto &T : Targets) F->addTarget(T); for (auto &[Lib, Targets] : Clients) @@ -919,6 +921,8 @@ Flags.emplace_back("flat_namespace"); if (!File->isApplicationExtensionSafe()) Flags.emplace_back("not_app_extension_safe"); + if (File->hasSimulatorSupport()) + Flags.emplace_back("sim_support"); return serializeScalar(TBDKey::Attributes, std::move(Flags)); } diff --git a/llvm/tools/llvm-readtapi/DiffEngine.cpp b/llvm/tools/llvm-readtapi/DiffEngine.cpp --- a/llvm/tools/llvm-readtapi/DiffEngine.cpp +++ b/llvm/tools/llvm-readtapi/DiffEngine.cpp @@ -363,6 +363,13 @@ rhs, IFRHS->isApplicationExtensionSafe()), "Application Extension Safe")); + if (IFLHS->hasSimulatorSupport() != IFRHS->hasSimulatorSupport()) + Output.push_back(recordDifferences(DiffScalarVal( + lhs, IFLHS->hasSimulatorSupport()), + DiffScalarVal( + rhs, IFRHS->hasSimulatorSupport()), + "Simulator Support")); + if (IFLHS->reexportedLibraries() != IFRHS->reexportedLibraries()) Output.push_back(recordDifferences(IFLHS->reexportedLibraries(), IFRHS->reexportedLibraries(), 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 @@ -1151,6 +1151,37 @@ EXPECT_EQ("invalid min_deployment section\n", ErrorMessage); } +TEST(TBDv5, SimSupport) { + static const char TBDv5File[] = R"({ +"tapi_tbd_version": 5, +"main_library": { + "target_info": [ + { + "target": "arm64-macos", + "min_deployment": "11.1" + } + ], + "install_names":[ + { "name":"/S/L/F/Foo.framework/Foo" } + ], + "flags":[ + { "attributes": ["sim_support"] } + ] +}})"; + + Expected Result = + TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd")); + EXPECT_TRUE(!!Result); + Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1)); + TBDFile ReadFile = std::move(Result.get()); + EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType()); + EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), + ReadFile->getInstallName()); + EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end()); + EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget); + EXPECT_TRUE(ReadFile->hasSimulatorSupport()); +} + TEST(TBDv5, MergeIF) { static const char TBDv5FileA[] = R"({ "tapi_tbd_version": 5,