Revert "[TextAPI] Implement TBDv5 Reader"
authorCyndy Ishida <cyndy_ishida@apple.com>
Sat, 18 Feb 2023 00:25:33 +0000 (16:25 -0800)
committerCyndy Ishida <cyndy_ishida@apple.com>
Sat, 18 Feb 2023 00:26:23 +0000 (16:26 -0800)
This reverts commit b861b1225380175a5a724e2a677754f5f74e5b0d.
This reverts commit 4be17641b05df1e63fa8e069af92676f1246eb83.

This patch wont build on some compilers on buildbot.

19 files changed:
lld/test/MachO/Inputs/libStubLink.tbd
lld/test/MachO/invalid/invalid-stub.s
lld/test/MachO/tapi-link.s
llvm/include/llvm/TextAPI/InterfaceFile.h
llvm/lib/TextAPI/CMakeLists.txt
llvm/lib/TextAPI/TextStub.cpp
llvm/lib/TextAPI/TextStubCommon.cpp
llvm/lib/TextAPI/TextStubCommon.h
llvm/lib/TextAPI/TextStubV5.cpp [deleted file]
llvm/test/Object/Inputs/tapi-v4-watchos.tbd
llvm/test/tools/llvm-tapi-diff/Inputs/v4A.tbd
llvm/test/tools/llvm-tapi-diff/Inputs/v4B.tbd
llvm/test/tools/llvm-tapi-diff/Inputs/v4C.tbd
llvm/test/tools/llvm-tapi-diff/Inputs/v4D.tbd
llvm/test/tools/llvm-tapi-diff/Inputs/v4E.tbd
llvm/unittests/TextAPI/CMakeLists.txt
llvm/unittests/TextAPI/TextStubHelpers.h
llvm/unittests/TextAPI/TextStubV4Tests.cpp
llvm/unittests/TextAPI/TextStubV5Tests.cpp [deleted file]

index eaf216d..6e6237e 100644 (file)
@@ -22,4 +22,3 @@ current-version: 1.0.0
 exports:
   - targets:         [ arm64-ios-simulator ]
     symbols:         [ _arm64_sim_only ]
-...
index a80dfa6..9975949 100644 (file)
@@ -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
index af205b6..b2aa2f2 100644 (file)
@@ -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 ]
-...
+---
index cb8ec4b..5f07397 100644 (file)
@@ -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),
index 1714ce3..c7e9e10 100644 (file)
@@ -2,7 +2,6 @@ add_llvm_component_library(LLVMTextAPI
   Architecture.cpp
   ArchitectureSet.cpp
   InterfaceFile.cpp
-  TextStubV5.cpp
   PackedVersion.cpp
   Platform.cpp
   Symbol.cpp
index 73cb614..ff93e43 100644 (file)
@@ -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<FileType> 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<std::unique_ptr<InterfaceFile>>
 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.
index 8959af4..01a9007 100644 (file)
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Implements common Text Stub YAML mappings.
+// Implememts common Text Stub YAML mappings.
 //
 //===----------------------------------------------------------------------===//
 
index 51b4231..aac2722 100644 (file)
 
 using UUID = std::pair<llvm::MachO::Target, std::string>;
 
-// 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<std::unique_ptr<InterfaceFile>>
-getInterfaceFileFromJSON(StringRef JSON);
-} // namespace MachO
-
+    class ArchitectureSet;
+    class PackedVersion;
+}
 namespace yaml {
 
 template <> struct ScalarTraits<FlowStringRef> {
diff --git a/llvm/lib/TextAPI/TextStubV5.cpp b/llvm/lib/TextAPI/TextStubV5.cpp
deleted file mode 100644 (file)
index 30faad5..0000000
+++ /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<std::string, TargetList>;
-using TargetsToSymbols =
-    SmallVector<std::pair<TargetList, std::vector<JSONSymbol>>>;
-
-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<StringRef, 64> 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<llvm::json::ParseError> {
-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 <typename JsonT, typename StubT = JsonT>
-Expected<StubT> getRequiredValue(
-    TBDKey Key, const Object *Obj,
-    std::function<std::optional<JsonT>(const Object *, StringRef)> GetValue,
-    std::function<std::optional<StubT>(JsonT)> Validate = nullptr) {
-  std::optional<JsonT> Val = GetValue(Obj, Keys[Key]);
-  if (!Val)
-    return make_error<JSONStubError>(getParseErrorMsg(Key));
-
-  if (Validate == nullptr)
-    return static_cast<StubT>(*Val);
-
-  std::optional<StubT> Result = Validate(*Val);
-  if (!Result.has_value())
-    return make_error<JSONStubError>(getParseErrorMsg(Key));
-  return Result.value();
-}
-
-template <typename JsonT, typename StubT = JsonT>
-Expected<StubT> getRequiredValue(
-    TBDKey Key, const Object *Obj,
-    std::function<std::optional<JsonT>(const Object *, StringRef)> GetValue,
-    StubT DefaultValue, std::function<std::optional<StubT>(JsonT)> Validate) {
-  std::optional<JsonT> Val = GetValue(Obj, Keys[Key]);
-  if (!Val)
-    return DefaultValue;
-
-  std::optional<StubT> Result;
-  Result = Validate(*Val);
-  if (!Result.has_value())
-    return make_error<JSONStubError>(getParseErrorMsg(Key));
-  return Result.value();
-}
-
-Error collectFromArray(TBDKey Key, const Object *Obj,
-                       std::function<void(StringRef)> Append,
-                       bool IsRequired = false) {
-  const auto *Values = Obj->getArray(Keys[Key]);
-  if (!Values) {
-    if (IsRequired)
-      return make_error<JSONStubError>(getParseErrorMsg(Key));
-    return Error::success();
-  }
-
-  for (Value Val : *Values) {
-    auto ValStr = Val.getAsString();
-    if (!ValStr.has_value())
-      return make_error<JSONStubError>(getParseErrorMsg(Key));
-    Append(ValStr.value());
-  }
-
-  return Error::success();
-}
-
-namespace StubParser {
-
-Expected<FileType> getVersion(const Object *File) {
-  auto VersionOrErr = getRequiredValue<int64_t, FileType>(
-      TBDKey::TBDVersion, File, &Object::getInteger,
-      [](int64_t Val) -> std::optional<FileType> {
-        unsigned Result = Val;
-        if (Result != 5)
-          return std::nullopt;
-        return FileType::TBD_V5;
-      });
-
-  if (!VersionOrErr)
-    return VersionOrErr.takeError();
-  return *VersionOrErr;
-}
-
-Expected<TargetList> getTargets(const Object *Section) {
-  const auto *Targets = Section->getArray(Keys[TBDKey::Targets]);
-  if (!Targets)
-    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Targets));
-
-  TargetList IFTargets;
-  for (Value JSONTarget : *Targets) {
-    auto TargetStr = JSONTarget.getAsString();
-    if (!TargetStr.has_value())
-      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
-    auto TargetOrErr = Target::create(TargetStr.value());
-    if (!TargetOrErr)
-      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
-    IFTargets.push_back(*TargetOrErr);
-  }
-  return IFTargets;
-}
-
-Expected<TargetList> getTargetsSection(const Object *Section) {
-  const Array *Targets = Section->getArray(Keys[TBDKey::TargetInfo]);
-  if (!Targets)
-    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Targets));
-
-  TargetList IFTargets;
-  for (const Value &JSONTarget : *Targets) {
-    const auto *Obj = JSONTarget.getAsObject();
-    if (!Obj)
-      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
-    auto TargetStr =
-        getRequiredValue<StringRef>(TBDKey::Target, Obj, &Object::getString);
-    if (!TargetStr)
-      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
-    auto TargetOrErr = Target::create(*TargetStr);
-    if (!TargetOrErr)
-      return make_error<JSONStubError>(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<StringRef> getNameSection(const Object *File) {
-  const Array *Section = File->getArray(Keys[TBDKey::InstallName]);
-  if (!Section)
-    return make_error<JSONStubError>(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<JSONStubError>(getParseErrorMsg(TBDKey::InstallName));
-
-  return getRequiredValue<StringRef>(TBDKey::Name, Obj, &Object::getString);
-}
-
-Expected<TargetsToSymbols> 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<JSONSymbol>()));
-
-    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<JSONStubError>(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<AttrToTargets> 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<AttrToTargets> 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<JSONStubError>(
-          getParseErrorMsg(TBDKey::ParentUmbrella));
-
-    // Get Targets section.
-    auto TargetsOrErr = getTargets(Obj);
-    if (!TargetsOrErr) {
-      MappedTargets = Targets;
-      consumeError(TargetsOrErr.takeError());
-    } else {
-      MappedTargets = *TargetsOrErr;
-    }
-
-    auto UmbrellaOrErr =
-        getRequiredValue<StringRef>(TBDKey::Umbrella, Obj, &Object::getString);
-    if (!UmbrellaOrErr)
-      return UmbrellaOrErr.takeError();
-    Result[UmbrellaOrErr->str()] = Targets;
-  }
-  return Result;
-}
-
-Expected<uint8_t> 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<JSONStubError>(getParseErrorMsg(TBDKey::SwiftABI));
-
-    // TODO: Take first for now.
-    return getRequiredValue<int64_t, uint8_t>(TBDKey::ABI, Obj,
-                                              &Object::getInteger);
-  }
-
-  return 0;
-}
-
-Expected<PackedVersion> 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<JSONStubError>(getParseErrorMsg(Key));
-
-    auto ValidatePV = [](StringRef Version) -> std::optional<PackedVersion> {
-      PackedVersion PV;
-      auto [success, truncated] = PV.parse64(Version);
-      if (!success || truncated)
-        return std::nullopt;
-      return PV;
-    };
-    // TODO: Take first for now.
-    return getRequiredValue<StringRef, PackedVersion>(
-        TBDKey::Version, Obj, &Object::getString, PackedVersion(1, 0, 0),
-        ValidatePV);
-  }
-
-  return PackedVersion(1, 0, 0);
-}
-
-Expected<TBDFlags> 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<JSONStubError>(getParseErrorMsg(TBDKey::Flags));
-
-    auto FlagsOrErr =
-        collectFromArray(TBDKey::Attributes, Obj, [&Flags](StringRef Flag) {
-          TBDFlags TBDFlag =
-              StringSwitch<TBDFlags>(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<InterfaceFile>;
-Expected<IFPtr> 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<std::vector<IFPtr>> getInlinedLibs(const Object *File) {
-  std::vector<IFPtr> 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<std::unique_ptr<InterfaceFile>>
-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<InterfaceFile> 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<InterfaceFile>(std::move(File)));
-  }
-  return std::move(IF);
-}
index 1a22de4..df06922 100644 (file)
@@ -11,4 +11,3 @@ current-version: 1
 exports:
   - targets:              [ armv7k-watchos-simulator, arm64_32-watchos-simulator ]
     symbols:              [ '_sym1' ]
-...
index e4e6dcc..7dba4d8 100644 (file)
@@ -47,4 +47,3 @@ undefineds:
     objc-ivars: []
     weak-symbols: []
     thread-local-symbols: []
-...
index 9ad435c..6a83184 100644 (file)
@@ -53,4 +53,3 @@ exports:
     weak-symbols:    [ _symC ]
   - targets:         [ x86_64-ios-simulator ]
     symbols:         [ _symB ]
-...
index 0ce4fb3..b2641e2 100644 (file)
@@ -47,4 +47,3 @@ undefineds:
     objc-ivars: []
     weak-symbols: []
     thread-local-symbols: []
-...
index 13b1416..1338f62 100644 (file)
@@ -102,4 +102,3 @@ undefineds:
     objc-ivars: []
     weak-symbols: []
     thread-local-symbols: []
-...
index b1b2d16..1d34b2d 100644 (file)
@@ -53,4 +53,3 @@ exports:
     weak-symbols:    [ _symC ]
   - targets:         [ x86_64-ios-simulator ]
     symbols:         [ _symB ]
-...
index 2cb5be6..d575d57 100644 (file)
@@ -7,7 +7,6 @@ add_llvm_unittest(TextAPITests
   TextStubV2Tests.cpp
   TextStubV3Tests.cpp
   TextStubV4Tests.cpp
-  TextStubV5Tests.cpp
 )
 
 target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport)
index c59252c..67bfa1a 100644 (file)
 
 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<ExportedSymbol>;
@@ -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) {
index ac51950..570e853 100644 (file)
@@ -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<TBDFile> 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 (file)
index 26f477a..0000000
+++ /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 <string>
-#include <vector>
-
-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<TBDFile> 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<std::pair<Target, std::string>> 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<ExportedSymbol> 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<ExportedSymbol> ExpectedReexportedSymbols = {
-      {SymbolKind::GlobalSymbol, "_funcA", false, false, MacOSTargets},
-      {SymbolKind::GlobalSymbol, "_globalRe", false, false, MacOSTargets},
-      {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, MacOSTargets},
-  };
-
-  std::vector<ExportedSymbol> 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<TBDFile> 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<TBDFile> 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<const Symbol *> 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