From 07e3ca238e681272475dc1007c31852647144330 Mon Sep 17 00:00:00 2001 From: Cyndy Ishida Date: Fri, 17 Feb 2023 16:25:33 -0800 Subject: [PATCH] Revert "[TextAPI] Implement TBDv5 Reader" This reverts commit b861b1225380175a5a724e2a677754f5f74e5b0d. This reverts commit 4be17641b05df1e63fa8e069af92676f1246eb83. This patch wont build on some compilers on buildbot. --- lld/test/MachO/Inputs/libStubLink.tbd | 1 - lld/test/MachO/invalid/invalid-stub.s | 5 +- lld/test/MachO/tapi-link.s | 5 +- llvm/include/llvm/TextAPI/InterfaceFile.h | 3 - llvm/lib/TextAPI/CMakeLists.txt | 1 - llvm/lib/TextAPI/TextStub.cpp | 49 +- llvm/lib/TextAPI/TextStubCommon.cpp | 2 +- llvm/lib/TextAPI/TextStubCommon.h | 20 +- llvm/lib/TextAPI/TextStubV5.cpp | 700 -------------------------- llvm/test/Object/Inputs/tapi-v4-watchos.tbd | 1 - llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd | 1 - llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd | 1 - llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd | 1 - llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd | 1 - llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd | 1 - llvm/unittests/TextAPI/CMakeLists.txt | 1 - llvm/unittests/TextAPI/TextStubHelpers.h | 13 +- llvm/unittests/TextAPI/TextStubV4Tests.cpp | 3 +- llvm/unittests/TextAPI/TextStubV5Tests.cpp | 488 ------------------ 19 files changed, 27 insertions(+), 1270 deletions(-) delete mode 100644 llvm/lib/TextAPI/TextStubV5.cpp delete mode 100644 llvm/unittests/TextAPI/TextStubV5Tests.cpp diff --git a/lld/test/MachO/Inputs/libStubLink.tbd b/lld/test/MachO/Inputs/libStubLink.tbd index eaf216d..6e6237ed 100644 --- a/lld/test/MachO/Inputs/libStubLink.tbd +++ b/lld/test/MachO/Inputs/libStubLink.tbd @@ -22,4 +22,3 @@ current-version: 1.0.0 exports: - targets: [ arm64-ios-simulator ] symbols: [ _arm64_sim_only ] -... diff --git a/lld/test/MachO/invalid/invalid-stub.s b/lld/test/MachO/invalid/invalid-stub.s index a80dfa6..9975949 100644 --- a/lld/test/MachO/invalid/invalid-stub.s +++ b/lld/test/MachO/invalid/invalid-stub.s @@ -7,8 +7,9 @@ # RUN: not %lld -L%t -linvalidYAML %t/test.o -o %t/test 2>&1 | FileCheck %s -DDIR=%t # RUN: not %lld -F%t -framework invalidYAML %t/test.o -o %t/test 2>&1 | FileCheck %s -DDIR=%t --check-prefix=CHECK-FRAMEWORK -# CHECK: could not load TAPI file at [[DIR]]{{[\\/]}}libinvalidYAML.tbd: unsupported file type -# CHECK-FRAMEWORK: could not load TAPI file at [[DIR]]{{[\\/]}}invalidYAML.framework{{[\\/]}}invalidYAML.tbd: unsupported file type +# CHECK: could not load TAPI file at [[DIR]]{{[\\/]}}libinvalidYAML.tbd: malformed file +# CHECK-FRAMEWORK: could not load TAPI file at [[DIR]]{{[\\/]}}invalidYAML.framework{{[\\/]}}invalidYAML.tbd: malformed file + .globl _main _main: ret diff --git a/lld/test/MachO/tapi-link.s b/lld/test/MachO/tapi-link.s index af205b6c..b2aa2f2 100644 --- a/lld/test/MachO/tapi-link.s +++ b/lld/test/MachO/tapi-link.s @@ -121,6 +121,7 @@ exports: re-exports: [ 'libNested.dylib' ] ... +## This tests that weak and thread-local symbols are imported as such. #--- libTlvWeak.tbd --- !tapi-tbd tbd-version: 4 @@ -130,8 +131,8 @@ uuids: value: 00000000-0000-0000-0000-000000000000 install-name: '/usr/lib/libTlvWeak.dylib' current-version: 0001.001.1 -exports: # Validate weak & thread-local symbols +exports: - targets: [ x86_64-macos ] weak-symbols: [ _weak ] thread-local-symbols: [ _tlv ] -... +--- diff --git a/llvm/include/llvm/TextAPI/InterfaceFile.h b/llvm/include/llvm/TextAPI/InterfaceFile.h index cb8ec4b..5f07397 100644 --- a/llvm/include/llvm/TextAPI/InterfaceFile.h +++ b/llvm/include/llvm/TextAPI/InterfaceFile.h @@ -66,9 +66,6 @@ enum FileType : unsigned { /// Text-based stub file (.tbd) version 4.0 TBD_V4 = 1U << 3, - /// Text-based stub file (.tbd) version 5.0 - TBD_V5 = 1U << 4, - All = ~0U, LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/All), diff --git a/llvm/lib/TextAPI/CMakeLists.txt b/llvm/lib/TextAPI/CMakeLists.txt index 1714ce3..c7e9e10 100644 --- a/llvm/lib/TextAPI/CMakeLists.txt +++ b/llvm/lib/TextAPI/CMakeLists.txt @@ -2,7 +2,6 @@ add_llvm_component_library(LLVMTextAPI Architecture.cpp ArchitectureSet.cpp InterfaceFile.cpp - TextStubV5.cpp PackedVersion.cpp Platform.cpp Symbol.cpp diff --git a/llvm/lib/TextAPI/TextStub.cpp b/llvm/lib/TextAPI/TextStub.cpp index 73cb614..ff93e43 100644 --- a/llvm/lib/TextAPI/TextStub.cpp +++ b/llvm/lib/TextAPI/TextStub.cpp @@ -258,6 +258,16 @@ struct UUIDv4 { UUIDv4(const Target &TargetID, const std::string &Value) : TargetID(TargetID), Value(Value) {} }; + +// clang-format off +enum TBDFlags : unsigned { + None = 0U, + FlatNamespace = 1U << 0, + NotApplicationExtensionSafe = 1U << 1, + InstallAPI = 1U << 2, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI), +}; +// clang-format on } // end anonymous namespace. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(Architecture) @@ -1095,49 +1105,10 @@ static void DiagHandler(const SMDiagnostic &Diag, void *Context) { File->ErrorMessage = ("malformed file\n" + Message).str(); } -namespace { - -Expected canReadFileType(MemoryBufferRef InputBuffer) { - auto TAPIFile = InputBuffer.getBuffer().trim(); - if (TAPIFile.startswith("{") && TAPIFile.endswith("}")) - return FileType::TBD_V5; - - if (!TAPIFile.endswith("...")) - return createStringError(std::errc::not_supported, "unsupported file type"); - - if (TAPIFile.startswith("--- !tapi-tbd\n")) - return FileType::TBD_V4; - - if (TAPIFile.startswith("--- !tapi-tbd-v3\n")) - return FileType::TBD_V3; - - if (TAPIFile.startswith("--- !tapi-tbd-v2\n")) - return FileType::TBD_V2; - - if (TAPIFile.startswith("--- !tapi-tbd-v1\n") || - TAPIFile.startswith("---\narchs:")) - return FileType::TBD_V1; - - return createStringError(std::errc::not_supported, "unsupported file type"); -} -} // namespace - Expected> TextAPIReader::get(MemoryBufferRef InputBuffer) { TextAPIContext Ctx; Ctx.Path = std::string(InputBuffer.getBufferIdentifier()); - if (auto FTOrErr = canReadFileType(InputBuffer)) - Ctx.FileKind = *FTOrErr; - else - return FTOrErr.takeError(); - - // Handle JSON Format. - if (Ctx.FileKind >= FileType::TBD_V5) { - auto FileOrErr = getInterfaceFileFromJSON(InputBuffer.getBuffer()); - if (!FileOrErr) - return FileOrErr.takeError(); - return std::move(*FileOrErr); - } yaml::Input YAMLIn(InputBuffer.getBuffer(), &Ctx, DiagHandler, &Ctx); // Fill vector with interface file objects created by parsing the YAML file. diff --git a/llvm/lib/TextAPI/TextStubCommon.cpp b/llvm/lib/TextAPI/TextStubCommon.cpp index 8959af4..01a9007 100644 --- a/llvm/lib/TextAPI/TextStubCommon.cpp +++ b/llvm/lib/TextAPI/TextStubCommon.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// Implements common Text Stub YAML mappings. +// Implememts common Text Stub YAML mappings. // //===----------------------------------------------------------------------===// diff --git a/llvm/lib/TextAPI/TextStubCommon.h b/llvm/lib/TextAPI/TextStubCommon.h index 51b4231..aac2722 100644 --- a/llvm/lib/TextAPI/TextStubCommon.h +++ b/llvm/lib/TextAPI/TextStubCommon.h @@ -22,16 +22,6 @@ using UUID = std::pair; -// clang-format off -enum TBDFlags : unsigned { - None = 0U, - FlatNamespace = 1U << 0, - NotApplicationExtensionSafe = 1U << 1, - InstallAPI = 1U << 2, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI), -}; -// clang-format on - LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, FlowStringRef) LLVM_YAML_STRONG_TYPEDEF(uint8_t, SwiftVersion) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(UUID) @@ -40,13 +30,9 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FlowStringRef) namespace llvm { namespace MachO { -class ArchitectureSet; -class PackedVersion; - -Expected> -getInterfaceFileFromJSON(StringRef JSON); -} // namespace MachO - + class ArchitectureSet; + class PackedVersion; +} namespace yaml { template <> struct ScalarTraits { diff --git a/llvm/lib/TextAPI/TextStubV5.cpp b/llvm/lib/TextAPI/TextStubV5.cpp deleted file mode 100644 index 30faad5..0000000 --- a/llvm/lib/TextAPI/TextStubV5.cpp +++ /dev/null @@ -1,700 +0,0 @@ -//===- TextStubV5.cpp -----------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Implements Text Stub JSON mappings. -// -//===----------------------------------------------------------------------===// -#include "TextStubCommon.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/JSON.h" - -// clang-format off -/* - -JSON Format specification. - -All library level keys, accept target values and are defaulted if not specified. - -{ -"tapi_tbd_version": 5, # Required: TBD version for all documents in file -"main_library": { # Required: top level library - "target_info": [ # Required: target information - { - "target": "x86_64-macos", - "min_deployment": "10.14" # Required: minimum OS deployment version - }, - { - "target": "arm64-macos", - "min_deployment": "10.14" - }, - { - "target": "arm64-maccatalyst", - "min_deployment": "12.1" - }], - "flags":[{"attributes": ["flat_namespace"]}], # Optional: - "install_names":[{"name":"/S/L/F/Foo.fwk/Foo"}], # Required: library install name - "current_versions":[{"version": "1.2"}], # Optional: defaults to 1 - "compatibility_versions":[{ "version": "1.1"}], # Optional: defaults to 1 - "rpaths": [ # Optional: - { - "targets": ["x86_64-macos"], # Optional: defaults to targets in `target-info` - "paths": ["@executable_path/.../Frameworks"] - }], - "parent_umbrellas": [{"umbrella": "System"}], - "allowable_clients": [{"clients": ["ClientA"]}], - "reexported_libraries": [{"names": ["/u/l/l/foo.dylib"]}], - "exported_symbols": [{ # List of export symbols section - "targets": ["x86_64-macos", "arm64-macos"], # Optional: defaults to targets in `target-info` - "text": { # List of Text segment symbols - "global": [ "_func" ], - "weak": [], - "thread_local": [] - }, - "data": { ... }, # List of Data segment symbols - }], - "reexported_symbols": [{ ... }], # List of reexported symbols section - "undefined_symbols": [{ ... }] # List of undefined symbols section -}, -"libraries": [ # Optional: Array of inlined libraries - {...}, {...}, {...} -] -} -*/ -// clang-format on - -using namespace llvm; -using namespace llvm::json; -using namespace llvm::MachO; - -struct JSONSymbol { - SymbolKind Kind; - std::string Name; - SymbolFlags Flags; -}; - -using AttrToTargets = std::map; -using TargetsToSymbols = - SmallVector>>; - -enum TBDKey : size_t { - TBDVersion = 0U, - MainLibrary, - Documents, - TargetInfo, - Targets, - Target, - Deployment, - Flags, - Attributes, - InstallName, - CurrentVersion, - CompatibilityVersion, - Version, - SwiftABI, - ABI, - ParentUmbrella, - Umbrella, - AllowableClients, - Clients, - ReexportLibs, - Names, - Name, - Exports, - Reexports, - Undefineds, - Data, - Text, - Weak, - ThreadLocal, - Globals, - ObjCClass, - ObjCEHType, - ObjCIvar, -}; - -std::array Keys = { - "tapi_tbd_version", - "main_library", - "libraries", - "target_info", - "targets", - "target", - "min_deployment", - "flags", - "attributes", - "install_names", - "current_versions", - "compatibility_versions", - "version", - "swift_abi", - "abi", - "parent_umbrellas", - "umbrella", - "allowable_clients", - "clients", - "reexported_libraries", - "names", - "name", - "exported_symbols", - "reexported_symbols", - "undefined_symbols", - "data", - "text", - "weak", - "thread_local", - "global", - "objc_class", - "objc_eh_type", - "objc_ivar", -}; - -static llvm::SmallString<128> getParseErrorMsg(TBDKey Key) { - return {"invalid ", Keys[Key], " section"}; -} - -class JSONStubError : public llvm::ErrorInfo { -public: - JSONStubError(Twine ErrMsg) : Message(ErrMsg.str()) {} - - void log(llvm::raw_ostream &OS) const override { OS << Message << "\n"; } - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } - -private: - std::string Message; -}; - -template -Expected getRequiredValue( - TBDKey Key, const Object *Obj, - std::function(const Object *, StringRef)> GetValue, - std::function(JsonT)> Validate = nullptr) { - std::optional Val = GetValue(Obj, Keys[Key]); - if (!Val) - return make_error(getParseErrorMsg(Key)); - - if (Validate == nullptr) - return static_cast(*Val); - - std::optional Result = Validate(*Val); - if (!Result.has_value()) - return make_error(getParseErrorMsg(Key)); - return Result.value(); -} - -template -Expected getRequiredValue( - TBDKey Key, const Object *Obj, - std::function(const Object *, StringRef)> GetValue, - StubT DefaultValue, std::function(JsonT)> Validate) { - std::optional Val = GetValue(Obj, Keys[Key]); - if (!Val) - return DefaultValue; - - std::optional Result; - Result = Validate(*Val); - if (!Result.has_value()) - return make_error(getParseErrorMsg(Key)); - return Result.value(); -} - -Error collectFromArray(TBDKey Key, const Object *Obj, - std::function Append, - bool IsRequired = false) { - const auto *Values = Obj->getArray(Keys[Key]); - if (!Values) { - if (IsRequired) - return make_error(getParseErrorMsg(Key)); - return Error::success(); - } - - for (Value Val : *Values) { - auto ValStr = Val.getAsString(); - if (!ValStr.has_value()) - return make_error(getParseErrorMsg(Key)); - Append(ValStr.value()); - } - - return Error::success(); -} - -namespace StubParser { - -Expected getVersion(const Object *File) { - auto VersionOrErr = getRequiredValue( - TBDKey::TBDVersion, File, &Object::getInteger, - [](int64_t Val) -> std::optional { - unsigned Result = Val; - if (Result != 5) - return std::nullopt; - return FileType::TBD_V5; - }); - - if (!VersionOrErr) - return VersionOrErr.takeError(); - return *VersionOrErr; -} - -Expected getTargets(const Object *Section) { - const auto *Targets = Section->getArray(Keys[TBDKey::Targets]); - if (!Targets) - return make_error(getParseErrorMsg(TBDKey::Targets)); - - TargetList IFTargets; - for (Value JSONTarget : *Targets) { - auto TargetStr = JSONTarget.getAsString(); - if (!TargetStr.has_value()) - return make_error(getParseErrorMsg(TBDKey::Target)); - auto TargetOrErr = Target::create(TargetStr.value()); - if (!TargetOrErr) - return make_error(getParseErrorMsg(TBDKey::Target)); - IFTargets.push_back(*TargetOrErr); - } - return IFTargets; -} - -Expected getTargetsSection(const Object *Section) { - const Array *Targets = Section->getArray(Keys[TBDKey::TargetInfo]); - if (!Targets) - return make_error(getParseErrorMsg(TBDKey::Targets)); - - TargetList IFTargets; - for (const Value &JSONTarget : *Targets) { - const auto *Obj = JSONTarget.getAsObject(); - if (!Obj) - return make_error(getParseErrorMsg(TBDKey::Target)); - auto TargetStr = - getRequiredValue(TBDKey::Target, Obj, &Object::getString); - if (!TargetStr) - return make_error(getParseErrorMsg(TBDKey::Target)); - auto TargetOrErr = Target::create(*TargetStr); - if (!TargetOrErr) - return make_error(getParseErrorMsg(TBDKey::Target)); - IFTargets.push_back(*TargetOrErr); - // TODO: Implement Deployment Version. - } - return IFTargets; -} - -Error collectSymbolsFromSegment(const Object *Segment, TargetsToSymbols &Result, - SymbolFlags SectionFlag) { - auto Err = collectFromArray( - TBDKey::Globals, Segment, [&Result, &SectionFlag](StringRef Name) { - JSONSymbol Sym = {SymbolKind::GlobalSymbol, Name.str(), SectionFlag}; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - Err = collectFromArray( - TBDKey::ObjCClass, Segment, [&Result, &SectionFlag](StringRef Name) { - JSONSymbol Sym = {SymbolKind::ObjectiveCClass, Name.str(), SectionFlag}; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - Err = collectFromArray(TBDKey::ObjCEHType, Segment, - [&Result, &SectionFlag](StringRef Name) { - JSONSymbol Sym = {SymbolKind::ObjectiveCClassEHType, - Name.str(), SectionFlag}; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - Err = collectFromArray( - TBDKey::ObjCIvar, Segment, [&Result, &SectionFlag](StringRef Name) { - JSONSymbol Sym = {SymbolKind::ObjectiveCInstanceVariable, Name.str(), - SectionFlag}; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - SymbolFlags WeakFlag = SectionFlag | (SectionFlag == SymbolFlags::Undefined - ? SymbolFlags::WeakReferenced - : SymbolFlags::WeakDefined); - Err = collectFromArray(TBDKey::Weak, Segment, - [&Result, WeakFlag](StringRef Name) { - JSONSymbol Sym = { - SymbolKind::GlobalSymbol, - Name.str(), - WeakFlag, - }; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - Err = collectFromArray( - TBDKey::ThreadLocal, Segment, [&Result, SectionFlag](StringRef Name) { - JSONSymbol Sym = {SymbolKind::GlobalSymbol, Name.str(), - SymbolFlags::ThreadLocalValue | SectionFlag}; - Result.back().second.emplace_back(Sym); - }); - if (Err) - return Err; - - return Error::success(); -} - -Expected getNameSection(const Object *File) { - const Array *Section = File->getArray(Keys[TBDKey::InstallName]); - if (!Section) - return make_error(getParseErrorMsg(TBDKey::InstallName)); - - assert(!Section->empty() && "unexpected missing install name"); - // TODO: Just take first for now. - const auto *Obj = Section->front().getAsObject(); - if (!Obj) - return make_error(getParseErrorMsg(TBDKey::InstallName)); - - return getRequiredValue(TBDKey::Name, Obj, &Object::getString); -} - -Expected getSymbolSection(const Object *File, TBDKey Key, - TargetList &Targets) { - - const Array *Section = File->getArray(Keys[Key]); - if (!Section) - return TargetsToSymbols(); - - SymbolFlags SectionFlag; - switch (Key) { - case TBDKey::Reexports: - SectionFlag = SymbolFlags::Rexported; - break; - case TBDKey::Undefineds: - SectionFlag = SymbolFlags::Undefined; - break; - default: - SectionFlag = SymbolFlags::None; - break; - }; - - TargetsToSymbols Result; - TargetList MappedTargets; - for (auto Val : *Section) { - auto *Obj = Val.getAsObject(); - if (!Obj) - continue; - - auto TargetsOrErr = getTargets(Obj); - if (!TargetsOrErr) { - MappedTargets = Targets; - consumeError(TargetsOrErr.takeError()); - } else { - MappedTargets = *TargetsOrErr; - } - Result.emplace_back(std::make_pair(Targets, std::vector())); - - auto *DataSection = Obj->getObject(Keys[TBDKey::Data]); - auto *TextSection = Obj->getObject(Keys[TBDKey::Text]); - // There should be at least one valid section. - if (!DataSection && !TextSection) - return make_error(getParseErrorMsg(Key)); - - if (DataSection) { - auto Err = collectSymbolsFromSegment(DataSection, Result, SectionFlag); - if (Err) - return std::move(Err); - } - if (TextSection) { - auto Err = collectSymbolsFromSegment(TextSection, Result, SectionFlag); - if (Err) - return std::move(Err); - } - } - - return Result; -} - -Expected getLibSection(const Object *File, TBDKey Key, - TBDKey SubKey, - const TargetList &Targets) { - auto *Section = File->getArray(Keys[Key]); - if (!Section) - return AttrToTargets(); - - AttrToTargets Result; - TargetList MappedTargets; - for (auto Val : *Section) { - auto *Obj = Val.getAsObject(); - if (!Obj) - continue; - - auto TargetsOrErr = getTargets(Obj); - if (!TargetsOrErr) { - MappedTargets = Targets; - consumeError(TargetsOrErr.takeError()); - } else { - MappedTargets = *TargetsOrErr; - } - auto Err = - collectFromArray(SubKey, Obj, [&Result, &MappedTargets](StringRef Key) { - Result[Key.str()] = MappedTargets; - }); - if (Err) - return std::move(Err); - } - - return Result; -} - -Expected getUmbrellaSection(const Object *File, - const TargetList &Targets) { - const auto *Umbrella = File->getArray(Keys[TBDKey::ParentUmbrella]); - if (!Umbrella) - return AttrToTargets(); - - AttrToTargets Result; - TargetList MappedTargets; - for (auto Val : *Umbrella) { - auto *Obj = Val.getAsObject(); - if (!Obj) - return make_error( - getParseErrorMsg(TBDKey::ParentUmbrella)); - - // Get Targets section. - auto TargetsOrErr = getTargets(Obj); - if (!TargetsOrErr) { - MappedTargets = Targets; - consumeError(TargetsOrErr.takeError()); - } else { - MappedTargets = *TargetsOrErr; - } - - auto UmbrellaOrErr = - getRequiredValue(TBDKey::Umbrella, Obj, &Object::getString); - if (!UmbrellaOrErr) - return UmbrellaOrErr.takeError(); - Result[UmbrellaOrErr->str()] = Targets; - } - return Result; -} - -Expected getSwiftVersion(const Object *File) { - const Array *Versions = File->getArray(Keys[TBDKey::SwiftABI]); - if (!Versions) - return 0; - - for (const auto &Val : *Versions) { - const auto *Obj = Val.getAsObject(); - if (!Obj) - return make_error(getParseErrorMsg(TBDKey::SwiftABI)); - - // TODO: Take first for now. - return getRequiredValue(TBDKey::ABI, Obj, - &Object::getInteger); - } - - return 0; -} - -Expected getPackedVersion(const Object *File, TBDKey Key) { - const Array *Versions = File->getArray(Keys[Key]); - if (!Versions) - return PackedVersion(1, 0, 0); - - for (const auto &Val : *Versions) { - const auto *Obj = Val.getAsObject(); - if (!Obj) - return make_error(getParseErrorMsg(Key)); - - auto ValidatePV = [](StringRef Version) -> std::optional { - PackedVersion PV; - auto [success, truncated] = PV.parse64(Version); - if (!success || truncated) - return std::nullopt; - return PV; - }; - // TODO: Take first for now. - return getRequiredValue( - TBDKey::Version, Obj, &Object::getString, PackedVersion(1, 0, 0), - ValidatePV); - } - - return PackedVersion(1, 0, 0); -} - -Expected getFlags(const Object *File) { - TBDFlags Flags = TBDFlags::None; - const Array *Section = File->getArray(Keys[TBDKey::Flags]); - if (!Section) - return Flags; - - for (auto &Val : *Section) { - // TODO: Just take first for now. - const auto *Obj = Val.getAsObject(); - if (!Obj) - return make_error(getParseErrorMsg(TBDKey::Flags)); - - auto FlagsOrErr = - collectFromArray(TBDKey::Attributes, Obj, [&Flags](StringRef Flag) { - TBDFlags TBDFlag = - StringSwitch(Flag) - .Case("flat_namespace", TBDFlags::FlatNamespace) - .Case("not_app_extension_safe", - TBDFlags::NotApplicationExtensionSafe) - .Default(TBDFlags::None); - Flags |= TBDFlag; - }); - - if (FlagsOrErr) - return std::move(FlagsOrErr); - - return Flags; - } - - return Flags; -} - -using IFPtr = std::unique_ptr; -Expected parseToInterfaceFile(const Object *File) { - auto TargetsOrErr = getTargetsSection(File); - if (!TargetsOrErr) - return TargetsOrErr.takeError(); - TargetList Targets = *TargetsOrErr; - - auto NameOrErr = getNameSection(File); - if (!NameOrErr) - return NameOrErr.takeError(); - StringRef Name = *NameOrErr; - - auto CurrVersionOrErr = getPackedVersion(File, TBDKey::CurrentVersion); - if (!CurrVersionOrErr) - return CurrVersionOrErr.takeError(); - PackedVersion CurrVersion = *CurrVersionOrErr; - - auto CompVersionOrErr = getPackedVersion(File, TBDKey::CompatibilityVersion); - if (!CompVersionOrErr) - return CompVersionOrErr.takeError(); - PackedVersion CompVersion = *CompVersionOrErr; - - auto SwiftABIOrErr = getSwiftVersion(File); - if (!SwiftABIOrErr) - return SwiftABIOrErr.takeError(); - uint8_t SwiftABI = *SwiftABIOrErr; - - auto FlagsOrErr = getFlags(File); - if (!FlagsOrErr) - return FlagsOrErr.takeError(); - TBDFlags Flags = *FlagsOrErr; - - auto UmbrellasOrErr = getUmbrellaSection(File, Targets); - if (!UmbrellasOrErr) - return UmbrellasOrErr.takeError(); - AttrToTargets Umbrellas = *UmbrellasOrErr; - - auto ClientsOrErr = - getLibSection(File, TBDKey::AllowableClients, TBDKey::Clients, Targets); - if (!ClientsOrErr) - return ClientsOrErr.takeError(); - AttrToTargets Clients = *ClientsOrErr; - - auto RLOrErr = - getLibSection(File, TBDKey::ReexportLibs, TBDKey::Names, Targets); - if (!RLOrErr) - return RLOrErr.takeError(); - AttrToTargets ReexportLibs = std::move(*RLOrErr); - - auto ExportsOrErr = getSymbolSection(File, TBDKey::Exports, Targets); - if (!ExportsOrErr) - return ExportsOrErr.takeError(); - TargetsToSymbols Exports = std::move(*ExportsOrErr); - - auto ReexportsOrErr = getSymbolSection(File, TBDKey::Reexports, Targets); - if (!ReexportsOrErr) - return ReexportsOrErr.takeError(); - TargetsToSymbols Reexports = std::move(*ReexportsOrErr); - - auto UndefinedsOrErr = getSymbolSection(File, TBDKey::Undefineds, Targets); - if (!UndefinedsOrErr) - return UndefinedsOrErr.takeError(); - TargetsToSymbols Undefineds = std::move(*UndefinedsOrErr); - - IFPtr F(new InterfaceFile); - F->setInstallName(Name); - F->setCurrentVersion(CurrVersion); - F->setCompatibilityVersion(CompVersion); - F->setSwiftABIVersion(SwiftABI); - F->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace)); - F->setApplicationExtensionSafe( - !(Flags & TBDFlags::NotApplicationExtensionSafe)); - for (auto &T : Targets) - F->addTarget(T); - for (auto &[Lib, Targets] : Clients) - for (auto Target : Targets) - F->addAllowableClient(Lib, Target); - for (auto &[Lib, Targets] : ReexportLibs) - for (auto Target : Targets) - F->addReexportedLibrary(Lib, Target); - for (auto &[Lib, Targets] : Umbrellas) - for (auto Target : Targets) - F->addParentUmbrella(Target, Lib); - for (auto &[Targets, Symbols] : Exports) - for (auto &Sym : Symbols) - F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags); - for (auto &[Targets, Symbols] : Reexports) - for (auto &Sym : Symbols) - F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags); - for (auto &[Targets, Symbols] : Undefineds) - for (auto &Sym : Symbols) - F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags); - - return F; -} - -Expected> getInlinedLibs(const Object *File) { - std::vector IFs; - const Array *Files = File->getArray(Keys[TBDKey::Documents]); - if (!Files) - return IFs; - - for (auto Lib : *Files) { - auto IFOrErr = parseToInterfaceFile(Lib.getAsObject()); - if (!IFOrErr) - return IFOrErr.takeError(); - auto IF = std::move(*IFOrErr); - IFs.emplace_back(std::move(IF)); - } - return IFs; -} - -} // namespace StubParser - -Expected> -MachO::getInterfaceFileFromJSON(StringRef JSON) { - auto ValOrErr = parse(JSON); - if (!ValOrErr) - return ValOrErr.takeError(); - - auto *Root = ValOrErr->getAsObject(); - auto VersionOrErr = StubParser::getVersion(Root); - if (!VersionOrErr) - return VersionOrErr.takeError(); - FileType Version = *VersionOrErr; - - Object *MainLib = Root->getObject(Keys[TBDKey::MainLibrary]); - auto IFOrErr = StubParser::parseToInterfaceFile(MainLib); - if (!IFOrErr) - return IFOrErr.takeError(); - (*IFOrErr)->setFileType(Version); - std::unique_ptr IF(std::move(*IFOrErr)); - - auto IFsOrErr = StubParser::getInlinedLibs(Root); - if (!IFsOrErr) - return IFsOrErr.takeError(); - for (auto &File : *IFsOrErr) { - File->setFileType(Version); - IF->addDocument(std::shared_ptr(std::move(File))); - } - return std::move(IF); -} diff --git a/llvm/test/Object/Inputs/tapi-v4-watchos.tbd b/llvm/test/Object/Inputs/tapi-v4-watchos.tbd index 1a22de4..df06922 100644 --- a/llvm/test/Object/Inputs/tapi-v4-watchos.tbd +++ b/llvm/test/Object/Inputs/tapi-v4-watchos.tbd @@ -11,4 +11,3 @@ current-version: 1 exports: - targets: [ armv7k-watchos-simulator, arm64_32-watchos-simulator ] symbols: [ '_sym1' ] -... diff --git a/llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd b/llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd index e4e6dcc..7dba4d8 100644 --- a/llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd +++ b/llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd @@ -47,4 +47,3 @@ undefineds: objc-ivars: [] weak-symbols: [] thread-local-symbols: [] -... diff --git a/llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd b/llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd index 9ad435c..6a83184 100644 --- a/llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd +++ b/llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd @@ -53,4 +53,3 @@ exports: weak-symbols: [ _symC ] - targets: [ x86_64-ios-simulator ] symbols: [ _symB ] -... diff --git a/llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd b/llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd index 0ce4fb3..b2641e2 100644 --- a/llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd +++ b/llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd @@ -47,4 +47,3 @@ undefineds: objc-ivars: [] weak-symbols: [] thread-local-symbols: [] -... diff --git a/llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd b/llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd index 13b1416..1338f62 100644 --- a/llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd +++ b/llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd @@ -102,4 +102,3 @@ undefineds: objc-ivars: [] weak-symbols: [] thread-local-symbols: [] -... diff --git a/llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd b/llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd index b1b2d16..1d34b2d 100644 --- a/llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd +++ b/llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd @@ -53,4 +53,3 @@ exports: weak-symbols: [ _symC ] - targets: [ x86_64-ios-simulator ] symbols: [ _symB ] -... diff --git a/llvm/unittests/TextAPI/CMakeLists.txt b/llvm/unittests/TextAPI/CMakeLists.txt index 2cb5be6..d575d57 100644 --- a/llvm/unittests/TextAPI/CMakeLists.txt +++ b/llvm/unittests/TextAPI/CMakeLists.txt @@ -7,7 +7,6 @@ add_llvm_unittest(TextAPITests TextStubV2Tests.cpp TextStubV3Tests.cpp TextStubV4Tests.cpp - TextStubV5Tests.cpp ) target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/TextAPI/TextStubHelpers.h b/llvm/unittests/TextAPI/TextStubHelpers.h index c59252c..67bfa1a 100644 --- a/llvm/unittests/TextAPI/TextStubHelpers.h +++ b/llvm/unittests/TextAPI/TextStubHelpers.h @@ -16,11 +16,10 @@ namespace llvm { struct ExportedSymbol { - MachO::SymbolKind Kind = MachO::SymbolKind::GlobalSymbol; - std::string Name = {}; - bool Weak = false; - bool ThreadLocalValue = false; - MachO::TargetList Targets = {}; + llvm::MachO::SymbolKind Kind; + std::string Name; + bool WeakDefined; + bool ThreadLocalValue; }; using ExportedSymbolSeq = std::vector; @@ -33,8 +32,8 @@ inline bool operator<(const ExportedSymbol &LHS, const ExportedSymbol &RHS) { } inline bool operator==(const ExportedSymbol &LHS, const ExportedSymbol &RHS) { - return std::tie(LHS.Kind, LHS.Name, LHS.Weak, LHS.ThreadLocalValue) == - std::tie(RHS.Kind, RHS.Name, RHS.Weak, RHS.ThreadLocalValue); + return std::tie(LHS.Kind, LHS.Name, LHS.WeakDefined, LHS.ThreadLocalValue) == + std::tie(RHS.Kind, RHS.Name, RHS.WeakDefined, RHS.ThreadLocalValue); } inline std::string stripWhitespace(std::string S) { diff --git a/llvm/unittests/TextAPI/TextStubV4Tests.cpp b/llvm/unittests/TextAPI/TextStubV4Tests.cpp index ac51950..570e853 100644 --- a/llvm/unittests/TextAPI/TextStubV4Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV4Tests.cpp @@ -903,8 +903,7 @@ TEST(TBDv4, MalformedFile2) { "tbd-version: 4\n" "targets: [ x86_64-macos ]\n" "install-name: Test.dylib\n" - "foobar: \"unsupported key\"\n" - "...\n"; + "foobar: \"unsupported key\"\n"; Expected Result = TextAPIReader::get(MemoryBufferRef(TBDv4MalformedFile2, "Test.tbd")); diff --git a/llvm/unittests/TextAPI/TextStubV5Tests.cpp b/llvm/unittests/TextAPI/TextStubV5Tests.cpp deleted file mode 100644 index 26f477a..0000000 --- a/llvm/unittests/TextAPI/TextStubV5Tests.cpp +++ /dev/null @@ -1,488 +0,0 @@ -//===-- TextStubV5Tests.cpp - TBD V5 File Test ----------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===-----------------------------------------------------------------------===/ - -#include "TextStubHelpers.h" -#include "llvm/TextAPI/InterfaceFile.h" -#include "llvm/TextAPI/TextAPIReader.h" -#include "llvm/TextAPI/TextAPIWriter.h" -#include "gtest/gtest.h" -#include -#include - -using namespace llvm; -using namespace llvm::MachO; - -namespace TBDv5 { - -TEST(TBDv5, ReadFile) { - static const char TBDv5File[] = R"({ -"tapi_tbd_version": 5, -"main_library": { - "target_info": [ - { - "target": "x86_64-macos", - "min_deployment": "10.14" - }, - { - "target": "arm64-macos", - "min_deployment": "10.14" - }, - { - "target": "arm64-maccatalyst", - "min_deployment": "12.1" - } - ], - "flags": [ - { - "targets": [ - "x86_64-macos" - ], - "attributes": [ - "flat_namespace" - ] - } - ], - "install_names": [ - { - "name": "/S/L/F/Foo.framework/Foo" - } - ], - "current_versions": [ - { - "version": "1.2" - } - ], - "compatibility_versions": [ - { "version": "1.1" } - ], - "rpaths": [ - { - "targets": [ - "x86_64-macos" - ], - "paths": [ - "@executable_path/.../Frameworks" - ] - } - ], - "parent_umbrellas": [ - { - "umbrella": "System" - } - ], - "allowable_clients": [ - { - "clients": [ - "ClientA", - "ClientB" - ] - } - ], - "reexported_libraries": [ - { - "names": [ - "/u/l/l/libfoo.dylib", - "/u/l/l/libbar.dylib" - ] - } - ], - "exported_symbols": [ - { - "targets": [ - "x86_64-macos", - "arm64-macos" - ], - "data": { - "global": [ - "_global" - ], - "objc_class": [ - "ClassA" - ], - "weak": [], - "thread_local": [] - }, - "text": { - "global": [ - "_func" - ], - "weak": [], - "thread_local": [] - } - }, - { - "targets": [ - "x86_64-macos" - ], - "data": { - "global": [ - "_globalVar" - ], - "objc_class": [ - "ClassData" - ], - "objc_eh_type": [ - "ClassA", - "ClassB" - ], - "objc_ivar": [ - "ClassA.ivar1", - "ClassA.ivar2", - "ClassC.ivar1" - ] - }, - "text": { - "global": [ - "_funcFoo" - ] - } - } - ], - "reexported_symbols": [ - { - "targets": [ - "x86_64-macos", - "arm64-macos" - ], - "data": { - "global": [ - "_globalRe" - ], - "objc_class": [ - "ClassRexport" - ] - }, - "text": { - "global": [ - "_funcA" - ] - } - } - ], - "undefined_symbols": [ - { - "targets": [ - "x86_64-macos" - ], - "data": { - "global": [ - "_globalBind" - ], - "weak": [ - "referenced_sym" - ] - } - } - ] -}, -"libraries": [] -})"; - - Expected Result = - TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd")); - EXPECT_TRUE(!!Result); - TBDFile File = std::move(Result.get()); - EXPECT_EQ(FileType::TBD_V5, File->getFileType()); - EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName()); - - TargetList AllTargets = { - Target(AK_x86_64, PLATFORM_MACOS), - Target(AK_arm64, PLATFORM_MACOS), - Target(AK_arm64, PLATFORM_MACCATALYST), - }; - EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms()); - EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures()); - - EXPECT_EQ(PackedVersion(1, 2, 0), File->getCurrentVersion()); - EXPECT_EQ(PackedVersion(1, 1, 0), File->getCompatibilityVersion()); - EXPECT_TRUE(File->isApplicationExtensionSafe()); - EXPECT_FALSE(File->isTwoLevelNamespace()); - EXPECT_EQ(0U, File->documents().size()); - - InterfaceFileRef ClientA("ClientA", AllTargets); - InterfaceFileRef ClientB("ClientB", AllTargets); - EXPECT_EQ(2U, File->allowableClients().size()); - EXPECT_EQ(ClientA, File->allowableClients().at(0)); - EXPECT_EQ(ClientB, File->allowableClients().at(1)); - - InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets); - InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets); - EXPECT_EQ(2U, File->reexportedLibraries().size()); - EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0)); - EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1)); - - std::vector> Umbrellas = { - {Target(AK_x86_64, PLATFORM_MACOS), "System"}, - {Target(AK_arm64, PLATFORM_MACOS), "System"}, - {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}}; - EXPECT_EQ(Umbrellas, File->umbrellas()); - - ExportedSymbolSeq Exports, Reexports, Undefineds; - for (const auto *Sym : File->symbols()) { - TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()}; - ExportedSymbol Temp = - ExportedSymbol{Sym->getKind(), std::string(Sym->getName()), - Sym->isWeakDefined() || Sym->isWeakReferenced(), - Sym->isThreadLocalValue(), SymTargets}; - if (Sym->isUndefined()) - Undefineds.emplace_back(std::move(Temp)); - else - Sym->isReexported() ? Reexports.emplace_back(std::move(Temp)) - : Exports.emplace_back(std::move(Temp)); - } - llvm::sort(Exports); - llvm::sort(Reexports); - llvm::sort(Undefineds); - - TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS), - Target(AK_arm64, PLATFORM_MACOS)}; - - std::vector ExpectedExportedSymbols = { - {SymbolKind::GlobalSymbol, "_func", false, false, MacOSTargets}, - {SymbolKind::GlobalSymbol, - "_funcFoo", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::GlobalSymbol, "_global", false, false, MacOSTargets}, - {SymbolKind::GlobalSymbol, - "_globalVar", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCClass, "ClassA", false, false, MacOSTargets}, - {SymbolKind::ObjectiveCClass, - "ClassData", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCClassEHType, - "ClassA", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCClassEHType, - "ClassB", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCInstanceVariable, - "ClassA.ivar1", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCInstanceVariable, - "ClassA.ivar2", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::ObjectiveCInstanceVariable, - "ClassC.ivar1", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - }; - std::vector ExpectedReexportedSymbols = { - {SymbolKind::GlobalSymbol, "_funcA", false, false, MacOSTargets}, - {SymbolKind::GlobalSymbol, "_globalRe", false, false, MacOSTargets}, - {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, MacOSTargets}, - }; - - std::vector ExpectedUndefinedSymbols = { - {SymbolKind::GlobalSymbol, - "_globalBind", - false, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - {SymbolKind::GlobalSymbol, - "referenced_sym", - true, - false, - {Target(AK_x86_64, PLATFORM_MACOS)}}, - }; - - EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size()); - EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size()); - EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size()); - EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(), - std::begin(ExpectedExportedSymbols))); - EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(), - std::begin(ExpectedReexportedSymbols))); - EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(), - std::begin(ExpectedUndefinedSymbols))); -} - -TEST(TBDv5, ReadMultipleTargets) { - static const char TBDv5File[] = R"({ -"tapi_tbd_version": 5, -"main_library": { - "target_info": [ - { - "target": "x86_64-macos", - "min_deployment": "10.14" - }, - { - "target": "arm64-macos", - "min_deployment": "10.14" - }, - { - "target": "arm64-maccatalyst", - "min_deployment": "12.1" - } - ], - "install_names":[ - { "name":"/usr/lib/libFoo.dylib" } - ], - "swift_abi":[ { "abi":8 } ], - "reexported_libraries": [ - { - "targets": [ "x86_64-maccatalyst" ], - "names": [ - "/u/l/l/libfoo.dylib", - "/u/l/l/libbar.dylib" - ] - }, - { - "targets": [ "arm64-maccatalyst" ], - "names": [ "/u/l/l/libArmOnly.dylib" ] - } - ] -} -})"; - - Expected Result = - TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd")); - EXPECT_TRUE(!!Result); - TBDFile File = std::move(Result.get()); - EXPECT_EQ(FileType::TBD_V5, File->getFileType()); - EXPECT_EQ(std::string("/usr/lib/libFoo.dylib"), File->getInstallName()); - EXPECT_TRUE(File->isApplicationExtensionSafe()); - EXPECT_TRUE(File->isTwoLevelNamespace()); - EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion()); - EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion()); - EXPECT_EQ(8U, File->getSwiftABIVersion()); - - TargetList AllTargets = { - Target(AK_x86_64, PLATFORM_MACOS), - Target(AK_arm64, PLATFORM_MACOS), - Target(AK_arm64, PLATFORM_MACCATALYST), - }; - EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms()); - EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures()); - - InterfaceFileRef ReexportA("/u/l/l/libArmOnly.dylib", - {Target(AK_arm64, PLATFORM_MACCATALYST)}); - InterfaceFileRef ReexportB("/u/l/l/libbar.dylib", - {Target(AK_x86_64, PLATFORM_MACCATALYST)}); - InterfaceFileRef ReexportC("/u/l/l/libfoo.dylib", - {Target(AK_x86_64, PLATFORM_MACCATALYST)}); - EXPECT_EQ(3U, File->reexportedLibraries().size()); - EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0)); - EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1)); - EXPECT_EQ(ReexportC, File->reexportedLibraries().at(2)); -} - -TEST(TBDv5, ReadMultipleDocuments) { - static const char TBDv5File[] = R"({ -"tapi_tbd_version": 5, -"main_library": { - "target_info": [ - { - "target": "armv7-ios", - "min_deployment": "11.0" - } - ], - "install_names":[ - { "name":"/S/L/F/Foo.framework/Foo" } - ], - "reexported_libraries": [ - { "names": ["/u/l/l/libfoo.dylib"] } - ] -}, -"libraries": [ - { - "target_info": [ - { - "target": "armv7-ios", - "min_deployment": "11.0" - } - ], - "install_names":[ - { "name":"/u/l/l/libfoo.dylib" } - ], - "flags":[ - { "attributes": ["not_app_extension_safe"] } - ], - "exported_symbols": [ - { - "data": { - "thread_local": [ "_globalVar" ], - "objc_class": [ "ClassData" ], - "objc_eh_type": [ "ClassA", "ClassB" ] - }, - "text": { - "global": [ "_funcFoo" ] - } - } - ] - } -]})"; - - Expected Result = - TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd")); - EXPECT_TRUE(!!Result); - TBDFile File = std::move(Result.get()); - EXPECT_EQ(FileType::TBD_V5, File->getFileType()); - EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName()); - EXPECT_TRUE(File->isTwoLevelNamespace()); - EXPECT_TRUE(File->isApplicationExtensionSafe()); - - TargetList Targets(File->targets().begin(), File->targets().end()); - Target iOSTarget(AK_armv7, PLATFORM_IOS); - EXPECT_EQ(TargetList{iOSTarget}, Targets); - std::vector Symbols(File->symbols().begin(), - File->symbols().end()); - EXPECT_EQ(0U, Symbols.size()); - - InterfaceFileRef Reexport("/u/l/l/libfoo.dylib", {iOSTarget}); - EXPECT_EQ(1U, File->reexportedLibraries().size()); - EXPECT_EQ(Reexport, File->reexportedLibraries().at(0)); - - // Check inlined library. - EXPECT_EQ(1U, File->documents().size()); - TBDReexportFile Document = File->documents().front(); - Targets = {Document->targets().begin(), Document->targets().end()}; - EXPECT_EQ(TargetList{iOSTarget}, Targets); - EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName()); - EXPECT_EQ(0U, Document->getSwiftABIVersion()); - EXPECT_TRUE(Document->isTwoLevelNamespace()); - EXPECT_FALSE(Document->isApplicationExtensionSafe()); - - ExportedSymbolSeq Exports; - for (const auto *Sym : Document->symbols()) - Exports.emplace_back( - ExportedSymbol{Sym->getKind(), - std::string(Sym->getName()), - Sym->isWeakDefined() || Sym->isWeakReferenced(), - Sym->isThreadLocalValue(), - {iOSTarget}}); - - ExportedSymbolSeq ExpectedExports = { - {SymbolKind::GlobalSymbol, "_globalVar", false, true, {iOSTarget}}, - {SymbolKind::ObjectiveCClass, "ClassData", false, false, {iOSTarget}}, - {SymbolKind::ObjectiveCClassEHType, "ClassB", false, false, {iOSTarget}}, - {SymbolKind::ObjectiveCClassEHType, "ClassA", false, false, {iOSTarget}}, - {SymbolKind::GlobalSymbol, "_funcFoo", false, false, {iOSTarget}}, - }; - - EXPECT_EQ(ExpectedExports.size(), Exports.size()); - EXPECT_TRUE( - std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports))); -} - -} // end namespace TBDv5 -- 2.7.4