diff options
author | Sam Powell <sam@sampowell.dev> | 2021-02-18 11:27:54 -0800 |
---|---|---|
committer | Cyndy Ishida <cyndy_ishida@apple.com> | 2021-02-18 11:53:08 -0800 |
commit | eb2eeeb76f7a294b2a8ddd6d09aafe1402ed9348 (patch) | |
tree | 0ac312a46ba4a5d1e861c98c1d715819271fe5ff /llvm/unittests | |
parent | 508aa69e9dbcf4b4de1876cb1b0e9d2c1dbc176f (diff) | |
download | llvm-eb2eeeb76f7a294b2a8ddd6d09aafe1402ed9348.zip llvm-eb2eeeb76f7a294b2a8ddd6d09aafe1402ed9348.tar.gz llvm-eb2eeeb76f7a294b2a8ddd6d09aafe1402ed9348.tar.bz2 |
[llvm][TextAPI] add equality operator for InterfaceFile
This patch adds functionality to compare for the equality between `InterfaceFile`s based on attributes specific to linking.
Reviewed By: cishida, steven_wu
Differential Revision: https://reviews.llvm.org/D96629
Diffstat (limited to 'llvm/unittests')
-rw-r--r-- | llvm/unittests/TextAPI/TextStubHelpers.h | 19 | ||||
-rw-r--r-- | llvm/unittests/TextAPI/TextStubV3Tests.cpp | 110 | ||||
-rw-r--r-- | llvm/unittests/TextAPI/TextStubV4Tests.cpp | 234 |
3 files changed, 363 insertions, 0 deletions
diff --git a/llvm/unittests/TextAPI/TextStubHelpers.h b/llvm/unittests/TextAPI/TextStubHelpers.h index cf93504..183dbf0 100644 --- a/llvm/unittests/TextAPI/TextStubHelpers.h +++ b/llvm/unittests/TextAPI/TextStubHelpers.h @@ -40,5 +40,24 @@ inline std::string stripWhitespace(std::string S) { S.erase(std::remove_if(S.begin(), S.end(), ::isspace), S.end()); return S; } + +// This will transform a single InterfaceFile then compare against the other +// InterfaceFile then transform the second InterfaceFile in the same way to +// regain equality. +inline bool +checkEqualityOnTransform(MachO::InterfaceFile &FileA, + MachO::InterfaceFile &FileB, + void (*Transform)(MachO::InterfaceFile *)) { + Transform(&FileA); + // Files should not be equal. + if (FileA == FileB) + return false; + Transform(&FileB); + // Files should be equal. + if (FileA != FileB) + return false; + return true; +} + } // namespace llvm #endif diff --git a/llvm/unittests/TextAPI/TextStubV3Tests.cpp b/llvm/unittests/TextAPI/TextStubV3Tests.cpp index 2881c95b..8841b20 100644 --- a/llvm/unittests/TextAPI/TextStubV3Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV3Tests.cpp @@ -836,4 +836,114 @@ TEST(TBDv3, MalformedFile2) { ErrorMessage); } +TEST(TBDv3, InterfaceEquality) { + static const char TBDv3File[] = + "--- !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" + "flags: [ installapi ]\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" + " 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: [ 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"; + Expected<TBDFile> ResultA = + TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd")); + EXPECT_TRUE(!!ResultA); + InterfaceFile FileA = std::move(*ResultA.get()); + Expected<TBDFile> ResultB = + TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd")); + EXPECT_TRUE(!!ResultB); + InterfaceFile FileB = std::move(*ResultB.get()); + EXPECT_FALSE(FileA.getPath() == FileB.getPath()); + EXPECT_TRUE(FileA == FileB); +} + + + +TEST(TBDv3, InterfaceInequality) { + static const char TBDv3File[] = "--- !tapi-tbd-v3\n" + "archs: [ armv7, arm64 ]\n" + "platform: ios\n" + "install-name: Test.dylib\n" + "...\n"; + + Expected<TBDFile> ResultA = + TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd")); + EXPECT_TRUE(!!ResultA); + InterfaceFile FileA = std::move(*ResultA.get()); + Expected<TBDFile> ResultB = + TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd")); + EXPECT_TRUE(!!ResultB); + InterfaceFile FileB = std::move(*ResultB.get()); + + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addTarget(Target(AK_x86_64, PlatformKind::iOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setCurrentVersion(PackedVersion(1, 2, 3)); + File->setCompatibilityVersion(PackedVersion(1, 0, 0)); + })); + EXPECT_TRUE(checkEqualityOnTransform( + FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setTwoLevelNamespace(false); + })); + EXPECT_TRUE(checkEqualityOnTransform( + FileA, FileB, [](InterfaceFile *File) { File->setInstallAPI(true); })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setApplicationExtensionSafe(false); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addParentUmbrella(Target(AK_armv7, PlatformKind::iOS), "Umbrella.dylib"); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addAllowableClient("ClientA", Target(AK_armv7, PlatformKind::iOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A", + Target(AK_armv7, PlatformKind::iOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addSymbol(SymbolKind::GlobalSymbol, "_symA", {Target(AK_arm64, PlatformKind::iOS)}); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + InterfaceFile Document; + Document.addTargets(TargetList{Target(AK_armv7, PlatformKind::iOS), + Target(AK_arm64, PlatformKind::iOS)}); + Document.setInstallName("/System/Library/Frameworks/A.framework/A"); + File->addDocument(std::make_shared<InterfaceFile>(std::move(Document))); + })); +} + } // namespace TBDv3 diff --git a/llvm/unittests/TextAPI/TextStubV4Tests.cpp b/llvm/unittests/TextAPI/TextStubV4Tests.cpp index 403e2d6..87dae84 100644 --- a/llvm/unittests/TextAPI/TextStubV4Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV4Tests.cpp @@ -938,4 +938,238 @@ TEST(TBDv4, MalformedFile3) { ErrorMessage); } +TEST(TBDv4, InterfaceEquality) { + static const char TBDv4File[] = + "--- !tapi-tbd\n" + "tbd-version: 4\n" + "targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" + "uuids:\n" + " - target: i386-macos\n" + " value: 00000000-0000-0000-0000-000000000000\n" + " - target: x86_64-macos\n" + " value: 11111111-1111-1111-1111-111111111111\n" + " - target: x86_64-ios\n" + " value: 11111111-1111-1111-1111-111111111111\n" + "flags: [ flat_namespace, installapi ]\n" + "install-name: Umbrella.framework/Umbrella\n" + "current-version: 1.2.3\n" + "compatibility-version: 1.2\n" + "swift-abi-version: 5\n" + "parent-umbrella:\n" + " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" + " umbrella: System\n" + "allowable-clients:\n" + " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" + " clients: [ ClientA ]\n" + "reexported-libraries:\n" + " - targets: [ i386-macos ]\n" + " libraries: [ /System/Library/Frameworks/A.framework/A ]\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-ios ]\n" + " symbols: [_symB]\n" + " - targets: [ x86_64-macos, x86_64-ios ]\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" + "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"; + + Expected<TBDFile> ResultA = + TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd")); + EXPECT_TRUE(!!ResultA); + InterfaceFile FileA = std::move(*ResultA.get()); + Expected<TBDFile> ResultB = + TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestB.tbd")); + EXPECT_TRUE(!!ResultB); + InterfaceFile FileB = std::move(*ResultB.get()); + EXPECT_TRUE(FileA == FileB); +} + +TEST(TBDv4, InterfaceDiffVersionsEquality) { + static const char TBDv4File[] = + "--- !tapi-tbd\n" + "tbd-version: 4\n" + "targets: [ i386-macos, x86_64-macos ]\n" + "uuids:\n" + " - target: i386-macos\n" + " value: 00000000-0000-0000-0000-000000000000\n" + " - target: x86_64-macos\n" + " value: 11111111-1111-1111-1111-111111111111\n" + "flags: [ installapi ]\n" + "install-name: Umbrella.framework/Umbrella\n" + "current-version: 1.2.3\n" + "compatibility-version: 1.0\n" + "swift-abi-version: 5\n" + "parent-umbrella:\n" + " - targets: [ i386-macos, x86_64-macos ]\n" + " umbrella: System\n" + "allowable-clients:\n" + " - targets: [ i386-macos, x86_64-macos ]\n" + " clients: [ ClientA ]\n" + "reexported-libraries:\n" + " - targets: [ i386-macos ]\n" + " libraries: [ /System/Library/Frameworks/A.framework/A ]\n" + "exports:\n" + " - targets: [ i386-macos ]\n" + " symbols: [ _sym5 ]\n" + " objc-classes: [ class3]\n" + " objc-eh-types: []\n" + " objc-ivars: [ class1._ivar3 ]\n" + " weak-symbols: [ _weak3 ]\n" + " - targets: [ x86_64-macos ]\n" + " symbols: [_symAB]\n" + " - targets: [ i386-macos, x86_64-macos ]\n" + " symbols: [_symA]\n" + " objc-classes: [ class1, class2 ]\n" + " objc-eh-types: [ class1 ]\n" + " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n" + " weak-symbols: [ _weak1, _weak2 ]\n" + " thread-local-symbols: [ _tlv1, _tlv3 ]\n" + "undefineds:\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" + "...\n"; + + static const char TBDv3File[] = + "--- !tapi-tbd-v3\n" + "archs: [ i386, x86_64 ]\n" + "uuids: [ 'i386: 00000000-0000-0000-0000-000000000000',\n" + " 'x86_64: 22222222-2222-2222-2222-222222222222']\n" + "platform: macosx\n" + "flags: [ installapi ]\n" + "install-name: Umbrella.framework/Umbrella\n" + "current-version: 1.2.3\n" + "compatibility-version: 1.0\n" + "swift-abi-version: 5\n" + "parent-umbrella: System\n" + "exports:\n" + " - archs: [ i386, x86_64 ]\n" + " allowable-clients: [ ClientA ]\n" + " symbols: [ _symA ]\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: [ i386 ]\n" + " re-exports: [ /System/Library/Frameworks/A.framework/A ]\n" + " symbols: [ _sym5 ]\n" + " objc-classes: [ class3 ]\n" + " objc-ivars: [ class1._ivar3 ]\n" + " weak-def-symbols: [ _weak3 ]\n" + " - archs: [ x86_64 ]\n" + " symbols: [ _symAB ]\n" + "undefineds:\n" + " - archs: [ i386 ]\n" + " symbols: [ _symC ]\n" + "...\n"; + + Expected<TBDFile> ResultA = + TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd")); + EXPECT_TRUE(!!ResultA); + InterfaceFile FileA = std::move(*ResultA.get()); + Expected<TBDFile> ResultB = + TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd")); + EXPECT_TRUE(!!ResultB); + InterfaceFile FileB = std::move(*ResultB.get()); + EXPECT_NE(FileA.uuids(), FileB.uuids()); + EXPECT_TRUE(FileA == FileB); +} + +TEST(TBDv4, InterfaceInequality) { + static const char TBDv4File[] = "--- !tapi-tbd\n" + "tbd-version: 4\n" + "targets: [ i386-macos, x86_64-macos ]\n" + "install-name: Umbrella.framework/Umbrella\n" + "...\n"; + + Expected<TBDFile> ResultA = + TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd")); + EXPECT_TRUE(!!ResultA); + InterfaceFile FileA = std::move(*ResultA.get()); + Expected<TBDFile> ResultB = + TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestB.tbd")); + EXPECT_TRUE(!!ResultB); + InterfaceFile FileB = std::move(*ResultB.get()); + + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addTarget(Target(AK_x86_64, PlatformKind::iOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setCurrentVersion(PackedVersion(1, 2, 3)); + File->setCompatibilityVersion(PackedVersion(1, 0, 0)); + })); + EXPECT_TRUE(checkEqualityOnTransform( + FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setTwoLevelNamespace(false); + })); + EXPECT_TRUE(checkEqualityOnTransform( + FileA, FileB, [](InterfaceFile *File) { File->setInstallAPI(true); })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->setApplicationExtensionSafe(false); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addParentUmbrella(Target(AK_x86_64, PlatformKind::macOS), "System.dylib"); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addAllowableClient("ClientA", Target(AK_i386, PlatformKind::macOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A", + Target(AK_i386, PlatformKind::macOS)); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + File->addSymbol(SymbolKind::GlobalSymbol, "_symA", {Target(AK_x86_64, PlatformKind::macOS)}); + })); + EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { + InterfaceFile Document; + Document.addTargets(TargetList {Target(AK_i386, PlatformKind::macOS), + Target(AK_x86_64, PlatformKind::macOS)}); + Document.setInstallName("/System/Library/Frameworks/A.framework/A"); + File->addDocument(std::make_shared<InterfaceFile>(std::move(Document))); + })); +} + } // end namespace TBDv4 |