941 lines · cpp
1//===-- TextStubV3Tests.cpp - TBD V3 File Test ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===-----------------------------------------------------------------------===/8#include "TextStubHelpers.h"9#include "llvm/TextAPI/InterfaceFile.h"10#include "llvm/TextAPI/TextAPIReader.h"11#include "llvm/TextAPI/TextAPIWriter.h"12#include "gtest/gtest.h"13#include <string>14#include <vector>15 16using namespace llvm;17using namespace llvm::MachO;18 19static ExportedSymbol TBDv3Symbols[] = {20 {EncodeKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},21 {EncodeKind::GlobalSymbol, "_sym1", false, false},22 {EncodeKind::GlobalSymbol, "_sym2", false, false},23 {EncodeKind::GlobalSymbol, "_sym3", false, false},24 {EncodeKind::GlobalSymbol, "_sym4", false, false},25 {EncodeKind::GlobalSymbol, "_sym5", false, false},26 {EncodeKind::GlobalSymbol, "_tlv1", false, true},27 {EncodeKind::GlobalSymbol, "_tlv3", false, true},28 {EncodeKind::GlobalSymbol, "_weak1", true, false},29 {EncodeKind::GlobalSymbol, "_weak2", true, false},30 {EncodeKind::GlobalSymbol, "_weak3", true, false},31 {EncodeKind::ObjectiveCClass, "class1", false, false},32 {EncodeKind::ObjectiveCClass, "class2", false, false},33 {EncodeKind::ObjectiveCClass, "class3", false, false},34 {EncodeKind::ObjectiveCClassEHType, "class1", false, false},35 {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},36 {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},37 {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},38};39 40namespace TBDv3 {41 42TEST(TBDv3, ReadFile) {43 static const char TBDv3File1[] =44 "--- !tapi-tbd-v3\n"45 "archs: [ armv7, arm64 ]\n"46 "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"47 " 'arm64: 11111111-1111-1111-1111-111111111111']\n"48 "platform: ios\n"49 "flags: [ installapi ]\n"50 "install-name: Test.dylib\n"51 "current-version: 2.3.4\n"52 "compatibility-version: 1.0\n"53 "swift-abi-version: 1.1\n"54 "parent-umbrella: Umbrella.dylib\n"55 "exports:\n"56 " - archs: [ armv7, arm64 ]\n"57 " allowable-clients: [ clientA ]\n"58 " re-exports: [ /usr/lib/libfoo.dylib ]\n"59 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"60 " objc-classes: [ class1, class2 ]\n"61 " objc-eh-types: [ class1 ]\n"62 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"63 " weak-def-symbols: [ _weak1, _weak2 ]\n"64 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"65 " - archs: [ armv7 ]\n"66 " symbols: [ _sym5 ]\n"67 " objc-classes: [ class3 ]\n"68 " objc-ivars: [ class1._ivar3 ]\n"69 " weak-def-symbols: [ _weak3 ]\n"70 " thread-local-symbols: [ _tlv3 ]\n"71 "...\n";72 73 Expected<TBDFile> Result =74 TextAPIReader::get(MemoryBufferRef(TBDv3File1, "Test.tbd"));75 EXPECT_TRUE(!!Result);76 TBDFile File = std::move(Result.get());77 EXPECT_EQ(FileType::TBD_V3, File->getFileType());78 auto Archs = AK_armv7 | AK_arm64;79 auto Platform = PLATFORM_IOS;80 TargetList Targets;81 for (auto &&arch : Archs)82 Targets.emplace_back(Target(arch, Platform));83 EXPECT_EQ(Archs, File->getArchitectures());84 TargetToAttr Uuids = {{Target(AK_armv7, PLATFORM_UNKNOWN),85 "00000000-0000-0000-0000-000000000000"},86 {Target(AK_arm64, PLATFORM_UNKNOWN),87 "11111111-1111-1111-1111-111111111111"}};88 EXPECT_EQ(File->getPlatforms().size(), 1U);89 EXPECT_EQ(Platform, *File->getPlatforms().begin());90 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());91 EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());92 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());93 EXPECT_EQ(2U, File->getSwiftABIVersion());94 EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());95 EXPECT_TRUE(File->isTwoLevelNamespace());96 EXPECT_TRUE(File->isApplicationExtensionSafe());97 InterfaceFileRef client("clientA", Targets);98 InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);99 EXPECT_EQ(1U, File->allowableClients().size());100 EXPECT_EQ(client, File->allowableClients().front());101 EXPECT_EQ(1U, File->reexportedLibraries().size());102 EXPECT_EQ(reexport, File->reexportedLibraries().front());103 104 ExportedSymbolSeq Exports;105 for (const auto *Sym : File->symbols()) {106 EXPECT_FALSE(Sym->isWeakReferenced());107 EXPECT_FALSE(Sym->isUndefined());108 Exports.emplace_back(109 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),110 Sym->isWeakDefined(), Sym->isThreadLocalValue()});111 }112 llvm::sort(Exports);113 114 EXPECT_EQ(std::size(TBDv3Symbols), Exports.size());115 EXPECT_TRUE(116 std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));117}118 119TEST(TBDv3, ReadMultipleDocuments) {120 static const char TBDv3Inlines[] =121 "--- !tapi-tbd-v3\n"122 "archs: [ armv7, arm64 ]\n"123 "platform: ios\n"124 "install-name: Test.dylib\n"125 "current-version: 2.3.4\n"126 "compatibility-version: 1.0\n"127 "swift-abi-version: 1.1\n"128 "parent-umbrella: Umbrella.dylib\n"129 "exports:\n"130 " - archs: [ armv7, arm64 ]\n"131 " allowable-clients: [ clientA ]\n"132 " re-exports: [ /usr/lib/libfoo.dylib,\n"133 " TestInline.dylib ]\n"134 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"135 " objc-classes: [ class1, class2 ]\n"136 " objc-eh-types: [ class1 ]\n"137 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"138 " weak-def-symbols: [ _weak1, _weak2 ]\n"139 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"140 " - archs: [ armv7 ]\n"141 " symbols: [ _sym5 ]\n"142 " objc-classes: [ class3 ]\n"143 " objc-ivars: [ class1._ivar3 ]\n"144 " weak-def-symbols: [ _weak3 ]\n"145 " thread-local-symbols: [ _tlv3 ]\n"146 "--- !tapi-tbd-v3\n"147 "archs: [ armv7, arm64 ]\n"148 "platform: ios\n"149 "install-name: TestInline.dylib\n"150 "swift-abi-version: 1.1\n"151 "exports:\n"152 " - archs: [ armv7, arm64 ]\n"153 " symbols: [ _sym5, _sym6 ]\n"154 "...\n";155 156 Expected<TBDFile> Result =157 TextAPIReader::get(MemoryBufferRef(TBDv3Inlines, "Test.tbd"));158 EXPECT_TRUE(!!Result);159 TBDFile File = std::move(Result.get());160 EXPECT_EQ(File->documents().size(), 1U);161 EXPECT_EQ(FileType::TBD_V3, File->getFileType());162 auto Archs = AK_armv7 | AK_arm64;163 auto Platform = PLATFORM_IOS;164 TargetList Targets;165 for (auto &&arch : Archs)166 Targets.emplace_back(Target(arch, Platform));167 EXPECT_EQ(Archs, File->getArchitectures());168 TargetToAttr Uuids = {{Target(AK_armv7, PLATFORM_UNKNOWN),169 "00000000-0000-0000-0000-000000000000"},170 {Target(AK_arm64, PLATFORM_UNKNOWN),171 "11111111-1111-1111-1111-111111111111"}};172 EXPECT_EQ(File->getPlatforms().size(), 1U);173 EXPECT_EQ(Platform, *File->getPlatforms().begin());174 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());175 EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());176 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());177 EXPECT_EQ(2U, File->getSwiftABIVersion());178 EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());179 EXPECT_TRUE(File->isTwoLevelNamespace());180 EXPECT_TRUE(File->isApplicationExtensionSafe());181 InterfaceFileRef Client("clientA", Targets);182 const std::vector<InterfaceFileRef> Reexports = {183 InterfaceFileRef("/usr/lib/libfoo.dylib", Targets),184 InterfaceFileRef("TestInline.dylib", Targets)};185 EXPECT_EQ(1U, File->allowableClients().size());186 EXPECT_EQ(Client, File->allowableClients().front());187 EXPECT_EQ(2U, File->reexportedLibraries().size());188 EXPECT_EQ(Reexports, File->reexportedLibraries());189 190 ExportedSymbolSeq Exports;191 for (const auto *Sym : File->symbols()) {192 EXPECT_FALSE(Sym->isWeakReferenced());193 EXPECT_FALSE(Sym->isUndefined());194 Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),195 Sym->isWeakDefined(),196 Sym->isThreadLocalValue()});197 }198 llvm::sort(Exports);199 200 EXPECT_EQ(std::size(TBDv3Symbols), Exports.size());201 EXPECT_TRUE(202 std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));203 204 // Check Second Document205 Exports.clear();206 TBDReexportFile Document = File->documents().front();207 EXPECT_EQ(FileType::TBD_V3, Document->getFileType());208 EXPECT_EQ(Archs, Document->getArchitectures());209 EXPECT_EQ(Platform, *Document->getPlatforms().begin());210 EXPECT_EQ(std::string("TestInline.dylib"), Document->getInstallName());211 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());212 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());213 EXPECT_EQ(2U, Document->getSwiftABIVersion());214 215 for (const auto *Sym : Document->symbols()) {216 EXPECT_FALSE(Sym->isWeakReferenced());217 EXPECT_FALSE(Sym->isUndefined());218 Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),219 Sym->isWeakDefined(),220 Sym->isThreadLocalValue()});221 }222 llvm::sort(Exports);223 224 ExportedSymbolSeq DocumentSymbols{225 {EncodeKind::GlobalSymbol, "_sym5", false, false},226 {EncodeKind::GlobalSymbol, "_sym6", false, false},227 };228 229 EXPECT_EQ(DocumentSymbols.size(), Exports.size());230 EXPECT_TRUE(231 std::equal(Exports.begin(), Exports.end(), DocumentSymbols.begin()));232}233 234TEST(TBDv3, WriteFile) {235 static const char TBDv3File3[] =236 "--- !tapi-tbd-v3\n"237 "archs: [ i386, x86_64 ]\n"238 "platform: macosx\n"239 "install-name: '/usr/lib/libfoo.dylib'\n"240 "current-version: 1.2.3\n"241 "compatibility-version: 0\n"242 "swift-abi-version: 5\n"243 "exports:\n"244 " - archs: [ i386 ]\n"245 " symbols: [ _sym1 ]\n"246 " weak-def-symbols: [ _sym2 ]\n"247 " thread-local-symbols: [ _sym3 ]\n"248 " - archs: [ x86_64 ]\n"249 " allowable-clients: [ clientA ]\n"250 " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"251 " objc-classes: [ Class1 ]\n"252 " objc-eh-types: [ Class1 ]\n"253 " objc-ivars: [ Class1._ivar1 ]\n"254 "...\n";255 256 InterfaceFile File;257 TargetList Targets;258 for (auto &&arch : AK_i386 | AK_x86_64)259 Targets.emplace_back(Target(arch, PLATFORM_MACOS));260 File.setPath("libfoo.dylib");261 File.setInstallName("/usr/lib/libfoo.dylib");262 File.setFileType(FileType::TBD_V3);263 File.addTargets(Targets);264 File.setCurrentVersion(PackedVersion(1, 2, 3));265 File.setTwoLevelNamespace();266 File.setApplicationExtensionSafe();267 File.setSwiftABIVersion(5);268 File.setObjCConstraint(ObjCConstraintType::Retain_Release);269 File.addAllowableClient("clientA", Targets[1]);270 File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);271 File.addSymbol(EncodeKind::GlobalSymbol, "_sym1", {Targets[0]});272 File.addSymbol(EncodeKind::GlobalSymbol, "_sym2", {Targets[0]},273 SymbolFlags::WeakDefined);274 File.addSymbol(EncodeKind::GlobalSymbol, "_sym3", {Targets[0]},275 SymbolFlags::ThreadLocalValue);276 File.addSymbol(EncodeKind::ObjectiveCClass, "Class1", {Targets[1]});277 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "Class1", {Targets[1]});278 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "Class1._ivar1",279 {Targets[1]});280 281 SmallString<4096> Buffer;282 raw_svector_ostream OS(Buffer);283 Error Result = TextAPIWriter::writeToStream(OS, File);284 EXPECT_FALSE(Result);285 EXPECT_STREQ(TBDv3File3, Buffer.c_str());286}287 288TEST(TBDv3, WriteMultipleDocuments) {289 static const char TBDv3Inlines[] =290 "--- !tapi-tbd-v3\n"291 "archs: [ i386, x86_64 ]\n"292 "platform: zippered\n"293 "install-name: '/usr/lib/libfoo.dylib'\n"294 "current-version: 1.2.3\n"295 "compatibility-version: 0\n"296 "swift-abi-version: 5\n"297 "exports:\n"298 " - archs: [ x86_64 ]\n"299 " allowable-clients: [ clientA ]\n"300 " re-exports: [ '/usr/lib/libbar.dylib' ]\n"301 " - archs: [ i386, x86_64 ]\n"302 " symbols: [ _sym1 ]\n"303 " objc-classes: [ Class1 ]\n"304 " objc-eh-types: [ Class1 ]\n"305 " objc-ivars: [ Class1._ivar1 ]\n"306 " weak-def-symbols: [ _sym2 ]\n"307 " thread-local-symbols: [ _symA ]\n"308 "--- !tapi-tbd-v3\n"309 "archs: [ i386 ]\n"310 "platform: macosx\n"311 "install-name: '/usr/lib/libbar.dylib'\n"312 "current-version: 0\n"313 "compatibility-version: 0\n"314 "swift-abi-version: 5\n"315 "objc-constraint: none\n"316 "exports:\n"317 " - archs: [ i386 ]\n"318 " symbols: [ _sym3, _sym4 ]\n"319 "...\n";320 321 InterfaceFile File;322 TargetList Targets;323 for (auto &&arch : AK_i386 | AK_x86_64) {324 Targets.emplace_back(Target(arch, PLATFORM_MACOS));325 Targets.emplace_back(Target(arch, PLATFORM_MACCATALYST));326 }327 File.addTargets(Targets);328 File.setPath("libfoo.dylib");329 File.setInstallName("/usr/lib/libfoo.dylib");330 File.setFileType(FileType::TBD_V3);331 File.setCurrentVersion(PackedVersion(1, 2, 3));332 File.setTwoLevelNamespace();333 File.setApplicationExtensionSafe();334 File.setSwiftABIVersion(5);335 File.setObjCConstraint(ObjCConstraintType::Retain_Release);336 File.addAllowableClient("clientA", Targets[2]);337 File.addReexportedLibrary("/usr/lib/libbar.dylib", Targets[2]);338 File.addSymbol(EncodeKind::GlobalSymbol, "_sym1", Targets);339 File.addSymbol(EncodeKind::GlobalSymbol, "_sym2", Targets,340 SymbolFlags::WeakDefined);341 File.addSymbol(EncodeKind::GlobalSymbol, "_symA", Targets,342 SymbolFlags::ThreadLocalValue);343 File.addSymbol(EncodeKind::ObjectiveCClass, "Class1", Targets);344 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "Class1", Targets);345 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "Class1._ivar1",346 Targets);347 348 // Inline document349 InterfaceFile Document;350 Targets = {Target(AK_i386, PLATFORM_MACOS)};351 Document.addTargets(Targets);352 Document.setPath("libbar.dylib");353 Document.setInstallName("/usr/lib/libbar.dylib");354 Document.setFileType(FileType::TBD_V3);355 Document.setTwoLevelNamespace();356 Document.setApplicationExtensionSafe();357 Document.setSwiftABIVersion(5);358 Document.addSymbol(EncodeKind::GlobalSymbol, "_sym3", Targets);359 Document.addSymbol(EncodeKind::GlobalSymbol, "_sym4", Targets);360 File.addDocument(std::make_shared<InterfaceFile>(std::move(Document)));361 362 SmallString<4096> Buffer;363 raw_svector_ostream OS(Buffer);364 Error Result = TextAPIWriter::writeToStream(OS, File);365 EXPECT_FALSE(Result);366 EXPECT_STREQ(TBDv3Inlines, Buffer.c_str());367}368 369TEST(TBDv3, Platform_macOS) {370 static const char TBDv3PlatformMacOS[] = "--- !tapi-tbd-v3\n"371 "archs: [ x86_64 ]\n"372 "platform: macosx\n"373 "install-name: Test.dylib\n"374 "...\n";375 376 Expected<TBDFile> Result =377 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformMacOS, "Test.tbd"));378 EXPECT_TRUE(!!Result);379 auto Platform = PLATFORM_MACOS;380 TBDFile File = std::move(Result.get());381 EXPECT_EQ(FileType::TBD_V3, File->getFileType());382 EXPECT_EQ(File->getPlatforms().size(), 1U);383 EXPECT_EQ(Platform, *File->getPlatforms().begin());384 385 SmallString<4096> Buffer;386 raw_svector_ostream OS(Buffer);387 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);388 EXPECT_TRUE(!WriteResult);389 EXPECT_EQ(stripWhitespace(TBDv3PlatformMacOS),390 stripWhitespace(Buffer.c_str()));391}392 393TEST(TBDv3, Platform_iOS) {394 static const char TBDv3PlatformiOS[] = "--- !tapi-tbd-v3\n"395 "archs: [ arm64 ]\n"396 "platform: ios\n"397 "install-name: Test.dylib\n"398 "...\n";399 400 Expected<TBDFile> Result =401 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOS, "Test.tbd"));402 EXPECT_TRUE(!!Result);403 auto Platform = PLATFORM_IOS;404 TBDFile File = std::move(Result.get());405 EXPECT_EQ(FileType::TBD_V3, File->getFileType());406 EXPECT_EQ(File->getPlatforms().size(), 1U);407 EXPECT_EQ(Platform, *File->getPlatforms().begin());408 409 SmallString<4096> Buffer;410 raw_svector_ostream OS(Buffer);411 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);412 EXPECT_TRUE(!WriteResult);413 EXPECT_EQ(stripWhitespace(TBDv3PlatformiOS), stripWhitespace(Buffer.c_str()));414}415 416TEST(TBDv3, Platform_watchOS) {417 static const char TBDv3watchOS[] = "--- !tapi-tbd-v3\n"418 "archs: [ armv7k ]\n"419 "platform: watchos\n"420 "install-name: Test.dylib\n"421 "...\n";422 423 Expected<TBDFile> Result =424 TextAPIReader::get(MemoryBufferRef(TBDv3watchOS, "Test.tbd"));425 EXPECT_TRUE(!!Result);426 auto Platform = PLATFORM_WATCHOS;427 TBDFile File = std::move(Result.get());428 EXPECT_EQ(FileType::TBD_V3, File->getFileType());429 EXPECT_EQ(File->getPlatforms().size(), 1U);430 EXPECT_EQ(Platform, *File->getPlatforms().begin());431 432 SmallString<4096> Buffer;433 raw_svector_ostream OS(Buffer);434 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);435 EXPECT_TRUE(!WriteResult);436 EXPECT_EQ(stripWhitespace(TBDv3watchOS), stripWhitespace(Buffer.c_str()));437}438 439TEST(TBDv3, Platform_tvOS) {440 static const char TBDv3PlatformtvOS[] = "--- !tapi-tbd-v3\n"441 "archs: [ arm64 ]\n"442 "platform: tvos\n"443 "install-name: Test.dylib\n"444 "...\n";445 446 Expected<TBDFile> Result =447 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOS, "Test.tbd"));448 EXPECT_TRUE(!!Result);449 TBDFile File = std::move(Result.get());450 auto Platform = PLATFORM_TVOS;451 EXPECT_EQ(FileType::TBD_V3, File->getFileType());452 EXPECT_EQ(File->getPlatforms().size(), 1U);453 EXPECT_EQ(Platform, *File->getPlatforms().begin());454 455 SmallString<4096> Buffer;456 raw_svector_ostream OS(Buffer);457 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);458 EXPECT_FALSE(WriteResult);459 EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOS),460 stripWhitespace(Buffer.c_str()));461}462 463TEST(TBDv3, Platform_bridgeOS) {464 static const char TBDv3BridgeOS[] = "--- !tapi-tbd-v3\n"465 "archs: [ armv7k ]\n"466 "platform: bridgeos\n"467 "install-name: Test.dylib\n"468 "...\n";469 470 Expected<TBDFile> Result =471 TextAPIReader::get(MemoryBufferRef(TBDv3BridgeOS, "Test.tbd"));472 EXPECT_TRUE(!!Result);473 auto Platform = PLATFORM_BRIDGEOS;474 TBDFile File = std::move(Result.get());475 EXPECT_EQ(FileType::TBD_V3, File->getFileType());476 EXPECT_EQ(File->getPlatforms().size(), 1U);477 EXPECT_EQ(Platform, *File->getPlatforms().begin());478 479 SmallString<4096> Buffer;480 raw_svector_ostream OS(Buffer);481 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);482 EXPECT_TRUE(!WriteResult);483 EXPECT_EQ(stripWhitespace(TBDv3BridgeOS), stripWhitespace(Buffer.c_str()));484}485 486TEST(TBDv3, Platform_macCatalyst) {487 static const char TBDv3PlatformiOSmac[] = "--- !tapi-tbd-v3\n"488 "archs: [ armv7k ]\n"489 "platform: maccatalyst\n"490 "install-name: Test.dylib\n"491 "...\n";492 493 Expected<TBDFile> Result =494 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSmac, "Test.tbd"));495 EXPECT_TRUE(!!Result);496 auto Platform = PLATFORM_MACCATALYST;497 TBDFile File = std::move(Result.get());498 EXPECT_EQ(FileType::TBD_V3, File->getFileType());499 EXPECT_EQ(Platform, *File->getPlatforms().begin());500 501 SmallString<4096> Buffer;502 raw_svector_ostream OS(Buffer);503 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);504 EXPECT_TRUE(!WriteResult);505 EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSmac),506 stripWhitespace(Buffer.c_str()));507}508 509TEST(TBDv3, Platform_zippered) {510 static const char TBDv3PlatformZippered[] = "--- !tapi-tbd-v3\n"511 "archs: [ armv7k ]\n"512 "platform: zippered\n"513 "install-name: Test.dylib\n"514 "...\n";515 516 Expected<TBDFile> Result =517 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformZippered, "Test.tbd"));518 EXPECT_TRUE(!!Result);519 TBDFile File = std::move(Result.get());520 EXPECT_EQ(FileType::TBD_V3, File->getFileType());521 522 PlatformSet Platforms;523 Platforms.insert(PLATFORM_MACOS);524 Platforms.insert(PLATFORM_MACCATALYST);525 EXPECT_EQ(Platforms.size(), File->getPlatforms().size());526 for (auto Platform : File->getPlatforms())527 EXPECT_EQ(Platforms.count(Platform), 1U);528 529 SmallString<4096> Buffer;530 raw_svector_ostream OS(Buffer);531 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);532 EXPECT_TRUE(!WriteResult);533 EXPECT_EQ(stripWhitespace(TBDv3PlatformZippered),534 stripWhitespace(Buffer.c_str()));535}536 537TEST(TBDv3, Platform_iOSSim) {538 static const char TBDv3PlatformiOSsim[] = "--- !tapi-tbd-v3\n"539 "archs: [ x86_64 ]\n"540 "platform: ios\n"541 "install-name: Test.dylib\n"542 "...\n";543 544 Expected<TBDFile> Result =545 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSsim, "Test.tbd"));546 EXPECT_TRUE(!!Result);547 auto Platform = PLATFORM_IOSSIMULATOR;548 TBDFile File = std::move(Result.get());549 EXPECT_EQ(FileType::TBD_V3, File->getFileType());550 EXPECT_EQ(File->getPlatforms().size(), 1U);551 EXPECT_EQ(Platform, *File->getPlatforms().begin());552 553 SmallString<4096> Buffer;554 raw_svector_ostream OS(Buffer);555 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);556 EXPECT_TRUE(!WriteResult);557 EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSsim),558 stripWhitespace(Buffer.c_str()));559}560 561TEST(TBDv3, Platform_watchOSSim) {562 static const char TBDv3watchOSsim[] = "--- !tapi-tbd-v3\n"563 "archs: [ x86_64 ]\n"564 "platform: watchos\n"565 "install-name: Test.dylib\n"566 "...\n";567 568 Expected<TBDFile> Result =569 TextAPIReader::get(MemoryBufferRef(TBDv3watchOSsim, "Test.tbd"));570 EXPECT_TRUE(!!Result);571 auto Platform = PLATFORM_WATCHOSSIMULATOR;572 TBDFile File = std::move(Result.get());573 EXPECT_EQ(FileType::TBD_V3, File->getFileType());574 EXPECT_EQ(File->getPlatforms().size(), 1U);575 EXPECT_EQ(Platform, *File->getPlatforms().begin());576 577 SmallString<4096> Buffer;578 raw_svector_ostream OS(Buffer);579 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);580 EXPECT_TRUE(!WriteResult);581 EXPECT_EQ(stripWhitespace(TBDv3watchOSsim), stripWhitespace(Buffer.c_str()));582}583 584TEST(TBDv3, Platform_tvOSSim) {585 static const char TBDv3PlatformtvOSsim[] = "--- !tapi-tbd-v3\n"586 "archs: [ x86_64 ]\n"587 "platform: tvos\n"588 "install-name: Test.dylib\n"589 "...\n";590 591 Expected<TBDFile> Result =592 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOSsim, "Test.tbd"));593 EXPECT_TRUE(!!Result);594 TBDFile File = std::move(Result.get());595 auto Platform = PLATFORM_TVOSSIMULATOR;596 EXPECT_EQ(FileType::TBD_V3, File->getFileType());597 EXPECT_EQ(File->getPlatforms().size(), 1U);598 EXPECT_EQ(Platform, *File->getPlatforms().begin());599 600 SmallString<4096> Buffer;601 raw_svector_ostream OS(Buffer);602 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);603 EXPECT_TRUE(!WriteResult);604 EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOSsim),605 stripWhitespace(Buffer.c_str()));606}607 608TEST(TBDv3, Arch_arm64e) {609 static const char TBDv3ArchArm64e[] = "--- !tapi-tbd-v3\n"610 "archs: [ arm64, arm64e ]\n"611 "platform: ios\n"612 "install-name: Test.dylib\n"613 "...\n";614 615 Expected<TBDFile> Result =616 TextAPIReader::get(MemoryBufferRef(TBDv3ArchArm64e, "Test.tbd"));617 EXPECT_TRUE(!!Result);618 TBDFile File = std::move(Result.get());619 auto Platform = PLATFORM_IOS;620 auto Archs = AK_arm64 | AK_arm64e;621 EXPECT_EQ(FileType::TBD_V3, File->getFileType());622 EXPECT_EQ(File->getPlatforms().size(), 1U);623 EXPECT_EQ(Platform, *File->getPlatforms().begin());624 EXPECT_EQ(Archs, File->getArchitectures());625 626 SmallString<4096> Buffer;627 raw_svector_ostream OS(Buffer);628 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);629 EXPECT_TRUE(!WriteResult);630 EXPECT_EQ(stripWhitespace(TBDv3ArchArm64e), stripWhitespace(Buffer.c_str()));631}632 633TEST(TBDv3, Swift_1_0) {634 static const char TBDv3Swift1[] = "--- !tapi-tbd-v3\n"635 "archs: [ arm64 ]\n"636 "platform: ios\n"637 "install-name: Test.dylib\n"638 "swift-abi-version: 1.0\n"639 "...\n";640 641 Expected<TBDFile> Result =642 TextAPIReader::get(MemoryBufferRef(TBDv3Swift1, "Test.tbd"));643 EXPECT_TRUE(!!Result);644 TBDFile File = std::move(Result.get());645 EXPECT_EQ(FileType::TBD_V3, File->getFileType());646 EXPECT_EQ(1U, File->getSwiftABIVersion());647 648 SmallString<4096> Buffer;649 raw_svector_ostream OS(Buffer);650 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);651 EXPECT_TRUE(!WriteResult);652 EXPECT_EQ(stripWhitespace(TBDv3Swift1), stripWhitespace(Buffer.c_str()));653}654 655TEST(TBDv3, Swift_1_1) {656 static const char TBDv3Swift1Dot[] = "--- !tapi-tbd-v3\n"657 "archs: [ arm64 ]\n"658 "platform: ios\n"659 "install-name: Test.dylib\n"660 "swift-abi-version: 1.1\n"661 "...\n";662 663 Expected<TBDFile> Result =664 TextAPIReader::get(MemoryBufferRef(TBDv3Swift1Dot, "Test.tbd"));665 EXPECT_TRUE(!!Result);666 TBDFile File = std::move(Result.get());667 EXPECT_EQ(FileType::TBD_V3, File->getFileType());668 EXPECT_EQ(2U, File->getSwiftABIVersion());669 670 SmallString<4096> Buffer;671 raw_svector_ostream OS(Buffer);672 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);673 EXPECT_TRUE(!WriteResult);674 EXPECT_EQ(stripWhitespace(TBDv3Swift1Dot), stripWhitespace(Buffer.c_str()));675}676 677TEST(TBDv3, Swift_2_0) {678 static const char TBDv3Swift2[] = "--- !tapi-tbd-v3\n"679 "archs: [ arm64 ]\n"680 "platform: ios\n"681 "install-name: Test.dylib\n"682 "swift-abi-version: 2.0\n"683 "...\n";684 685 Expected<TBDFile> Result =686 TextAPIReader::get(MemoryBufferRef(TBDv3Swift2, "Test.tbd"));687 EXPECT_TRUE(!!Result);688 TBDFile File = std::move(Result.get());689 EXPECT_EQ(FileType::TBD_V3, File->getFileType());690 EXPECT_EQ(3U, File->getSwiftABIVersion());691 692 SmallString<4096> Buffer;693 raw_svector_ostream OS(Buffer);694 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);695 EXPECT_TRUE(!WriteResult);696 EXPECT_EQ(stripWhitespace(TBDv3Swift2), stripWhitespace(Buffer.c_str()));697}698 699TEST(TBDv3, Swift_3_0) {700 static const char TBDv3Swift3[] = "--- !tapi-tbd-v3\n"701 "archs: [ arm64 ]\n"702 "platform: ios\n"703 "install-name: Test.dylib\n"704 "swift-abi-version: 3.0\n"705 "...\n";706 707 Expected<TBDFile> Result =708 TextAPIReader::get(MemoryBufferRef(TBDv3Swift3, "Test.tbd"));709 EXPECT_TRUE(!!Result);710 TBDFile File = std::move(Result.get());711 EXPECT_EQ(FileType::TBD_V3, File->getFileType());712 EXPECT_EQ(4U, File->getSwiftABIVersion());713 714 SmallString<4096> Buffer;715 raw_svector_ostream OS(Buffer);716 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);717 EXPECT_TRUE(!WriteResult);718 EXPECT_EQ(stripWhitespace(TBDv3Swift3), stripWhitespace(Buffer.c_str()));719}720 721TEST(TBDv3, Swift_4_0) {722 static const char TBDv3Swift4[] = "--- !tapi-tbd-v3\n"723 "archs: [ arm64 ]\n"724 "platform: ios\n"725 "install-name: Test.dylib\n"726 "swift-abi-version: 4.0\n"727 "...\n";728 729 Expected<TBDFile> Result =730 TextAPIReader::get(MemoryBufferRef(TBDv3Swift4, "Test.tbd"));731 EXPECT_FALSE(!!Result);732 std::string ErrorMessage = toString(Result.takeError());733 EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "734 "version.\nswift-abi-version: 4.0\n ^~~\n",735 ErrorMessage);736}737 738TEST(TBDv3, Swift_5) {739 static const char TBDv3Swift5[] = "--- !tapi-tbd-v3\n"740 "archs: [ arm64 ]\n"741 "platform: ios\n"742 "install-name: Test.dylib\n"743 "swift-abi-version: 5\n"744 "...\n";745 746 Expected<TBDFile> Result =747 TextAPIReader::get(MemoryBufferRef(TBDv3Swift5, "Test.tbd"));748 EXPECT_TRUE(!!Result);749 TBDFile File = std::move(Result.get());750 EXPECT_EQ(FileType::TBD_V3, File->getFileType());751 EXPECT_EQ(5U, File->getSwiftABIVersion());752}753 754TEST(TBDv3, Swift_99) {755 static const char TBDv3Swift99[] = "--- !tapi-tbd-v3\n"756 "archs: [ arm64 ]\n"757 "platform: ios\n"758 "install-name: Test.dylib\n"759 "swift-abi-version: 99\n"760 "...\n";761 762 Expected<TBDFile> Result =763 TextAPIReader::get(MemoryBufferRef(TBDv3Swift99, "Test.tbd"));764 EXPECT_TRUE(!!Result);765 TBDFile File = std::move(Result.get());766 EXPECT_EQ(FileType::TBD_V3, File->getFileType());767 EXPECT_EQ(99U, File->getSwiftABIVersion());768}769 770TEST(TBDv3, UnknownArchitecture) {771 static const char TBDv3FileUnknownArch[] = "--- !tapi-tbd-v3\n"772 "archs: [ foo ]\n"773 "platform: macosx\n"774 "install-name: Test.dylib\n"775 "...\n";776 777 Expected<TBDFile> Result =778 TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownArch, "Test.tbd"));779 EXPECT_TRUE(!!Result);780}781 782TEST(TBDv3, UnknownPlatform) {783 static const char TBDv3FileUnknownPlatform[] = "--- !tapi-tbd-v3\n"784 "archs: [ i386 ]\n"785 "platform: newOS\n"786 "...\n";787 788 Expected<TBDFile> Result =789 TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownPlatform, "Test.tbd"));790 EXPECT_FALSE(!!Result);791 std::string ErrorMessage = toString(Result.takeError());792 EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "793 "newOS\n ^~~~~\n",794 ErrorMessage);795}796 797TEST(TBDv3, MalformedFile1) {798 static const char TBDv3FileMalformed1[] = "--- !tapi-tbd-v3\n"799 "archs: [ arm64 ]\n"800 "foobar: \"Unsupported key\"\n"801 "...\n";802 803 Expected<TBDFile> Result =804 TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed1, "Test.tbd"));805 EXPECT_FALSE(!!Result);806 std::string ErrorMessage = toString(Result.takeError());807 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "808 "'platform'\narchs: [ arm64 ]\n^\n",809 ErrorMessage);810}811 812TEST(TBDv3, MalformedFile2) {813 static const char TBDv3FileMalformed2[] = "--- !tapi-tbd-v3\n"814 "archs: [ arm64 ]\n"815 "platform: ios\n"816 "install-name: Test.dylib\n"817 "foobar: \"Unsupported key\"\n"818 "...\n";819 820 Expected<TBDFile> Result =821 TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed2, "Test.tbd"));822 EXPECT_FALSE(!!Result);823 std::string ErrorMessage = toString(Result.takeError());824 ASSERT_EQ(825 "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: "826 "\"Unsupported key\"\n^~~~~~\n",827 ErrorMessage);828}829 830TEST(TBDv3, InterfaceEquality) {831 static const char TBDv3File[] =832 "--- !tapi-tbd-v3\n"833 "archs: [ armv7, arm64 ]\n"834 "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"835 " 'arm64: 11111111-1111-1111-1111-111111111111']\n"836 "platform: ios\n"837 "flags: [ installapi ]\n"838 "install-name: Test.dylib\n"839 "current-version: 2.3.4\n"840 "compatibility-version: 1.0\n"841 "swift-abi-version: 1.1\n"842 "parent-umbrella: Umbrella.dylib\n"843 "exports:\n"844 " - archs: [ armv7, arm64 ]\n"845 " allowable-clients: [ clientA ]\n"846 " re-exports: [ /usr/lib/libfoo.dylib ]\n"847 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"848 " objc-classes: [ class1, class2 ]\n"849 " objc-eh-types: [ class1 ]\n"850 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"851 " weak-def-symbols: [ _weak1, _weak2 ]\n"852 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"853 " - archs: [ armv7 ]\n"854 " symbols: [ _sym5 ]\n"855 " objc-classes: [ class3 ]\n"856 " objc-ivars: [ class1._ivar3 ]\n"857 " weak-def-symbols: [ _weak3 ]\n"858 " thread-local-symbols: [ _tlv3 ]\n"859 "--- !tapi-tbd-v3\n"860 "archs: [ i386 ]\n"861 "platform: macosx\n"862 "install-name: '/usr/lib/libbar.dylib'\n"863 "current-version: 0\n"864 "compatibility-version: 0\n"865 "swift-abi-version: 5\n"866 "objc-constraint: none\n"867 "exports:\n"868 " - archs: [ i386 ]\n"869 " symbols: [ _sym3, _sym4 ]\n"870 "...\n";871 Expected<TBDFile> ResultA =872 TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd"));873 EXPECT_TRUE(!!ResultA);874 InterfaceFile FileA = std::move(*ResultA.get());875 Expected<TBDFile> ResultB =876 TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd"));877 EXPECT_TRUE(!!ResultB);878 InterfaceFile FileB = std::move(*ResultB.get());879 EXPECT_FALSE(FileA.getPath() == FileB.getPath());880 EXPECT_TRUE(FileA == FileB);881}882 883 884 885TEST(TBDv3, InterfaceInequality) {886 static const char TBDv3File[] = "--- !tapi-tbd-v3\n"887 "archs: [ armv7, arm64 ]\n"888 "platform: ios\n"889 "install-name: Test.dylib\n"890 "...\n";891 892 Expected<TBDFile> ResultA =893 TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd"));894 EXPECT_TRUE(!!ResultA);895 InterfaceFile FileA = std::move(*ResultA.get());896 Expected<TBDFile> ResultB =897 TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd"));898 EXPECT_TRUE(!!ResultB);899 InterfaceFile FileB = std::move(*ResultB.get());900 901 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {902 File->addTarget(Target(AK_x86_64, PLATFORM_IOS));903 }));904 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {905 File->setCurrentVersion(PackedVersion(1, 2, 3));906 File->setCompatibilityVersion(PackedVersion(1, 0, 0));907 }));908 EXPECT_TRUE(checkEqualityOnTransform(909 FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); }));910 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {911 File->setTwoLevelNamespace(false);912 }));913 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {914 File->setApplicationExtensionSafe(false);915 }));916 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {917 File->addParentUmbrella(Target(AK_armv7, PLATFORM_IOS), "Umbrella.dylib");918 }));919 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {920 File->addAllowableClient("ClientA", Target(AK_armv7, PLATFORM_IOS));921 }));922 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {923 File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A",924 Target(AK_armv7, PLATFORM_IOS));925 }));926 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {927 File->addSymbol(EncodeKind::GlobalSymbol, "_symA",928 {Target(AK_arm64, PLATFORM_IOS)});929 }));930 EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {931 InterfaceFile Document;932 Document.setFileType(FileType::TBD_V3);933 Document.addTargets(TargetList{Target(AK_armv7, PLATFORM_IOS),934 Target(AK_arm64, PLATFORM_IOS)});935 Document.setInstallName("/System/Library/Frameworks/A.framework/A");936 File->addDocument(std::make_shared<InterfaceFile>(std::move(Document)));937 }));938}939 940} // namespace TBDv3941