mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[llvm][TextAPI] adding inlining reexported libraries support
Summary: [llvm][TextAPI] adding inlining reexported libraries support * this patch adds reader/writer support for MachO tbd files. The usecase is to represent reexported libraries in top level library that won't need to exist for linker indirection because all of the needed content will be inlined in the same document. Reviewers: ributzka, steven_wu, jhenderson Reviewed By: ributzka Subscribers: JDevlieghere, hiraditya, mgrang, dexonsmith, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67646
This commit is contained in:
parent
a316b89267
commit
619546feb9
@ -274,6 +274,11 @@ public:
|
||||
/// \param Target_ The target applicable to Parent
|
||||
/// \param Parent The name of Parent
|
||||
void addParentUmbrella(const Target &Target_, StringRef Parent);
|
||||
|
||||
/// Get the list of Parent Umbrella frameworks.
|
||||
///
|
||||
/// \return Returns a list of target information and install name of parent
|
||||
/// umbrellas.
|
||||
const std::vector<std::pair<Target, std::string>> &umbrellas() const {
|
||||
return ParentUmbrellas;
|
||||
}
|
||||
@ -328,6 +333,20 @@ public:
|
||||
return UUIDs;
|
||||
}
|
||||
|
||||
/// Add a library for inlining to top level library.
|
||||
///
|
||||
///\param Document The library to inline with top level library.
|
||||
void addDocument(std::shared_ptr<InterfaceFile> &&Document) {
|
||||
Documents.emplace_back(std::move(Document));
|
||||
}
|
||||
|
||||
/// Get the list of inlined libraries.
|
||||
///
|
||||
/// \return Returns a list of the inlined frameworks.
|
||||
const std::vector<std::shared_ptr<InterfaceFile>> &documents() const {
|
||||
return Documents;
|
||||
}
|
||||
|
||||
/// Add a symbol to the symbols list or extend an existing one.
|
||||
void addSymbol(SymbolKind Kind, StringRef Name, const TargetList &Targets,
|
||||
SymbolFlags Flags = SymbolFlags::None);
|
||||
@ -403,6 +422,7 @@ private:
|
||||
std::vector<std::pair<Target, std::string>> ParentUmbrellas;
|
||||
std::vector<InterfaceFileRef> AllowableClients;
|
||||
std::vector<InterfaceFileRef> ReexportedLibraries;
|
||||
std::vector<std::shared_ptr<InterfaceFile>> Documents;
|
||||
std::vector<std::pair<Target, std::string>> UUIDs;
|
||||
SymbolMapType Symbols;
|
||||
};
|
||||
|
@ -1118,6 +1118,10 @@ TextAPIReader::get(MemoryBufferRef InputBuffer) {
|
||||
auto File = std::unique_ptr<InterfaceFile>(
|
||||
const_cast<InterfaceFile *>(Files.front()));
|
||||
|
||||
for (auto Iter = std::next(Files.begin()); Iter != Files.end(); ++Iter)
|
||||
File->addDocument(
|
||||
std::shared_ptr<InterfaceFile>(const_cast<InterfaceFile *>(*Iter)));
|
||||
|
||||
if (YAMLIn.error())
|
||||
return make_error<StringError>(Ctx.ErrorMessage, YAMLIn.error());
|
||||
|
||||
@ -1133,6 +1137,9 @@ Error TextAPIWriter::writeToStream(raw_ostream &OS, const InterfaceFile &File) {
|
||||
std::vector<const InterfaceFile *> Files;
|
||||
Files.emplace_back(&File);
|
||||
|
||||
for (auto Document : File.documents())
|
||||
Files.emplace_back(Document.get());
|
||||
|
||||
// Stream out yaml.
|
||||
YAMLOut << Files;
|
||||
|
||||
|
@ -117,6 +117,127 @@ TEST(TBDv3, ReadFile) {
|
||||
std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));
|
||||
}
|
||||
|
||||
TEST(TBDv3, ReadMultipleDocuments) {
|
||||
static const char TBDv3Inlines[] =
|
||||
"--- !tapi-tbd-v3\n"
|
||||
"archs: [ armv7, arm64 ]\n"
|
||||
"uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
|
||||
" 'arm64: 11111111-1111-1111-1111-111111111111']\n"
|
||||
"platform: ios\n"
|
||||
"install-name: Test.dylib\n"
|
||||
"current-version: 2.3.4\n"
|
||||
"compatibility-version: 1.0\n"
|
||||
"swift-abi-version: 1.1\n"
|
||||
"parent-umbrella: Umbrella.dylib\n"
|
||||
"exports:\n"
|
||||
" - archs: [ armv7, arm64 ]\n"
|
||||
" allowable-clients: [ clientA ]\n"
|
||||
" re-exports: [ /usr/lib/libfoo.dylib,\n"
|
||||
" TestInline.dylib ]\n"
|
||||
" symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
|
||||
" objc-classes: [ class1, class2 ]\n"
|
||||
" objc-eh-types: [ class1 ]\n"
|
||||
" objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
|
||||
" weak-def-symbols: [ _weak1, _weak2 ]\n"
|
||||
" thread-local-symbols: [ _tlv1, _tlv3 ]\n"
|
||||
" - archs: [ armv7 ]\n"
|
||||
" symbols: [ _sym5 ]\n"
|
||||
" objc-classes: [ class3 ]\n"
|
||||
" objc-ivars: [ class1._ivar3 ]\n"
|
||||
" weak-def-symbols: [ _weak3 ]\n"
|
||||
" thread-local-symbols: [ _tlv3 ]\n"
|
||||
"--- !tapi-tbd-v3\n"
|
||||
"archs: [ armv7, arm64 ]\n"
|
||||
"uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
|
||||
" 'arm64: 11111111-1111-1111-1111-111111111111']\n"
|
||||
"platform: ios\n"
|
||||
"install-name: TestInline.dylib\n"
|
||||
"swift-abi-version: 1.1\n"
|
||||
"exports:\n"
|
||||
" - archs: [ armv7, arm64 ]\n"
|
||||
" symbols: [ _sym5, _sym6 ]\n"
|
||||
"...\n";
|
||||
|
||||
auto Result = TextAPIReader::get(MemoryBufferRef(TBDv3Inlines, "Test.tbd"));
|
||||
EXPECT_TRUE(!!Result);
|
||||
auto File = std::move(Result.get());
|
||||
EXPECT_EQ(File->documents().size(), 1U);
|
||||
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
|
||||
auto Archs = AK_armv7 | AK_arm64;
|
||||
auto Platform = PlatformKind::iOS;
|
||||
TargetList Targets;
|
||||
for (auto &&arch : Archs)
|
||||
Targets.emplace_back(Target(arch, Platform));
|
||||
EXPECT_EQ(Archs, File->getArchitectures());
|
||||
UUIDs Uuids = {{Target(AK_armv7, PlatformKind::unknown),
|
||||
"00000000-0000-0000-0000-000000000000"},
|
||||
{Target(AK_arm64, PlatformKind::unknown),
|
||||
"11111111-1111-1111-1111-111111111111"}};
|
||||
EXPECT_EQ(Uuids, File->uuids());
|
||||
EXPECT_EQ(File->getPlatforms().size(), 1U);
|
||||
EXPECT_EQ(Platform, *File->getPlatforms().begin());
|
||||
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
|
||||
EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
|
||||
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
|
||||
EXPECT_EQ(2U, File->getSwiftABIVersion());
|
||||
EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
|
||||
EXPECT_TRUE(File->isTwoLevelNamespace());
|
||||
EXPECT_TRUE(File->isApplicationExtensionSafe());
|
||||
EXPECT_FALSE(File->isInstallAPI());
|
||||
InterfaceFileRef Client("clientA", Targets);
|
||||
const std::vector<InterfaceFileRef> Reexports = {
|
||||
InterfaceFileRef("/usr/lib/libfoo.dylib", Targets),
|
||||
InterfaceFileRef("TestInline.dylib", Targets)};
|
||||
EXPECT_EQ(1U, File->allowableClients().size());
|
||||
EXPECT_EQ(Client, File->allowableClients().front());
|
||||
EXPECT_EQ(2U, File->reexportedLibraries().size());
|
||||
EXPECT_EQ(Reexports, File->reexportedLibraries());
|
||||
|
||||
ExportedSymbolSeq Exports;
|
||||
for (const auto *Sym : File->symbols()) {
|
||||
EXPECT_FALSE(Sym->isWeakReferenced());
|
||||
EXPECT_FALSE(Sym->isUndefined());
|
||||
Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),
|
||||
Sym->isWeakDefined(),
|
||||
Sym->isThreadLocalValue()});
|
||||
}
|
||||
llvm::sort(Exports.begin(), Exports.end());
|
||||
|
||||
EXPECT_EQ(sizeof(TBDv3Symbols) / sizeof(ExportedSymbol), Exports.size());
|
||||
EXPECT_TRUE(
|
||||
std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));
|
||||
|
||||
// Check Second Document
|
||||
Exports.clear();
|
||||
auto Document = File->documents().front();
|
||||
EXPECT_EQ(FileType::TBD_V3, Document->getFileType());
|
||||
EXPECT_EQ(Archs, Document->getArchitectures());
|
||||
EXPECT_EQ(Uuids, Document->uuids());
|
||||
EXPECT_EQ(Platform, *Document->getPlatforms().begin());
|
||||
EXPECT_EQ(std::string("TestInline.dylib"), Document->getInstallName());
|
||||
EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());
|
||||
EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());
|
||||
EXPECT_EQ(2U, Document->getSwiftABIVersion());
|
||||
|
||||
for (const auto *Sym : Document->symbols()) {
|
||||
EXPECT_FALSE(Sym->isWeakReferenced());
|
||||
EXPECT_FALSE(Sym->isUndefined());
|
||||
Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),
|
||||
Sym->isWeakDefined(),
|
||||
Sym->isThreadLocalValue()});
|
||||
}
|
||||
llvm::sort(Exports.begin(), Exports.end());
|
||||
|
||||
ExportedSymbolSeq DocumentSymbols{
|
||||
{SymbolKind::GlobalSymbol, "_sym5", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_sym6", false, false},
|
||||
};
|
||||
|
||||
EXPECT_EQ(DocumentSymbols.size(), Exports.size());
|
||||
EXPECT_TRUE(
|
||||
std::equal(Exports.begin(), Exports.end(), DocumentSymbols.begin()));
|
||||
}
|
||||
|
||||
TEST(TBDv3, WriteFile) {
|
||||
static const char TBDv3File3[] =
|
||||
"--- !tapi-tbd-v3\n"
|
||||
@ -171,6 +292,87 @@ TEST(TBDv3, WriteFile) {
|
||||
EXPECT_STREQ(TBDv3File3, Buffer.c_str());
|
||||
}
|
||||
|
||||
TEST(TBDv3, WriteMultipleDocuments) {
|
||||
static const char TBDv3Inlines[] =
|
||||
"--- !tapi-tbd-v3\n"
|
||||
"archs: [ i386, x86_64 ]\n"
|
||||
"platform: zippered\n"
|
||||
"install-name: '/usr/lib/libfoo.dylib'\n"
|
||||
"current-version: 1.2.3\n"
|
||||
"compatibility-version: 0\n"
|
||||
"swift-abi-version: 5\n"
|
||||
"exports:\n"
|
||||
" - archs: [ x86_64 ]\n"
|
||||
" allowable-clients: [ clientA ]\n"
|
||||
" re-exports: [ '/usr/lib/libbar.dylib' ]\n"
|
||||
" - archs: [ i386, x86_64 ]\n"
|
||||
" symbols: [ _sym1 ]\n"
|
||||
" objc-classes: [ Class1 ]\n"
|
||||
" objc-eh-types: [ Class1 ]\n"
|
||||
" objc-ivars: [ Class1._ivar1 ]\n"
|
||||
" weak-def-symbols: [ _sym2 ]\n"
|
||||
" thread-local-symbols: [ _symA ]\n"
|
||||
"--- !tapi-tbd-v3\n"
|
||||
"archs: [ i386 ]\n"
|
||||
"platform: macosx\n"
|
||||
"install-name: '/usr/lib/libbar.dylib'\n"
|
||||
"current-version: 0\n"
|
||||
"compatibility-version: 0\n"
|
||||
"swift-abi-version: 5\n"
|
||||
"objc-constraint: none\n"
|
||||
"exports:\n"
|
||||
" - archs: [ i386 ]\n"
|
||||
" symbols: [ _sym3, _sym4 ]\n"
|
||||
"...\n";
|
||||
|
||||
InterfaceFile File;
|
||||
TargetList Targets;
|
||||
for (auto &&arch : AK_i386 | AK_x86_64) {
|
||||
Targets.emplace_back(Target(arch, PlatformKind::macOS));
|
||||
Targets.emplace_back(Target(arch, PlatformKind::macCatalyst));
|
||||
}
|
||||
File.addTargets(Targets);
|
||||
File.setPath("libfoo.dylib");
|
||||
File.setInstallName("/usr/lib/libfoo.dylib");
|
||||
File.setFileType(FileType::TBD_V3);
|
||||
File.setCurrentVersion(PackedVersion(1, 2, 3));
|
||||
File.setTwoLevelNamespace();
|
||||
File.setApplicationExtensionSafe();
|
||||
File.setSwiftABIVersion(5);
|
||||
File.setObjCConstraint(ObjCConstraintType::Retain_Release);
|
||||
File.addAllowableClient("clientA", Targets[2]);
|
||||
File.addReexportedLibrary("/usr/lib/libbar.dylib", Targets[2]);
|
||||
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", Targets);
|
||||
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", Targets,
|
||||
SymbolFlags::WeakDefined);
|
||||
File.addSymbol(SymbolKind::GlobalSymbol, "_symA", Targets,
|
||||
SymbolFlags::ThreadLocalValue);
|
||||
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", Targets);
|
||||
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", Targets);
|
||||
File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
|
||||
Targets);
|
||||
|
||||
// Inline document
|
||||
InterfaceFile Document;
|
||||
Targets = {Target(AK_i386, PlatformKind::macOS)};
|
||||
Document.addTargets(Targets);
|
||||
Document.setPath("libbar.dylib");
|
||||
Document.setInstallName("/usr/lib/libbar.dylib");
|
||||
Document.setFileType(FileType::TBD_V3);
|
||||
Document.setTwoLevelNamespace();
|
||||
Document.setApplicationExtensionSafe();
|
||||
Document.setSwiftABIVersion(5);
|
||||
Document.addSymbol(SymbolKind::GlobalSymbol, "_sym3", Targets);
|
||||
Document.addSymbol(SymbolKind::GlobalSymbol, "_sym4", Targets);
|
||||
File.addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
|
||||
|
||||
SmallString<4096> Buffer;
|
||||
raw_svector_ostream OS(Buffer);
|
||||
auto Result = TextAPIWriter::writeToStream(OS, File);
|
||||
EXPECT_FALSE(Result);
|
||||
EXPECT_STREQ(TBDv3Inlines, Buffer.c_str());
|
||||
}
|
||||
|
||||
TEST(TBDv3, Platform_macOS) {
|
||||
static const char TBDv3PlatformMacOS[] = "--- !tapi-tbd-v3\n"
|
||||
"archs: [ x86_64 ]\n"
|
||||
|
@ -17,19 +17,6 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::MachO;
|
||||
|
||||
static ExportedSymbol TBDv4ExportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symA", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_symAB", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_symB", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol TBDv4ReexportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symC", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol TBDv4UndefinedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symD", false, false},
|
||||
};
|
||||
|
||||
namespace TBDv4 {
|
||||
|
||||
@ -141,18 +128,209 @@ TEST(TBDv4, ReadFile) {
|
||||
llvm::sort(Reexports.begin(), Reexports.end());
|
||||
llvm::sort(Undefineds.begin(), Undefineds.end());
|
||||
|
||||
EXPECT_EQ(sizeof(TBDv4ExportedSymbols) / sizeof(ExportedSymbol),
|
||||
static ExportedSymbol ExpectedExportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symA", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_symAB", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_symB", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol ExpectedReexportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symC", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol ExpectedUndefinedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symD", false, false},
|
||||
};
|
||||
|
||||
EXPECT_EQ(sizeof(ExpectedExportedSymbols) / sizeof(ExportedSymbol),
|
||||
Exports.size());
|
||||
EXPECT_EQ(sizeof(TBDv4ReexportedSymbols) / sizeof(ExportedSymbol),
|
||||
EXPECT_EQ(sizeof(ExpectedReexportedSymbols) / sizeof(ExportedSymbol),
|
||||
Reexports.size());
|
||||
EXPECT_EQ(sizeof(TBDv4UndefinedSymbols) / sizeof(ExportedSymbol),
|
||||
EXPECT_EQ(sizeof(ExpectedUndefinedSymbols) / sizeof(ExportedSymbol),
|
||||
Undefineds.size());
|
||||
EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
|
||||
std::begin(TBDv4ExportedSymbols)));
|
||||
std::begin(ExpectedExportedSymbols)));
|
||||
EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
|
||||
std::begin(TBDv4ReexportedSymbols)));
|
||||
std::begin(ExpectedReexportedSymbols)));
|
||||
EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
|
||||
std::begin(TBDv4UndefinedSymbols)));
|
||||
std::begin(ExpectedUndefinedSymbols)));
|
||||
}
|
||||
|
||||
TEST(TBDv4, ReadMultipleDocuments) {
|
||||
static const char TBDv4Inlines[] =
|
||||
"--- !tapi-tbd\n"
|
||||
"tbd-version: 4\n"
|
||||
"targets: [ i386-macos, i386-maccatalyst, x86_64-macos, "
|
||||
"x86_64-maccatalyst ]\n"
|
||||
"uuids:\n"
|
||||
" - target: i386-macos\n"
|
||||
" value: 00000000-0000-0000-0000-000000000000\n"
|
||||
" - target: i386-maccatalyst\n"
|
||||
" value: 00000000-0000-0000-0000-000000000002\n"
|
||||
" - target: x86_64-macos\n"
|
||||
" value: 11111111-1111-1111-1111-111111111111\n"
|
||||
" - target: x86_64-maccatalyst\n"
|
||||
" value: 11111111-1111-1111-1111-111111111112\n"
|
||||
"install-name: /System/Library/Frameworks/Umbrella.framework/Umbrella\n"
|
||||
"parent-umbrella:\n"
|
||||
" - targets: [ i386-macos, x86_64-macos ]\n"
|
||||
" umbrella: System\n"
|
||||
"reexported-libraries:\n"
|
||||
" - targets: [ i386-macos, x86_64-macos ]\n"
|
||||
" libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
|
||||
"--- !tapi-tbd\n"
|
||||
"tbd-version: 4\n"
|
||||
"targets: [ i386-macos, x86_64-macos ]\n"
|
||||
"uuids:\n"
|
||||
" - target: i386-macos\n"
|
||||
" value: 20000000-0000-0000-0000-000000000000\n"
|
||||
" - target: x86_64-macos\n"
|
||||
" value: 21111111-1111-1111-1111-111111111111\n"
|
||||
"flags: [ flat_namespace ]\n"
|
||||
"install-name: /System/Library/Frameworks/A.framework/A\n"
|
||||
"current-version: 1.2.3\n"
|
||||
"compatibility-version: 1.2\n"
|
||||
"swift-abi-version: 5\n"
|
||||
"exports:\n"
|
||||
" - targets: [ i386-macos ]\n"
|
||||
" symbols: [ _symA ]\n"
|
||||
" objc-classes: []\n"
|
||||
" objc-eh-types: []\n"
|
||||
" objc-ivars: []\n"
|
||||
" weak-symbols: []\n"
|
||||
" thread-local-symbols: []\n"
|
||||
" - targets: [ x86_64-macos ]\n"
|
||||
" symbols: [_symAB]\n"
|
||||
"reexports:\n"
|
||||
" - targets: [ i386-macos ]\n"
|
||||
" symbols: [_symC]\n"
|
||||
" objc-classes: []\n"
|
||||
" objc-eh-types: []\n"
|
||||
" objc-ivars: []\n"
|
||||
" weak-symbols: []\n"
|
||||
" thread-local-symbols: []\n"
|
||||
"undefineds:\n"
|
||||
" - targets: [ i386-macos ]\n"
|
||||
" symbols: [ _symD ]\n"
|
||||
" objc-classes: []\n"
|
||||
" objc-eh-types: []\n"
|
||||
" objc-ivars: []\n"
|
||||
" weak-symbols: []\n"
|
||||
" thread-local-symbols: []\n"
|
||||
"...\n";
|
||||
|
||||
PlatformSet Platforms;
|
||||
Platforms.insert(PlatformKind::macOS);
|
||||
Platforms.insert(PlatformKind::macCatalyst);
|
||||
ArchitectureSet Archs = AK_i386 | AK_x86_64;
|
||||
TargetList Targets;
|
||||
for (auto &&Arch : Archs)
|
||||
for (auto &&Platform : Platforms)
|
||||
Targets.emplace_back(Target(Arch, Platform));
|
||||
UUIDs Uuids = {
|
||||
{Targets[0], "00000000-0000-0000-0000-000000000000"},
|
||||
{Targets[1], "00000000-0000-0000-0000-000000000002"},
|
||||
{Targets[2], "11111111-1111-1111-1111-111111111111"},
|
||||
{Targets[3], "11111111-1111-1111-1111-111111111112"},
|
||||
};
|
||||
|
||||
auto Result = TextAPIReader::get(MemoryBufferRef(TBDv4Inlines, "Test.tbd"));
|
||||
EXPECT_TRUE(!!Result);
|
||||
auto File = std::move(Result.get());
|
||||
EXPECT_EQ(FileType::TBD_V4, File->getFileType());
|
||||
EXPECT_EQ(Archs, File->getArchitectures());
|
||||
EXPECT_EQ(Uuids, File->uuids());
|
||||
EXPECT_EQ(Platforms, File->getPlatforms());
|
||||
EXPECT_EQ(
|
||||
std::string("/System/Library/Frameworks/Umbrella.framework/Umbrella"),
|
||||
File->getInstallName());
|
||||
EXPECT_TRUE(File->isTwoLevelNamespace());
|
||||
EXPECT_TRUE(File->isApplicationExtensionSafe());
|
||||
EXPECT_FALSE(File->isInstallAPI());
|
||||
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
|
||||
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
|
||||
InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
|
||||
{Targets[0], Targets[2]});
|
||||
EXPECT_EQ(1U, File->reexportedLibraries().size());
|
||||
EXPECT_EQ(reexport, File->reexportedLibraries().front());
|
||||
ExportedSymbolSeq Exports;
|
||||
for (const auto *Sym : File->symbols()) {
|
||||
EXPECT_FALSE(Sym->isWeakReferenced());
|
||||
EXPECT_FALSE(Sym->isUndefined());
|
||||
Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),
|
||||
Sym->isWeakDefined(),
|
||||
Sym->isThreadLocalValue()});
|
||||
}
|
||||
EXPECT_EQ(0U, Exports.size());
|
||||
|
||||
// Check Inlined Document
|
||||
Exports.clear();
|
||||
Targets.clear();
|
||||
Uuids.clear();
|
||||
PlatformKind Platform = PlatformKind::macOS;
|
||||
for (auto &&Arch : Archs)
|
||||
Targets.emplace_back(Target(Arch, Platform));
|
||||
Uuids = {
|
||||
{Targets[0], "20000000-0000-0000-0000-000000000000"},
|
||||
{Targets[1], "21111111-1111-1111-1111-111111111111"},
|
||||
};
|
||||
|
||||
auto Document = File->documents().front();
|
||||
EXPECT_EQ(FileType::TBD_V4, Document->getFileType());
|
||||
EXPECT_EQ(Archs, Document->getArchitectures());
|
||||
EXPECT_EQ(Uuids, Document->uuids());
|
||||
EXPECT_EQ(1U, Document->getPlatforms().size());
|
||||
EXPECT_EQ(Platform, *(Document->getPlatforms().begin()));
|
||||
EXPECT_EQ(std::string("/System/Library/Frameworks/A.framework/A"),
|
||||
Document->getInstallName());
|
||||
EXPECT_EQ(PackedVersion(1, 2, 3), Document->getCurrentVersion());
|
||||
EXPECT_EQ(PackedVersion(1, 2, 0), Document->getCompatibilityVersion());
|
||||
EXPECT_EQ(5U, Document->getSwiftABIVersion());
|
||||
EXPECT_FALSE(Document->isTwoLevelNamespace());
|
||||
EXPECT_TRUE(Document->isApplicationExtensionSafe());
|
||||
EXPECT_FALSE(Document->isInstallAPI());
|
||||
|
||||
ExportedSymbolSeq Reexports, Undefineds;
|
||||
for (const auto *Sym : Document->symbols()) {
|
||||
ExportedSymbol Temp =
|
||||
ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
|
||||
Sym->isWeakDefined(), Sym->isThreadLocalValue()};
|
||||
EXPECT_FALSE(Sym->isWeakReferenced());
|
||||
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.begin(), Exports.end());
|
||||
llvm::sort(Reexports.begin(), Reexports.end());
|
||||
llvm::sort(Undefineds.begin(), Undefineds.end());
|
||||
|
||||
static ExportedSymbol ExpectedExportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symA", false, false},
|
||||
{SymbolKind::GlobalSymbol, "_symAB", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol ExpectedReexportedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symC", false, false},
|
||||
};
|
||||
|
||||
static ExportedSymbol ExpectedUndefinedSymbols[] = {
|
||||
{SymbolKind::GlobalSymbol, "_symD", false, false},
|
||||
};
|
||||
|
||||
EXPECT_EQ(sizeof(ExpectedExportedSymbols) / sizeof(ExportedSymbol),
|
||||
Exports.size());
|
||||
EXPECT_EQ(sizeof(ExpectedReexportedSymbols) / sizeof(ExportedSymbol),
|
||||
Reexports.size());
|
||||
EXPECT_EQ(sizeof(ExpectedUndefinedSymbols) / sizeof(ExportedSymbol),
|
||||
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(TBDv4, WriteFile) {
|
||||
@ -218,6 +396,89 @@ TEST(TBDv4, WriteFile) {
|
||||
EXPECT_STREQ(TBDv4File, Buffer.c_str());
|
||||
}
|
||||
|
||||
TEST(TBDv4, WriteMultipleDocuments) {
|
||||
static const char TBDv4Inlines[] =
|
||||
"--- !tapi-tbd\n"
|
||||
"tbd-version: 4\n"
|
||||
"targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n"
|
||||
"uuids:\n"
|
||||
" - target: i386-maccatalyst\n"
|
||||
" value: 00000000-0000-0000-0000-000000000002\n"
|
||||
" - target: x86_64-maccatalyst\n"
|
||||
" value: 11111111-1111-1111-1111-111111111112\n"
|
||||
"install-name: "
|
||||
"'/System/Library/Frameworks/Umbrella.framework/Umbrella'\n"
|
||||
"reexported-libraries:\n"
|
||||
" - targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n"
|
||||
" libraries: [ '/System/Library/Frameworks/A.framework/A' ]\n"
|
||||
"--- !tapi-tbd\n"
|
||||
"tbd-version: 4\n"
|
||||
"targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n"
|
||||
"uuids:\n"
|
||||
" - target: i386-maccatalyst\n"
|
||||
" value: 00000000-0000-0000-0000-000000000000\n"
|
||||
" - target: x86_64-maccatalyst\n"
|
||||
" value: 11111111-1111-1111-1111-111111111111\n"
|
||||
"install-name: '/System/Library/Frameworks/A.framework/A'\n"
|
||||
"exports:\n"
|
||||
" - targets: [ i386-maccatalyst ]\n"
|
||||
" weak-symbols: [ _symC ]\n"
|
||||
" - targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n"
|
||||
" symbols: [ _symA ]\n"
|
||||
" objc-classes: [ Class1 ]\n"
|
||||
" - targets: [ x86_64-maccatalyst ]\n"
|
||||
" symbols: [ _symAB ]\n"
|
||||
"...\n";
|
||||
|
||||
InterfaceFile File;
|
||||
PlatformKind Platform = PlatformKind::macCatalyst;
|
||||
TargetList Targets = {
|
||||
Target(AK_i386, Platform),
|
||||
Target(AK_x86_64, Platform),
|
||||
};
|
||||
UUIDs Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000002"},
|
||||
{Targets[1], "11111111-1111-1111-1111-111111111112"}};
|
||||
File.setInstallName("/System/Library/Frameworks/Umbrella.framework/Umbrella");
|
||||
File.setFileType(FileType::TBD_V4);
|
||||
File.addTargets(Targets);
|
||||
File.addUUID(Uuids[0].first, Uuids[0].second);
|
||||
File.addUUID(Uuids[1].first, Uuids[1].second);
|
||||
File.setCompatibilityVersion(PackedVersion(1, 0, 0));
|
||||
File.setCurrentVersion(PackedVersion(1, 0, 0));
|
||||
File.setTwoLevelNamespace();
|
||||
File.setApplicationExtensionSafe(true);
|
||||
File.addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
|
||||
Targets[0]);
|
||||
File.addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
|
||||
Targets[1]);
|
||||
|
||||
// Write Second Document
|
||||
Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
|
||||
{Targets[1], "11111111-1111-1111-1111-111111111111"}};
|
||||
InterfaceFile Document;
|
||||
Document.setInstallName("/System/Library/Frameworks/A.framework/A");
|
||||
Document.setFileType(FileType::TBD_V4);
|
||||
Document.addTargets(Targets);
|
||||
Document.addUUID(Uuids[0].first, Uuids[0].second);
|
||||
Document.addUUID(Uuids[1].first, Uuids[1].second);
|
||||
Document.setCompatibilityVersion(PackedVersion(1, 0, 0));
|
||||
Document.setCurrentVersion(PackedVersion(1, 0, 0));
|
||||
Document.setTwoLevelNamespace();
|
||||
Document.setApplicationExtensionSafe(true);
|
||||
Document.addSymbol(SymbolKind::GlobalSymbol, "_symA", Targets);
|
||||
Document.addSymbol(SymbolKind::GlobalSymbol, "_symAB", {Targets[1]});
|
||||
Document.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
|
||||
SymbolFlags::WeakDefined);
|
||||
Document.addSymbol(SymbolKind::ObjectiveCClass, "Class1", Targets);
|
||||
File.addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
|
||||
|
||||
SmallString<4096> Buffer;
|
||||
raw_svector_ostream OS(Buffer);
|
||||
auto Result = TextAPIWriter::writeToStream(OS, File);
|
||||
EXPECT_FALSE(Result);
|
||||
EXPECT_STREQ(TBDv4Inlines, Buffer.c_str());
|
||||
}
|
||||
|
||||
TEST(TBDv4, MultipleTargets) {
|
||||
static const char TBDv4MultipleTargets[] =
|
||||
"--- !tapi-tbd\n"
|
||||
|
Loading…
Reference in New Issue
Block a user