2482 lines · cpp
1//===-- TextStubV5Tests.cpp - TBD V5 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 9#include "TextStubHelpers.h"10#include "llvm/TextAPI/InterfaceFile.h"11#include "llvm/TextAPI/TextAPIReader.h"12#include "llvm/TextAPI/TextAPIWriter.h"13#include "gtest/gtest.h"14#include <string>15#include <vector>16 17using namespace llvm;18using namespace llvm::MachO;19 20namespace TBDv5 {21 22TEST(TBDv5, ReadFile) {23 static const char TBDv5File[] = R"({24"tapi_tbd_version": 5,25"main_library": {26 "target_info": [27 {28 "target": "x86_64-macos",29 "min_deployment": "10.14"30 },31 {32 "target": "arm64-macos",33 "min_deployment": "10.14"34 },35 {36 "target": "arm64-maccatalyst",37 "min_deployment": "12.1"38 }39 ],40 "flags": [41 {42 "targets": [43 "x86_64-macos"44 ],45 "attributes": [46 "flat_namespace"47 ]48 }49 ],50 "install_names": [51 {52 "name": "/S/L/F/Foo.framework/Foo"53 }54 ],55 "current_versions": [56 {57 "version": "1.2"58 }59 ],60 "compatibility_versions": [61 { "version": "1.1" }62 ],63 "rpaths": [64 {65 "targets": [66 "x86_64-macos"67 ],68 "paths": [69 "@executable_path/.../Frameworks"70 ]71 }72 ],73 "parent_umbrellas": [74 {75 "umbrella": "System"76 }77 ],78 "allowable_clients": [79 {80 "clients": [81 "ClientA",82 "ClientB"83 ]84 }85 ],86 "reexported_libraries": [87 {88 "names": [89 "/u/l/l/libfoo.dylib",90 "/u/l/l/libbar.dylib"91 ]92 }93 ],94 "exported_symbols": [95 {96 "targets": [97 "x86_64-macos",98 "arm64-macos"99 ],100 "data": {101 "global": [102 "_global"103 ],104 "objc_class": [105 "ClassA"106 ],107 "weak": [],108 "thread_local": []109 },110 "text": {111 "global": [112 "_func"113 ],114 "weak": [],115 "thread_local": []116 }117 },118 {119 "targets": [120 "x86_64-macos"121 ],122 "data": {123 "global": [124 "_globalVar"125 ],126 "objc_class": [127 "ClassA",128 "ClassB",129 "ClassData"130 ],131 "objc_eh_type": [132 "ClassA",133 "ClassB"134 ],135 "objc_ivar": [136 "ClassA.ivar1",137 "ClassA.ivar2",138 "ClassC.ivar1"139 ]140 },141 "text": {142 "global": [143 "_funcFoo"144 ]145 }146 }147 ],148 "reexported_symbols": [149 {150 "targets": [151 "x86_64-macos",152 "arm64-macos"153 ],154 "data": {155 "global": [156 "_globalRe"157 ],158 "objc_class": [159 "ClassRexport"160 ]161 },162 "text": {163 "global": [164 "_funcA"165 ]166 }167 }168 ],169 "undefined_symbols": [170 {171 "targets": [172 "x86_64-macos"173 ],174 "data": {175 "global": [176 "_globalBind"177 ],178 "weak": [179 "referenced_sym"180 ]181 }182 }183 ]184},185"libraries": []186})";187 188 MemoryBufferRef InputBuf = MemoryBufferRef(TBDv5File, "Test.tbd");189 Expected<FileType> ExpectedFT = TextAPIReader::canRead(InputBuf);190 EXPECT_TRUE(!!ExpectedFT);191 192 Expected<TBDFile> Result = TextAPIReader::get(InputBuf);193 EXPECT_TRUE(!!Result);194 TBDFile File = std::move(Result.get());195 EXPECT_EQ(FileType::TBD_V5, File->getFileType());196 EXPECT_EQ(*ExpectedFT, File->getFileType());197 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());198 199 TargetList AllTargets = {200 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),201 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),202 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),203 };204 std::set<Target> FileTargets{File->targets().begin(), File->targets().end()};205 EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());206 EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());207 EXPECT_EQ(FileTargets.size(), AllTargets.size());208 for (const auto &Targ : AllTargets) {209 auto FileTarg = FileTargets.find(Targ);210 EXPECT_FALSE(FileTarg == FileTargets.end());211 EXPECT_EQ(*FileTarg, Targ);212 PackedVersion MD = Targ.MinDeployment;213 PackedVersion FileMD = FileTarg->MinDeployment;214 EXPECT_EQ(MD, FileMD);215 }216 217 EXPECT_EQ(PackedVersion(1, 2, 0), File->getCurrentVersion());218 EXPECT_EQ(PackedVersion(1, 1, 0), File->getCompatibilityVersion());219 EXPECT_TRUE(File->isApplicationExtensionSafe());220 EXPECT_FALSE(File->isTwoLevelNamespace());221 EXPECT_FALSE(File->isOSLibNotForSharedCache());222 EXPECT_EQ(0U, File->documents().size());223 224 InterfaceFileRef ClientA("ClientA", AllTargets);225 InterfaceFileRef ClientB("ClientB", AllTargets);226 EXPECT_EQ(2U, File->allowableClients().size());227 EXPECT_EQ(ClientA, File->allowableClients().at(0));228 EXPECT_EQ(ClientB, File->allowableClients().at(1));229 230 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);231 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);232 EXPECT_EQ(2U, File->reexportedLibraries().size());233 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));234 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));235 236 TargetToAttr RPaths = {237 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},238 };239 EXPECT_EQ(RPaths, File->rpaths());240 241 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},242 {Target(AK_arm64, PLATFORM_MACOS), "System"},243 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};244 EXPECT_EQ(Umbrellas, File->umbrellas());245 246 ExportedSymbolSeq Exports, Reexports, Undefineds;247 for (const auto *Sym : File->symbols()) {248 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};249 ExportedSymbol Temp =250 ExportedSymbol{Sym->getKind(),251 std::string(Sym->getName()),252 Sym->isWeakDefined() || Sym->isWeakReferenced(),253 Sym->isThreadLocalValue(),254 Sym->isData(),255 SymTargets};256 if (Sym->isUndefined())257 Undefineds.emplace_back(std::move(Temp));258 else259 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))260 : Exports.emplace_back(std::move(Temp));261 }262 llvm::sort(Exports);263 llvm::sort(Reexports);264 llvm::sort(Undefineds);265 266 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),267 Target(AK_arm64, PLATFORM_MACOS)};268 269 std::vector<ExportedSymbol> ExpectedExportedSymbols = {270 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},271 {EncodeKind::GlobalSymbol,272 "_funcFoo",273 false,274 false,275 false,276 {Target(AK_x86_64, PLATFORM_MACOS)}},277 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},278 {EncodeKind::GlobalSymbol,279 "_globalVar",280 false,281 false,282 true,283 {Target(AK_x86_64, PLATFORM_MACOS)}},284 {EncodeKind::ObjectiveCClass,285 "ClassA",286 false,287 false,288 true,289 {Target(AK_x86_64, PLATFORM_MACOS)}},290 {EncodeKind::ObjectiveCClass,291 "ClassB",292 false,293 false,294 true,295 {Target(AK_x86_64, PLATFORM_MACOS)}},296 {EncodeKind::ObjectiveCClass,297 "ClassData",298 false,299 false,300 true,301 {Target(AK_x86_64, PLATFORM_MACOS)}},302 {EncodeKind::ObjectiveCClassEHType,303 "ClassA",304 false,305 false,306 true,307 {Target(AK_x86_64, PLATFORM_MACOS)}},308 {EncodeKind::ObjectiveCClassEHType,309 "ClassB",310 false,311 false,312 true,313 {Target(AK_x86_64, PLATFORM_MACOS)}},314 {EncodeKind::ObjectiveCInstanceVariable,315 "ClassA.ivar1",316 false,317 false,318 true,319 {Target(AK_x86_64, PLATFORM_MACOS)}},320 {EncodeKind::ObjectiveCInstanceVariable,321 "ClassA.ivar2",322 false,323 false,324 true,325 {Target(AK_x86_64, PLATFORM_MACOS)}},326 {EncodeKind::ObjectiveCInstanceVariable,327 "ClassC.ivar1",328 false,329 false,330 true,331 {Target(AK_x86_64, PLATFORM_MACOS)}},332 };333 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {334 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},335 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},336 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,337 MacOSTargets},338 };339 340 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {341 {EncodeKind::GlobalSymbol,342 "_globalBind",343 false,344 false,345 true,346 {Target(AK_x86_64, PLATFORM_MACOS)}},347 {EncodeKind::GlobalSymbol,348 "referenced_sym",349 true,350 false,351 true,352 {Target(AK_x86_64, PLATFORM_MACOS)}},353 };354 355 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());356 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());357 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());358 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),359 std::begin(ExpectedExportedSymbols)));360 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),361 std::begin(ExpectedReexportedSymbols)));362 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),363 std::begin(ExpectedUndefinedSymbols)));364 365 EXPECT_TRUE(366 File->getSymbol(EncodeKind::GlobalSymbol, "_globalBind").has_value());367}368 369TEST(TBDv5, ReadMultipleTargets) {370 static const char TBDv5File[] = R"({ 371"tapi_tbd_version": 5,372"main_library": {373 "target_info": [374 {375 "target": "x86_64-macos",376 "min_deployment": "10.14" 377 },378 {379 "target": "arm64-macos",380 "min_deployment": "10.14"381 },382 {383 "target": "arm64-maccatalyst",384 "min_deployment": "12.1"385 }386 ],387 "install_names":[388 { "name":"/usr/lib/libFoo.dylib" }389 ],390 "swift_abi":[ { "abi":8 } ],391 "reexported_libraries": [392 {393 "targets": [ "x86_64-maccatalyst" ],394 "names": [395 "/u/l/l/libfoo.dylib",396 "/u/l/l/libbar.dylib"397 ]398 },399 {400 "targets": [ "arm64-maccatalyst" ],401 "names": [ "/u/l/l/libArmOnly.dylib" ]402 }403 ]404}405})";406 407 Expected<TBDFile> Result =408 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));409 EXPECT_TRUE(!!Result);410 TBDFile File = std::move(Result.get());411 EXPECT_EQ(FileType::TBD_V5, File->getFileType());412 EXPECT_EQ(std::string("/usr/lib/libFoo.dylib"), File->getInstallName());413 EXPECT_TRUE(File->isApplicationExtensionSafe());414 EXPECT_TRUE(File->isTwoLevelNamespace());415 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());416 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());417 EXPECT_EQ(8U, File->getSwiftABIVersion());418 419 TargetList AllTargets = {420 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),421 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),422 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),423 };424 EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());425 EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());426 427 InterfaceFileRef ReexportA("/u/l/l/libArmOnly.dylib",428 {Target(AK_arm64, PLATFORM_MACCATALYST)});429 InterfaceFileRef ReexportB("/u/l/l/libbar.dylib",430 {Target(AK_x86_64, PLATFORM_MACCATALYST)});431 InterfaceFileRef ReexportC("/u/l/l/libfoo.dylib",432 {Target(AK_x86_64, PLATFORM_MACCATALYST)});433 EXPECT_EQ(3U, File->reexportedLibraries().size());434 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));435 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));436 EXPECT_EQ(ReexportC, File->reexportedLibraries().at(2));437}438 439TEST(TBDv5, ReadMultipleDocuments) {440 static const char TBDv5File[] = R"({ 441"tapi_tbd_version": 5,442"main_library": {443 "target_info": [444 {445 "target": "armv7-ios",446 "min_deployment": "11.0" 447 }448 ],449 "install_names":[450 { "name":"/S/L/F/Foo.framework/Foo" }451 ],452 "reexported_libraries": [453 { "names": ["/u/l/l/libfoo.dylib"] }454 ]455},456"libraries": [457 {458 "target_info": [459 {460 "target": "armv7-ios",461 "min_deployment": "11.0" 462 }463 ],464 "install_names":[465 { "name":"/u/l/l/libfoo.dylib" }466 ],467 "flags":[ 468 { "attributes": ["not_app_extension_safe"] }469 ], 470 "exported_symbols": [471 {472 "data": {473 "thread_local": [ "_globalVar" ],474 "objc_class": [ "ClassData", "ClassA", "ClassB"], 475 "objc_eh_type": [ "ClassA", "ClassB" ]476 },477 "text": {478 "global": [ "_funcFoo" ]479 }480 }481 ]482 }483]})";484 485 Expected<TBDFile> Result =486 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));487 EXPECT_TRUE(!!Result);488 TBDFile File = std::move(Result.get());489 EXPECT_EQ(FileType::TBD_V5, File->getFileType());490 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());491 EXPECT_TRUE(File->isTwoLevelNamespace());492 EXPECT_TRUE(File->isApplicationExtensionSafe());493 494 TargetList Targets(File->targets().begin(), File->targets().end());495 Target iOSTarget(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0));496 EXPECT_EQ(TargetList{iOSTarget}, Targets);497 std::vector<const Symbol *> Symbols(File->symbols().begin(),498 File->symbols().end());499 EXPECT_EQ(0U, Symbols.size());500 501 InterfaceFileRef Reexport("/u/l/l/libfoo.dylib", {iOSTarget});502 EXPECT_EQ(1U, File->reexportedLibraries().size());503 EXPECT_EQ(Reexport, File->reexportedLibraries().at(0));504 505 // Check inlined library.506 EXPECT_EQ(1U, File->documents().size());507 TBDReexportFile Document = File->documents().front();508 Targets = {Document->targets().begin(), Document->targets().end()};509 EXPECT_EQ(TargetList{iOSTarget}, Targets);510 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());511 EXPECT_EQ(0U, Document->getSwiftABIVersion());512 EXPECT_TRUE(Document->isTwoLevelNamespace());513 EXPECT_FALSE(Document->isApplicationExtensionSafe());514 515 ExportedSymbolSeq Exports;516 for (const auto *Sym : Document->symbols())517 Exports.emplace_back(518 ExportedSymbol{Sym->getKind(),519 std::string(Sym->getName()),520 Sym->isWeakDefined() || Sym->isWeakReferenced(),521 Sym->isThreadLocalValue(),522 Sym->isData(),523 {iOSTarget}});524 525 llvm::sort(Exports);526 ExportedSymbolSeq ExpectedExports = {527 {EncodeKind::GlobalSymbol, "_funcFoo", false, false, false, {iOSTarget}},528 {EncodeKind::GlobalSymbol, "_globalVar", false, true, true, {iOSTarget}},529 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, {iOSTarget}},530 {EncodeKind::ObjectiveCClass, "ClassB", false, false, true, {iOSTarget}},531 {EncodeKind::ObjectiveCClass,532 "ClassData",533 false,534 false,535 true,536 {iOSTarget}},537 {EncodeKind::ObjectiveCClassEHType,538 "ClassA",539 false,540 false,541 true,542 {iOSTarget}},543 {EncodeKind::ObjectiveCClassEHType,544 "ClassB",545 false,546 false,547 true,548 {iOSTarget}},549 };550 551 EXPECT_EQ(ExpectedExports.size(), Exports.size());552 EXPECT_TRUE(553 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));554}555 556TEST(TBDv5, WriteFile) {557 static const char TBDv5File[] = R"({558"tapi_tbd_version": 5,559"main_library": {560 "target_info": [561 {562 "target": "x86_64-macos",563 "min_deployment": "10.14"564 },565 {566 "target": "arm64-macos",567 "min_deployment": "10.14"568 },569 {570 "target": "arm64-maccatalyst",571 "min_deployment": "12.1"572 }573 ],574 "install_names": [575 {576 "name": "@rpath/S/L/F/Foo.framework/Foo"577 }578 ],579 "current_versions": [580 {581 "version": "1.2"582 }583 ],584 "compatibility_versions": [585 { "version": "1.1" }586 ],587 "flags": [588 {589 "attributes": [590 "flat_namespace"591 ]592 }593 ],594 "rpaths": [595 {596 "targets": [597 "x86_64-macos"598 ],599 "paths": [600 "@executable_path/.../Frameworks"601 ]602 }603 ],604 "parent_umbrellas": [605 {606 "umbrella": "System"607 }608 ],609 "allowable_clients": [610 {611 "clients": [612 "ClientA",613 "ClientB"614 ]615 }616 ],617 "reexported_libraries": [618 {619 "names": [620 "/u/l/l/libfoo.dylib",621 "/u/l/l/libbar.dylib"622 ]623 }624 ],625 "exported_symbols": [626 {627 "targets": [628 "x86_64-macos",629 "arm64-macos"630 ],631 "data": {632 "global": [633 "_global"634 ],635 "objc_class": [636 "ClassA"637 ],638 "weak": [],639 "thread_local": []640 },641 "text": {642 "global": [643 "_func"644 ],645 "weak": [],646 "thread_local": []647 }648 },649 {650 "targets": [651 "x86_64-macos"652 ],653 "data": {654 "global": [655 "_globalVar"656 ],657 "objc_class": [658 "ClassA",659 "ClassB",660 "ClassData"661 ],662 "objc_eh_type": [663 "ClassA",664 "ClassB"665 ],666 "objc_ivar": [667 "ClassA.ivar1",668 "ClassA.ivar2",669 "ClassC.ivar1"670 ]671 },672 "text": {673 "global": [674 "_funcFoo"675 ]676 }677 }678 ],679 "reexported_symbols": [680 {681 "data": {682 "global": [683 "_globalRe"684 ],685 "objc_class": [686 "ClassRexport"687 ]688 },689 "text": {690 "global": [691 "_funcA"692 ]693 }694 }695 ],696 "undefined_symbols": [697 {698 "targets": [699 "x86_64-macos"700 ],701 "data": {702 "global": [703 "_globalBind"704 ],705 "weak": [706 "referenced_sym"707 ]708 }709 }710 ]711}})";712 713 InterfaceFile File;714 File.setFileType(FileType::TBD_V5);715 716 TargetList AllTargets = {717 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),718 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),719 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),720 };721 File.addTargets(AllTargets);722 File.setInstallName("@rpath/S/L/F/Foo.framework/Foo");723 File.setCurrentVersion(PackedVersion(1, 2, 0));724 File.setCompatibilityVersion(PackedVersion(1, 1, 0));725 File.addRPath("@executable_path/.../Frameworks", AllTargets[0]);726 727 for (const auto &Targ : AllTargets) {728 File.addParentUmbrella(Targ, "System");729 File.addAllowableClient("ClientA", Targ);730 File.addAllowableClient("ClientB", Targ);731 File.addReexportedLibrary("/u/l/l/libfoo.dylib", Targ);732 File.addReexportedLibrary("/u/l/l/libbar.dylib", Targ);733 }734 735 SymbolFlags Flags = SymbolFlags::None;736 // Exports.737 File.addSymbol(EncodeKind::GlobalSymbol, "_global",738 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);739 File.addSymbol(EncodeKind::GlobalSymbol, "_func",740 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Text);741 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassA",742 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);743 File.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", {AllTargets[0]},744 Flags | SymbolFlags::Text);745 File.addSymbol(EncodeKind::GlobalSymbol, "_globalVar", {AllTargets[0]},746 Flags | SymbolFlags::Data);747 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassData", {AllTargets[0]},748 Flags | SymbolFlags::Data);749 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassA", {AllTargets[0]},750 Flags | SymbolFlags::Data);751 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassB", {AllTargets[0]},752 Flags | SymbolFlags::Data);753 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar1",754 {AllTargets[0]}, Flags | SymbolFlags::Data);755 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar2",756 {AllTargets[0]}, Flags | SymbolFlags::Data);757 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassC.ivar1",758 {AllTargets[0]}, Flags | SymbolFlags::Data);759 760 // Reexports.761 Flags = SymbolFlags::Rexported;762 File.addSymbol(EncodeKind::GlobalSymbol, "_globalRe", AllTargets,763 Flags | SymbolFlags::Data);764 File.addSymbol(EncodeKind::GlobalSymbol, "_funcA", AllTargets,765 Flags | SymbolFlags::Text);766 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassRexport", AllTargets,767 Flags | SymbolFlags::Data);768 769 // Undefineds.770 Flags = SymbolFlags::Undefined;771 File.addSymbol(EncodeKind::GlobalSymbol, "_globalBind", {AllTargets[0]},772 Flags | SymbolFlags::Data);773 File.addSymbol(EncodeKind::GlobalSymbol, "referenced_sym", {AllTargets[0]},774 Flags | SymbolFlags::Data | SymbolFlags::WeakReferenced);775 776 File.setTwoLevelNamespace(false);777 File.setApplicationExtensionSafe(true);778 779 // Write out file then process it back into IF and compare equality780 // against TBDv5File.781 SmallString<4096> Buffer;782 raw_svector_ostream OS(Buffer);783 Error Result = TextAPIWriter::writeToStream(OS, File);784 EXPECT_FALSE(Result);785 786 Expected<TBDFile> Input =787 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));788 EXPECT_TRUE(!!Input);789 TBDFile InputFile = std::move(Input.get());790 791 Expected<TBDFile> Output =792 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));793 EXPECT_TRUE(!!Output);794 TBDFile OutputFile = std::move(Output.get());795 EXPECT_EQ(*InputFile, *OutputFile);796}797 798TEST(TBDv5, WriteMultipleDocuments) {799 static const char TBDv5File[] = R"({ 800"tapi_tbd_version": 5,801"main_library": {802 "target_info": [803 {804 "target": "armv7-ios",805 "min_deployment": "11.0" 806 }807 ],808 "install_names":[809 { "name":"/S/L/F/Foo.framework/Foo" }810 ],811 "reexported_libraries": [812 { "names": ["/u/l/l/libfoo.dylib"] 813 }814 ]815},816"libraries": [817 {818 "target_info": [819 {820 "target": "armv7-ios",821 "min_deployment": "11.0" 822 },823 {824 "target": "armv7s-ios",825 "min_deployment": "11.0" 826 }827 ],828 "install_names":[829 { "name":"/u/l/l/libfoo.dylib" }830 ],831 "current_versions": [832 {833 "version": "2.1.1"834 }835 ],836 "rpaths": [837 {838 "targets": [839 "armv7-ios"840 ],841 "paths": [842 "@executable_path/.../Frameworks"843 ]844 }],845 "reexported_libraries": [ { "names": ["@rpath/libfoo.dylib"] } ],846 "flags":[ 847 { "attributes": ["not_app_extension_safe"] }848 ], 849 "exported_symbols": [850 {851 "text": {852 "global": [ "_funcFoo" ]853 }854 }855 ]856 },857 {858 "target_info": [859 {860 "target": "armv7-ios",861 "min_deployment": "11.0" 862 }863 ],864 "install_names":[865 { "name":"@rpath/libfoo.dylib" }866 ],867 "exported_symbols": [868 {869 "data": {870 "global": [ "_varFooBaz" ]871 }872 }873 ]874 }875]})";876 877 InterfaceFile File;878 File.setFileType(FileType::TBD_V5);879 880 TargetList AllTargets = {881 Target(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0)),882 Target(AK_armv7s, PLATFORM_IOS, VersionTuple(11, 0)),883 };884 File.setInstallName("/S/L/F/Foo.framework/Foo");885 File.addTarget(AllTargets[0]);886 File.setCurrentVersion(PackedVersion(1, 0, 0));887 File.setCompatibilityVersion(PackedVersion(1, 0, 0));888 File.addReexportedLibrary("/u/l/l/libfoo.dylib", AllTargets[0]);889 File.setTwoLevelNamespace();890 File.setApplicationExtensionSafe(true);891 892 InterfaceFile NestedFile;893 NestedFile.setFileType(FileType::TBD_V5);894 NestedFile.setInstallName("/u/l/l/libfoo.dylib");895 NestedFile.addTargets(AllTargets);896 NestedFile.setCompatibilityVersion(PackedVersion(1, 0, 0));897 NestedFile.setTwoLevelNamespace();898 NestedFile.setApplicationExtensionSafe(false);899 NestedFile.setCurrentVersion(PackedVersion(2, 1, 1));900 NestedFile.addRPath("@executable_path/.../Frameworks", AllTargets[0]);901 for (const auto &Targ : AllTargets)902 NestedFile.addReexportedLibrary("@rpath/libfoo.dylib", Targ);903 NestedFile.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", AllTargets,904 SymbolFlags::Text);905 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFile)));906 907 InterfaceFile NestedFileB;908 NestedFileB.setFileType(FileType::TBD_V5);909 NestedFileB.setInstallName("@rpath/libfoo.dylib");910 NestedFileB.addTarget(AllTargets[0]);911 NestedFileB.setCompatibilityVersion(PackedVersion(1, 0, 0));912 NestedFileB.setCurrentVersion(PackedVersion(1, 0, 0));913 NestedFileB.setTwoLevelNamespace();914 NestedFileB.setApplicationExtensionSafe(true);915 NestedFileB.addSymbol(EncodeKind::GlobalSymbol, "_varFooBaz", {AllTargets[0]},916 SymbolFlags::Data);917 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFileB)));918 919 // Write out file then process it back into IF and compare equality920 // against TBDv5File.921 SmallString<4096> Buffer;922 raw_svector_ostream OS(Buffer);923 Error Result = TextAPIWriter::writeToStream(OS, File, FileType::Invalid,924 /*Compact=*/true);925 EXPECT_FALSE(Result);926 927 Expected<TBDFile> Input =928 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));929 EXPECT_TRUE(!!Input);930 TBDFile InputFile = std::move(Input.get());931 932 Expected<TBDFile> Output =933 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));934 EXPECT_TRUE(!!Output);935 TBDFile OutputFile = std::move(Output.get());936 EXPECT_EQ(*InputFile, *OutputFile);937}938 939TEST(TBDv5, Target_Simulator) {940 static const char TBDv5File[] = R"({ 941"tapi_tbd_version": 5,942"main_library": {943 "target_info": [944 {945 "target": "arm64-ios-simulator",946 "min_deployment": "11.0"947 },948 {949 "target": "x86_64-ios-simulator",950 "min_deployment": "11.3" 951 }952 ],953 "install_names":[954 { "name":"/S/L/F/Foo.framework/Foo" }955 ]956}})";957 958 Expected<TBDFile> Result =959 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));960 EXPECT_TRUE(!!Result);961 TBDFile File = std::move(Result.get());962 EXPECT_EQ(FileType::TBD_V5, File->getFileType());963 TargetList ExpectedTargets = {964 Target(AK_x86_64, PLATFORM_IOSSIMULATOR, VersionTuple(11, 3)),965 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0)),966 };967 TargetList Targets{File->targets().begin(), File->targets().end()};968 llvm::sort(Targets);969 EXPECT_EQ(Targets, ExpectedTargets);970 971 SmallString<4096> Buffer;972 raw_svector_ostream OS(Buffer);973 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);974 EXPECT_TRUE(!WriteResult);975 976 Expected<TBDFile> Output =977 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));978 EXPECT_TRUE(!!Output);979 TBDFile WriteResultFile = std::move(Output.get());980 EXPECT_EQ(*File, *WriteResultFile);981}982 983TEST(TBDv5, Target_UnsupportedMinOS) {984 static const char TBDv5File[] = R"({ 985"tapi_tbd_version": 5,986"main_library": {987 "target_info": [988 {989 "target": "arm64-macos",990 "min_deployment": "10.14"991 },992 {993 "target": "x86_64-macos",994 "min_deployment": "10.14" 995 }996 ],997 "install_names":[998 { "name":"/S/L/F/Foo.framework/Foo" }999 ]1000}})";1001 1002 Expected<TBDFile> Result =1003 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1004 EXPECT_TRUE(!!Result);1005 TBDFile File = std::move(Result.get());1006 EXPECT_EQ(FileType::TBD_V5, File->getFileType());1007 TargetList ExpectedTargets = {1008 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),1009 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0)),1010 };1011 TargetList Targets{File->targets().begin(), File->targets().end()};1012 llvm::sort(Targets);1013 EXPECT_EQ(Targets, ExpectedTargets);1014 1015 SmallString<4096> Buffer;1016 raw_svector_ostream OS(Buffer);1017 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);1018 EXPECT_TRUE(!WriteResult);1019 1020 Expected<TBDFile> Output =1021 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));1022 EXPECT_TRUE(!!Output);1023 TBDFile WriteResultFile = std::move(Output.get());1024 EXPECT_EQ(*File, *WriteResultFile);1025}1026 1027TEST(TBDv5, MisspelledKey) {1028 static const char TBDv5File[] = R"({ 1029"tapi_tbd_version": 5,1030"main_library": {1031 "target_info": [1032 {1033 "target": "arm64-ios-simulator",1034 "min_deployment": "11.0"1035 }1036 ],1037 "intall_names":[1038 { "name":"/S/L/F/Foo.framework/Foo" }1039 ]1040}})";1041 1042 Expected<TBDFile> Result =1043 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1044 EXPECT_FALSE(!!Result);1045 std::string ErrorMessage = toString(Result.takeError());1046 EXPECT_EQ("invalid install_names section\n", ErrorMessage);1047}1048 1049TEST(TBDv5, InvalidVersion) {1050 static const char TBDv5File[] = R"({ 1051"tapi_tbd_version": 11,1052"main_library": {1053 "target_info": [1054 {1055 "target": "arm64-ios-simulator",1056 "min_deployment": "11.0"1057 }1058 ],1059 "install_names":[1060 { "name":"/S/L/F/Foo.framework/Foo" }1061 ]1062}})";1063 1064 Expected<TBDFile> Result =1065 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1066 EXPECT_FALSE(!!Result);1067 std::string ErrorMessage = toString(Result.takeError());1068 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);1069}1070 1071TEST(TBDv5, MissingRequiredKey) {1072 static const char TBDv5File[] = R"({ 1073"main_library": {1074 "target_info": [1075 {1076 "target": "arm64-ios-simulator",1077 "min_deployment": "11.0"1078 }1079 ],1080 "install_names":[1081 { "name":"/S/L/F/Foo.framework/Foo" }1082 ]1083}})";1084 1085 Expected<TBDFile> Result =1086 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1087 EXPECT_FALSE(!!Result);1088 std::string ErrorMessage = toString(Result.takeError());1089 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);1090}1091 1092TEST(TBDv5, InvalidSymbols) {1093 static const char TBDv5File[] = R"({ 1094"tapi_tbd_version": 5,1095"main_library": {1096 "target_info": [1097 {1098 "target": "arm64-driverkit",1099 "min_deployment": "11.0"1100 }1101 ],1102 "install_names":[1103 { "name":"/S/L/F/Foo.framework/Foo" }1104 ],1105 "exported_symbols": [1106 {1107 "daa": {1108 "global": {1109 "weak": []1110 }1111 }1112 }1113 ]1114}})";1115 1116 Expected<TBDFile> Result =1117 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1118 EXPECT_FALSE(!!Result);1119 std::string ErrorMessage = toString(Result.takeError());1120 EXPECT_EQ("invalid exported_symbols section\n", ErrorMessage);1121}1122 1123TEST(TBDv5, DefaultMinOS) {1124 static const char TBDv5File[] = R"({ 1125"tapi_tbd_version": 5,1126"main_library": {1127 "target_info": [1128 {1129 "target": "arm64-ios-simulator"1130 }1131 ],1132 "install_names":[1133 { "name":"/S/L/F/Foo.framework/Foo" }1134 ]1135}})";1136 1137 Expected<TBDFile> Result =1138 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1139 EXPECT_TRUE(!!Result);1140 TBDFile File = std::move(Result.get());1141 EXPECT_EQ(FileType::TBD_V5, File->getFileType());1142 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());1143 EXPECT_TRUE(File->targets().begin() != File->targets().end());1144 EXPECT_EQ(*File->targets().begin(),1145 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(0, 0)));1146}1147 1148TEST(TBDv5, InvalidMinOS) {1149 static const char TBDv5File[] = R"({ 1150"tapi_tbd_version": 5,1151"main_library": {1152 "target_info": [1153 {1154 "target": "arm64-ios-simulator",1155 "min_deployment": "swift-abi"1156 }1157 ],1158 "install_names":[1159 { "name":"/S/L/F/Foo.framework/Foo" }1160 ]1161}})";1162 1163 Expected<TBDFile> Result =1164 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1165 EXPECT_FALSE(!!Result);1166 std::string ErrorMessage = toString(Result.takeError());1167 EXPECT_EQ("invalid min_deployment section\n", ErrorMessage);1168}1169 1170TEST(TBDv5, RISCV) {1171 static const char TBDv5File[] = R"({ 1172"tapi_tbd_version": 5,1173"main_library": {1174 "target_info": [1175 {1176 "target": "riscv32-ios",1177 "min_deployment": "34.1" 1178 }1179 ],1180 "install_names":[1181 { "name":"/S/L/F/Foo.framework/Foo" }1182 ]1183}})";1184 1185 Expected<TBDFile> Result =1186 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1187 EXPECT_TRUE(!!Result);1188 Target ExpectedTarget = Target(AK_riscv32, PLATFORM_IOS, VersionTuple(34, 1));1189 TBDFile ReadFile = std::move(Result.get());1190 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());1191 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1192 ReadFile->getInstallName());1193 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());1194 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);1195}1196 1197TEST(TBDv5, SimSupport) {1198 static const char TBDv5File[] = R"({ 1199"tapi_tbd_version": 5,1200"main_library": {1201 "target_info": [1202 {1203 "target": "arm64-macos",1204 "min_deployment": "11.1" 1205 }1206 ],1207 "install_names":[1208 { "name":"/S/L/F/Foo.framework/Foo" }1209 ],1210 "flags":[ 1211 { "attributes": ["sim_support"] }1212 ] 1213}})";1214 1215 Expected<TBDFile> Result =1216 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1217 EXPECT_TRUE(!!Result);1218 Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));1219 TBDFile ReadFile = std::move(Result.get());1220 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());1221 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1222 ReadFile->getInstallName());1223 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());1224 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);1225 EXPECT_TRUE(ReadFile->hasSimulatorSupport());1226}1227 1228TEST(TBDv5, NotForSharedCache) {1229 static const char TBDv5File[] = R"({ 1230"tapi_tbd_version": 5,1231"main_library": {1232 "target_info": [1233 {1234 "target": "arm64-macos",1235 "min_deployment": "11.1" 1236 }1237 ],1238 "install_names":[1239 { "name":"/S/L/F/Foo.framework/Foo" }1240 ],1241 "flags":[ 1242 { "attributes": ["not_for_dyld_shared_cache"] }1243 ] 1244}})";1245 1246 Expected<TBDFile> Result =1247 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1248 EXPECT_TRUE(!!Result);1249 Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));1250 TBDFile ReadFile = std::move(Result.get());1251 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());1252 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1253 ReadFile->getInstallName());1254 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());1255 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);1256 EXPECT_FALSE(ReadFile->hasSimulatorSupport());1257 EXPECT_TRUE(ReadFile->isOSLibNotForSharedCache());1258}1259 1260TEST(TBDv5, ObjCInterfaces) {1261 static const char TBDv5File[] = R"({ 1262"tapi_tbd_version": 5,1263"main_library": {1264 "target_info": [1265 {1266 "target": "arm64-ios-simulator",1267 "min_deployment": "14.0"1268 }1269 ],1270 "install_names":[1271 { "name":"/S/L/F/Foo.framework/Foo" }1272 ],1273 "exported_symbols": [1274 {1275 "data": {1276 "global": [1277 "_global",1278 "_OBJC_METACLASS_$_Standalone",1279 "_OBJC_CLASS_$_Standalone2"1280 ],1281 "weak": ["_OBJC_EHTYPE_$_NSObject"],1282 "objc_class": [1283 "ClassA",1284 "ClassB"1285 ],1286 "objc_eh_type": ["ClassA"]1287 }1288 }]1289}})";1290 1291 Expected<TBDFile> Result =1292 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1293 EXPECT_TRUE(!!Result);1294 TBDFile File = std::move(Result.get());1295 EXPECT_EQ(FileType::TBD_V5, File->getFileType());1296 Target ExpectedTarget =1297 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0));1298 EXPECT_EQ(*File->targets().begin(), ExpectedTarget);1299 1300 // Check Symbols.1301 ExportedSymbolSeq Exports;1302 for (const auto *Sym : File->symbols()) {1303 ExportedSymbol Temp =1304 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),1305 Sym->isWeakDefined() || Sym->isWeakReferenced(),1306 Sym->isThreadLocalValue(), Sym->isData()};1307 Exports.emplace_back(std::move(Temp));1308 }1309 llvm::sort(Exports);1310 1311 std::vector<ExportedSymbol> ExpectedExports = {1312 {EncodeKind::GlobalSymbol, "_OBJC_CLASS_$_Standalone2", false, false,1313 true},1314 {EncodeKind::GlobalSymbol, "_OBJC_EHTYPE_$_NSObject", true, false, true},1315 {EncodeKind::GlobalSymbol, "_OBJC_METACLASS_$_Standalone", false, false,1316 true},1317 {EncodeKind::GlobalSymbol, "_global", false, false, true},1318 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true},1319 {EncodeKind::ObjectiveCClass, "ClassB", false, false, true},1320 {EncodeKind::ObjectiveCClassEHType, "ClassA", false, false, true}};1321 1322 EXPECT_EQ(ExpectedExports.size(), Exports.size());1323 EXPECT_TRUE(1324 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));1325 1326 SmallString<4096> Buffer;1327 raw_svector_ostream OS(Buffer);1328 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);1329 EXPECT_TRUE(!WriteResult);1330 1331 Expected<TBDFile> Output =1332 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));1333 EXPECT_TRUE(!!Output);1334 TBDFile WriteResultFile = std::move(Output.get());1335 EXPECT_EQ(*File, *WriteResultFile);1336}1337 1338TEST(TBDv5, MergeIF) {1339 static const char TBDv5FileA[] = R"({1340"tapi_tbd_version": 5,1341"main_library": {1342 "target_info": [1343 {1344 "target": "x86_64-macos",1345 "min_deployment": "10.14"1346 },1347 {1348 "target": "arm64-macos",1349 "min_deployment": "10.14"1350 },1351 {1352 "target": "arm64-maccatalyst",1353 "min_deployment": "12.1"1354 }1355 ],1356 "flags": [1357 {1358 "targets": [1359 "x86_64-macos"1360 ],1361 "attributes": [1362 "flat_namespace"1363 ]1364 }1365 ],1366 "install_names": [1367 {1368 "name": "/S/L/F/Foo.framework/Foo"1369 }1370 ],1371 "current_versions": [1372 {1373 "version": "1.2"1374 }1375 ],1376 "compatibility_versions": [1377 { "version": "1.1" }1378 ],1379 "rpaths": [1380 {1381 "targets": [1382 "x86_64-macos"1383 ],1384 "paths": [1385 "@executable_path/.../Frameworks"1386 ]1387 }1388 ],1389 "parent_umbrellas": [1390 {1391 "umbrella": "System"1392 }1393 ],1394 "allowable_clients": [1395 {1396 "clients": [1397 "ClientA",1398 "ClientB"1399 ]1400 }1401 ],1402 "reexported_libraries": [1403 {1404 "names": [1405 "/u/l/l/libfoo.dylib",1406 "/u/l/l/libbar.dylib"1407 ]1408 }1409 ],1410 "exported_symbols": [1411 {1412 "targets": [1413 "x86_64-macos",1414 "arm64-macos"1415 ],1416 "data": {1417 "global": [1418 "_global"1419 ],1420 "objc_class": [1421 "ClassA"1422 ],1423 "weak": [],1424 "thread_local": []1425 },1426 "text": {1427 "global": [1428 "_func"1429 ],1430 "weak": [],1431 "thread_local": []1432 }1433 },1434 {1435 "targets": [1436 "x86_64-macos"1437 ],1438 "data": {1439 "global": [1440 "_globalVar"1441 ],1442 "objc_class": [1443 "ClassA",1444 "ClassB",1445 "ClassData"1446 ],1447 "objc_eh_type": [1448 "ClassA",1449 "ClassB"1450 ],1451 "objc_ivar": [1452 "ClassA.ivar1",1453 "ClassA.ivar2",1454 "ClassC.ivar1"1455 ]1456 },1457 "text": {1458 "global": [1459 "_funcFoo"1460 ]1461 }1462 }1463 ],1464 "reexported_symbols": [1465 {1466 "targets": [1467 "x86_64-macos",1468 "arm64-macos"1469 ],1470 "data": {1471 "global": [1472 "_globalRe"1473 ],1474 "objc_class": [1475 "ClassRexport"1476 ]1477 },1478 "text": {1479 "global": [1480 "_funcA"1481 ]1482 }1483 }1484 ],1485 "undefined_symbols": [1486 {1487 "targets": [1488 "x86_64-macos"1489 ],1490 "data": {1491 "global": [1492 "_globalBind"1493 ],1494 "weak": [1495 "referenced_sym"1496 ]1497 }1498 }1499 ]1500},1501"libraries": []1502})";1503 1504 static const char TBDv5FileB[] = R"({1505"tapi_tbd_version": 5,1506"main_library": {1507 "target_info": [1508 {1509 "target": "x86_64-macos",1510 "min_deployment": "10.14"1511 },1512 {1513 "target": "arm64-macos",1514 "min_deployment": "10.14"1515 },1516 {1517 "target": "arm64-maccatalyst",1518 "min_deployment": "12.1"1519 }1520 ],1521 "flags": [1522 {1523 "targets": [1524 "x86_64-macos"1525 ],1526 "attributes": [1527 "flat_namespace"1528 ]1529 }1530 ],1531 "install_names": [1532 {1533 "name": "/S/L/F/Foo.framework/Foo"1534 }1535 ],1536 "current_versions": [1537 {1538 "version": "1.2"1539 }1540 ],1541 "compatibility_versions": [1542 { "version": "1.1" }1543 ],1544 "exported_symbols": [1545 {1546 "targets": [1547 "x86_64-macos",1548 "arm64-macos"1549 ],1550 "data": {1551 "global": [1552 "_globalZ"1553 ],1554 "objc_class": [1555 "ClassZ"1556 ],1557 "weak": [],1558 "thread_local": []1559 },1560 "text": {1561 "global": [1562 "_funcZ"1563 ],1564 "weak": [],1565 "thread_local": []1566 }1567 },1568 {1569 "targets": [1570 "x86_64-macos"1571 ],1572 "data": {1573 "global": [1574 "_globalVarZ"1575 ],1576 "objc_class": [1577 "ClassZ",1578 "ClassF"1579 ],1580 "objc_eh_type": [1581 "ClassZ",1582 "ClassF"1583 ],1584 "objc_ivar": [1585 "ClassZ.ivar1",1586 "ClassZ.ivar2",1587 "ClassF.ivar1"1588 ]1589 },1590 "text": {1591 "global": [1592 "_funcFooZ"1593 ]1594 }1595 }1596 ]1597},1598"libraries": []1599})";1600 1601 Expected<TBDFile> ResultA =1602 TextAPIReader::get(MemoryBufferRef(TBDv5FileA, "Test.tbd"));1603 EXPECT_TRUE(!!ResultA);1604 TBDFile FileA = std::move(ResultA.get());1605 1606 Expected<TBDFile> ResultB =1607 TextAPIReader::get(MemoryBufferRef(TBDv5FileB, "Test.tbd"));1608 EXPECT_TRUE(!!ResultB);1609 TBDFile FileB = std::move(ResultB.get());1610 1611 Expected<TBDFile> MergedResult = FileA->merge(FileB.get());1612 EXPECT_TRUE(!!MergedResult);1613 TBDFile MergedFile = std::move(MergedResult.get());1614 1615 EXPECT_EQ(FileType::TBD_V5, MergedFile->getFileType());1616 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1617 MergedFile->getInstallName());1618 TargetList AllTargets = {1619 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),1620 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),1621 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),1622 };1623 EXPECT_EQ(mapToPlatformSet(AllTargets), MergedFile->getPlatforms());1624 EXPECT_EQ(mapToArchitectureSet(AllTargets), MergedFile->getArchitectures());1625 EXPECT_EQ(PackedVersion(1, 2, 0), MergedFile->getCurrentVersion());1626 EXPECT_EQ(PackedVersion(1, 1, 0), MergedFile->getCompatibilityVersion());1627 EXPECT_TRUE(MergedFile->isApplicationExtensionSafe());1628 EXPECT_FALSE(MergedFile->isTwoLevelNamespace());1629 EXPECT_EQ(0U, MergedFile->documents().size());1630 InterfaceFileRef ClientA("ClientA", AllTargets);1631 InterfaceFileRef ClientB("ClientB", AllTargets);1632 EXPECT_EQ(2U, MergedFile->allowableClients().size());1633 EXPECT_EQ(ClientA, MergedFile->allowableClients().at(0));1634 EXPECT_EQ(ClientB, MergedFile->allowableClients().at(1));1635 1636 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);1637 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);1638 EXPECT_EQ(2U, MergedFile->reexportedLibraries().size());1639 EXPECT_EQ(ReexportA, MergedFile->reexportedLibraries().at(0));1640 EXPECT_EQ(ReexportB, MergedFile->reexportedLibraries().at(1));1641 1642 TargetToAttr RPaths = {1643 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},1644 };1645 EXPECT_EQ(RPaths, MergedFile->rpaths());1646 1647 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},1648 {Target(AK_arm64, PLATFORM_MACOS), "System"},1649 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};1650 EXPECT_EQ(Umbrellas, MergedFile->umbrellas());1651 1652 ExportedSymbolSeq Exports, Reexports, Undefineds;1653 for (const auto *Sym : MergedFile->symbols()) {1654 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};1655 ExportedSymbol Temp =1656 ExportedSymbol{Sym->getKind(),1657 std::string(Sym->getName()),1658 Sym->isWeakDefined() || Sym->isWeakReferenced(),1659 Sym->isThreadLocalValue(),1660 Sym->isData(),1661 SymTargets};1662 if (Sym->isUndefined())1663 Undefineds.emplace_back(std::move(Temp));1664 else1665 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))1666 : Exports.emplace_back(std::move(Temp));1667 }1668 llvm::sort(Exports);1669 llvm::sort(Reexports);1670 llvm::sort(Undefineds);1671 1672 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),1673 Target(AK_arm64, PLATFORM_MACOS)};1674 1675 std::vector<ExportedSymbol> ExpectedExportedSymbols = {1676 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},1677 {EncodeKind::GlobalSymbol,1678 "_funcFoo",1679 false,1680 false,1681 false,1682 {Target(AK_x86_64, PLATFORM_MACOS)}},1683 {EncodeKind::GlobalSymbol,1684 "_funcFooZ",1685 false,1686 false,1687 false,1688 {Target(AK_x86_64, PLATFORM_MACOS)}},1689 {EncodeKind::GlobalSymbol, "_funcZ", false, false, false, MacOSTargets},1690 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},1691 {EncodeKind::GlobalSymbol,1692 "_globalVar",1693 false,1694 false,1695 true,1696 {Target(AK_x86_64, PLATFORM_MACOS)}},1697 {EncodeKind::GlobalSymbol,1698 "_globalVarZ",1699 false,1700 false,1701 true,1702 {Target(AK_x86_64, PLATFORM_MACOS)}},1703 {EncodeKind::GlobalSymbol, "_globalZ", false, false, true, MacOSTargets},1704 {EncodeKind::ObjectiveCClass,1705 "ClassA",1706 false,1707 false,1708 true,1709 {Target(AK_x86_64, PLATFORM_MACOS)}},1710 {EncodeKind::ObjectiveCClass,1711 "ClassB",1712 false,1713 false,1714 true,1715 {Target(AK_x86_64, PLATFORM_MACOS)}},1716 {EncodeKind::ObjectiveCClass,1717 "ClassData",1718 false,1719 false,1720 true,1721 {Target(AK_x86_64, PLATFORM_MACOS)}},1722 {EncodeKind::ObjectiveCClass,1723 "ClassF",1724 false,1725 false,1726 true,1727 {Target(AK_x86_64, PLATFORM_MACOS)}},1728 {EncodeKind::ObjectiveCClass,1729 "ClassZ",1730 false,1731 false,1732 true,1733 {Target(AK_x86_64, PLATFORM_MACOS)}},1734 {EncodeKind::ObjectiveCClassEHType,1735 "ClassA",1736 false,1737 false,1738 true,1739 {Target(AK_x86_64, PLATFORM_MACOS)}},1740 {EncodeKind::ObjectiveCClassEHType,1741 "ClassB",1742 false,1743 false,1744 true,1745 {Target(AK_x86_64, PLATFORM_MACOS)}},1746 {EncodeKind::ObjectiveCClassEHType,1747 "ClassF",1748 false,1749 false,1750 true,1751 {Target(AK_x86_64, PLATFORM_MACOS)}},1752 {EncodeKind::ObjectiveCClassEHType,1753 "ClassZ",1754 false,1755 false,1756 true,1757 {Target(AK_x86_64, PLATFORM_MACOS)}},1758 {EncodeKind::ObjectiveCInstanceVariable,1759 "ClassA.ivar1",1760 false,1761 false,1762 true,1763 {Target(AK_x86_64, PLATFORM_MACOS)}},1764 {EncodeKind::ObjectiveCInstanceVariable,1765 "ClassA.ivar2",1766 false,1767 false,1768 true,1769 {Target(AK_x86_64, PLATFORM_MACOS)}},1770 {EncodeKind::ObjectiveCInstanceVariable,1771 "ClassC.ivar1",1772 false,1773 false,1774 true,1775 {Target(AK_x86_64, PLATFORM_MACOS)}},1776 {EncodeKind::ObjectiveCInstanceVariable,1777 "ClassF.ivar1",1778 false,1779 false,1780 true,1781 {Target(AK_x86_64, PLATFORM_MACOS)}},1782 {EncodeKind::ObjectiveCInstanceVariable,1783 "ClassZ.ivar1",1784 false,1785 false,1786 true,1787 {Target(AK_x86_64, PLATFORM_MACOS)}},1788 {EncodeKind::ObjectiveCInstanceVariable,1789 "ClassZ.ivar2",1790 false,1791 false,1792 true,1793 {Target(AK_x86_64, PLATFORM_MACOS)}},1794 };1795 1796 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {1797 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},1798 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},1799 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,1800 MacOSTargets},1801 };1802 1803 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {1804 {EncodeKind::GlobalSymbol,1805 "_globalBind",1806 false,1807 false,1808 true,1809 {Target(AK_x86_64, PLATFORM_MACOS)}},1810 {EncodeKind::GlobalSymbol,1811 "referenced_sym",1812 true,1813 false,1814 true,1815 {Target(AK_x86_64, PLATFORM_MACOS)}},1816 };1817 1818 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());1819 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());1820 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());1821 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),1822 std::begin(ExpectedExportedSymbols)));1823 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),1824 std::begin(ExpectedReexportedSymbols)));1825 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),1826 std::begin(ExpectedUndefinedSymbols)));1827}1828 1829TEST(TBDv5, ExtractIF) {1830 static const char TBDv5File[] = R"({1831"tapi_tbd_version": 5,1832"main_library": {1833 "target_info": [1834 {1835 "target": "x86_64-macos",1836 "min_deployment": "10.14"1837 },1838 {1839 "target": "arm64-macos",1840 "min_deployment": "10.14"1841 },1842 {1843 "target": "arm64-maccatalyst",1844 "min_deployment": "12.1"1845 }1846 ],1847 "flags": [1848 {1849 "targets": [1850 "x86_64-macos"1851 ],1852 "attributes": [1853 "flat_namespace"1854 ]1855 }1856 ],1857 "install_names": [1858 {1859 "name": "/S/L/F/Foo.framework/Foo"1860 }1861 ],1862 "current_versions": [1863 {1864 "version": "1.2"1865 }1866 ],1867 "compatibility_versions": [1868 { "version": "1.1" }1869 ],1870 "rpaths": [1871 {1872 "targets": [1873 "x86_64-macos"1874 ],1875 "paths": [1876 "@executable_path/.../Frameworks"1877 ]1878 }1879 ],1880 "parent_umbrellas": [1881 {1882 "umbrella": "System"1883 }1884 ],1885 "allowable_clients": [1886 {1887 "clients": [1888 "ClientA",1889 "ClientB"1890 ]1891 }1892 ],1893 "reexported_libraries": [1894 {1895 "names": [1896 "/u/l/l/libfoo.dylib",1897 "/u/l/l/libbar.dylib"1898 ]1899 }1900 ],1901 "exported_symbols": [1902 {1903 "targets": [1904 "x86_64-macos",1905 "arm64-macos"1906 ],1907 "data": {1908 "global": [1909 "_global"1910 ],1911 "objc_class": [1912 "ClassA"1913 ],1914 "weak": [],1915 "thread_local": []1916 },1917 "text": {1918 "global": [1919 "_func"1920 ],1921 "weak": [],1922 "thread_local": []1923 }1924 },1925 {1926 "targets": [1927 "x86_64-macos"1928 ],1929 "data": {1930 "global": [1931 "_globalVar"1932 ],1933 "objc_class": [1934 "ClassA",1935 "ClassB",1936 "ClassData"1937 ],1938 "objc_eh_type": [1939 "ClassA",1940 "ClassB"1941 ],1942 "objc_ivar": [1943 "ClassA.ivar1",1944 "ClassA.ivar2",1945 "ClassC.ivar1"1946 ]1947 },1948 "text": {1949 "global": [1950 "_funcFoo"1951 ]1952 }1953 }1954 ],1955 "reexported_symbols": [1956 {1957 "targets": [1958 "x86_64-macos",1959 "arm64-macos"1960 ],1961 "data": {1962 "global": [1963 "_globalRe"1964 ],1965 "objc_class": [1966 "ClassRexport"1967 ]1968 },1969 "text": {1970 "global": [1971 "_funcA"1972 ]1973 }1974 }1975 ],1976 "undefined_symbols": [1977 {1978 "targets": [1979 "x86_64-macos"1980 ],1981 "data": {1982 "global": [1983 "_globalBind"1984 ],1985 "weak": [1986 "referenced_sym"1987 ]1988 }1989 }1990 ]1991},1992"libraries": []1993})";1994 1995 Expected<TBDFile> Result =1996 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1997 EXPECT_TRUE(!!Result);1998 TBDFile File = std::move(Result.get());1999 2000 Expected<TBDFile> ExtractedResult = File->extract(AK_arm64);2001 EXPECT_TRUE(!!ExtractedResult);2002 TBDFile ExtractedFile = std::move(ExtractedResult.get());2003 2004 EXPECT_EQ(FileType::TBD_V5, ExtractedFile->getFileType());2005 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),2006 ExtractedFile->getInstallName());2007 2008 TargetList AllTargets = {2009 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),2010 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),2011 };2012 EXPECT_EQ(mapToPlatformSet(AllTargets), ExtractedFile->getPlatforms());2013 EXPECT_EQ(mapToArchitectureSet(AllTargets),2014 ExtractedFile->getArchitectures());2015 2016 EXPECT_EQ(PackedVersion(1, 2, 0), ExtractedFile->getCurrentVersion());2017 EXPECT_EQ(PackedVersion(1, 1, 0), ExtractedFile->getCompatibilityVersion());2018 EXPECT_TRUE(ExtractedFile->isApplicationExtensionSafe());2019 EXPECT_FALSE(ExtractedFile->isTwoLevelNamespace());2020 EXPECT_EQ(0U, ExtractedFile->documents().size());2021 2022 InterfaceFileRef ClientA("ClientA", AllTargets);2023 InterfaceFileRef ClientB("ClientB", AllTargets);2024 EXPECT_EQ(2U, ExtractedFile->allowableClients().size());2025 EXPECT_EQ(ClientA, ExtractedFile->allowableClients().at(0));2026 EXPECT_EQ(ClientB, ExtractedFile->allowableClients().at(1));2027 2028 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2029 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2030 EXPECT_EQ(2U, ExtractedFile->reexportedLibraries().size());2031 EXPECT_EQ(ReexportA, ExtractedFile->reexportedLibraries().at(0));2032 EXPECT_EQ(ReexportB, ExtractedFile->reexportedLibraries().at(1));2033 2034 EXPECT_EQ(0u, ExtractedFile->rpaths().size());2035 2036 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},2037 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};2038 EXPECT_EQ(Umbrellas, ExtractedFile->umbrellas());2039 2040 ExportedSymbolSeq Exports, Reexports, Undefineds;2041 for (const auto *Sym : ExtractedFile->symbols()) {2042 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2043 ExportedSymbol Temp =2044 ExportedSymbol{Sym->getKind(),2045 std::string(Sym->getName()),2046 Sym->isWeakDefined() || Sym->isWeakReferenced(),2047 Sym->isThreadLocalValue(),2048 Sym->isData(),2049 SymTargets};2050 if (Sym->isUndefined())2051 Undefineds.emplace_back(std::move(Temp));2052 else2053 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))2054 : Exports.emplace_back(std::move(Temp));2055 }2056 llvm::sort(Exports);2057 llvm::sort(Reexports);2058 llvm::sort(Undefineds);2059 2060 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};2061 2062 std::vector<ExportedSymbol> ExpectedExportedSymbols = {2063 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},2064 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},2065 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},2066 };2067 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {2068 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},2069 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},2070 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,2071 MacOSTargets},2072 };2073 2074 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());2075 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());2076 EXPECT_EQ(0U, Undefineds.size());2077 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),2078 std::begin(ExpectedExportedSymbols)));2079 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),2080 std::begin(ExpectedReexportedSymbols)));2081}2082 2083TEST(TBDv5, RemoveIF) {2084 static const char TBDv5File[] = R"({2085"tapi_tbd_version": 5,2086"main_library": {2087 "target_info": [2088 {2089 "target": "x86_64-macos",2090 "min_deployment": "10.14"2091 },2092 {2093 "target": "arm64-macos",2094 "min_deployment": "10.14"2095 },2096 {2097 "target": "arm64-maccatalyst",2098 "min_deployment": "12.1"2099 }2100 ],2101 "flags": [2102 {2103 "targets": [2104 "x86_64-macos"2105 ],2106 "attributes": [2107 "flat_namespace",2108 "not_for_dyld_shared_cache"2109 ]2110 }2111 ],2112 "install_names": [2113 {2114 "name": "/S/L/F/Foo.framework/Foo"2115 }2116 ],2117 "current_versions": [2118 {2119 "version": "1.2"2120 }2121 ],2122 "compatibility_versions": [2123 { "version": "1.1" }2124 ],2125 "rpaths": [2126 {2127 "targets": [2128 "x86_64-macos"2129 ],2130 "paths": [2131 "@executable_path/.../Frameworks"2132 ]2133 }2134 ],2135 "parent_umbrellas": [2136 {2137 "umbrella": "System"2138 }2139 ],2140 "allowable_clients": [2141 {2142 "clients": [2143 "ClientA",2144 "ClientB"2145 ]2146 }2147 ],2148 "reexported_libraries": [2149 {2150 "names": [2151 "/u/l/l/libfoo.dylib",2152 "/u/l/l/libbar.dylib"2153 ]2154 }2155 ],2156 "exported_symbols": [2157 {2158 "targets": [2159 "x86_64-macos",2160 "arm64-macos"2161 ],2162 "data": {2163 "global": [2164 "_global"2165 ],2166 "objc_class": [2167 "ClassA"2168 ],2169 "weak": [],2170 "thread_local": []2171 },2172 "text": {2173 "global": [2174 "_func"2175 ],2176 "weak": [],2177 "thread_local": []2178 }2179 },2180 {2181 "targets": [2182 "x86_64-macos"2183 ],2184 "data": {2185 "global": [2186 "_globalVar"2187 ],2188 "objc_class": [2189 "ClassA",2190 "ClassB",2191 "ClassData"2192 ],2193 "objc_eh_type": [2194 "ClassA",2195 "ClassB"2196 ],2197 "objc_ivar": [2198 "ClassA.ivar1",2199 "ClassA.ivar2",2200 "ClassC.ivar1"2201 ]2202 },2203 "text": {2204 "global": [2205 "_funcFoo"2206 ]2207 }2208 }2209 ],2210 "reexported_symbols": [2211 {2212 "targets": [2213 "x86_64-macos",2214 "arm64-macos"2215 ],2216 "data": {2217 "global": [2218 "_globalRe"2219 ],2220 "objc_class": [2221 "ClassRexport"2222 ]2223 },2224 "text": {2225 "global": [2226 "_funcA"2227 ]2228 }2229 }2230 ],2231 "undefined_symbols": [2232 {2233 "targets": [2234 "x86_64-macos"2235 ],2236 "data": {2237 "global": [2238 "_globalBind"2239 ],2240 "weak": [2241 "referenced_sym"2242 ]2243 }2244 }2245 ]2246},2247"libraries": []2248})";2249 2250 Expected<TBDFile> Result =2251 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));2252 EXPECT_TRUE(!!Result);2253 TBDFile File = std::move(Result.get());2254 2255 Expected<TBDFile> RemovedResult = File->remove(AK_x86_64);2256 EXPECT_TRUE(!!RemovedResult);2257 TBDFile RemovedFile = std::move(RemovedResult.get());2258 2259 EXPECT_EQ(FileType::TBD_V5, RemovedFile->getFileType());2260 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),2261 RemovedFile->getInstallName());2262 2263 TargetList AllTargets = {2264 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),2265 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),2266 };2267 EXPECT_EQ(mapToPlatformSet(AllTargets), RemovedFile->getPlatforms());2268 EXPECT_EQ(mapToArchitectureSet(AllTargets), RemovedFile->getArchitectures());2269 2270 EXPECT_EQ(PackedVersion(1, 2, 0), RemovedFile->getCurrentVersion());2271 EXPECT_EQ(PackedVersion(1, 1, 0), RemovedFile->getCompatibilityVersion());2272 EXPECT_TRUE(RemovedFile->isApplicationExtensionSafe());2273 EXPECT_TRUE(RemovedFile->isOSLibNotForSharedCache());2274 EXPECT_FALSE(RemovedFile->isTwoLevelNamespace());2275 EXPECT_EQ(0U, RemovedFile->documents().size());2276 2277 InterfaceFileRef ClientA("ClientA", AllTargets);2278 InterfaceFileRef ClientB("ClientB", AllTargets);2279 EXPECT_EQ(2U, RemovedFile->allowableClients().size());2280 EXPECT_EQ(ClientA, RemovedFile->allowableClients().at(0));2281 EXPECT_EQ(ClientB, RemovedFile->allowableClients().at(1));2282 2283 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2284 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2285 EXPECT_EQ(2U, RemovedFile->reexportedLibraries().size());2286 EXPECT_EQ(ReexportA, RemovedFile->reexportedLibraries().at(0));2287 EXPECT_EQ(ReexportB, RemovedFile->reexportedLibraries().at(1));2288 2289 EXPECT_EQ(0u, RemovedFile->rpaths().size());2290 2291 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},2292 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};2293 EXPECT_EQ(Umbrellas, RemovedFile->umbrellas());2294 2295 ExportedSymbolSeq Exports, Reexports, Undefineds;2296 for (const auto *Sym : RemovedFile->symbols()) {2297 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2298 ExportedSymbol Temp =2299 ExportedSymbol{Sym->getKind(),2300 std::string(Sym->getName()),2301 Sym->isWeakDefined() || Sym->isWeakReferenced(),2302 Sym->isThreadLocalValue(),2303 Sym->isData(),2304 SymTargets};2305 if (Sym->isUndefined())2306 Undefineds.emplace_back(std::move(Temp));2307 else2308 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))2309 : Exports.emplace_back(std::move(Temp));2310 }2311 llvm::sort(Exports);2312 llvm::sort(Reexports);2313 llvm::sort(Undefineds);2314 2315 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};2316 2317 std::vector<ExportedSymbol> ExpectedExportedSymbols = {2318 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},2319 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},2320 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},2321 };2322 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {2323 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},2324 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},2325 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,2326 MacOSTargets},2327 };2328 2329 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());2330 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());2331 EXPECT_EQ(0U, Undefineds.size());2332 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),2333 std::begin(ExpectedExportedSymbols)));2334 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),2335 std::begin(ExpectedReexportedSymbols)));2336}2337 2338TEST(TBDv5, InlineIF) {2339 static const char UmbrellaFile[] = R"({2340"tapi_tbd_version": 5,2341"main_library": {2342 "target_info": [2343 {2344 "target": "x86_64-macos",2345 "min_deployment": "10.14"2346 },2347 {2348 "target": "arm64-macos",2349 "min_deployment": "10.14"2350 }2351 ],2352 "install_names": [2353 {2354 "name": "/S/L/F/Foo.framework/Foo"2355 }2356 ],2357 "current_versions": [2358 {2359 "version": "1.2"2360 }2361 ],2362 "reexported_libraries": [2363 {2364 "names": [2365 "/u/l/l/libfoo.dylib",2366 "/u/l/l/libbar.dylib"2367 ]2368 }2369 ]2370}})";2371 2372 static const char ReexportFile[] = R"({2373"tapi_tbd_version": 5,2374"main_library": {2375 "target_info": [2376 {2377 "target": "x86_64-macos",2378 "min_deployment": "10.14"2379 },2380 {2381 "target": "arm64-macos",2382 "min_deployment": "10.14"2383 }2384 ],2385 "install_names": [2386 {2387 "name" : "/u/l/l/libfoo.dylib"2388 }2389 ],2390 "current_versions": [2391 {2392 "version": "1"2393 }2394 ],2395 "rpaths": [2396 {2397 "targets": [2398 "x86_64-macos"2399 ],2400 "paths": [2401 "@executable_path/.../Frameworks"2402 ]2403 }2404 ],2405 "exported_symbols": [2406 {2407 "targets": [2408 "x86_64-macos",2409 "arm64-macos"2410 ],2411 "data": {2412 "global": [2413 "_global"2414 ],2415 "objc_class": [2416 "ClassA"2417 ],2418 "weak": [],2419 "thread_local": []2420 }2421 }2422 ]}})";2423 2424 Expected<TBDFile> UmbrellaResult =2425 TextAPIReader::get(MemoryBufferRef(UmbrellaFile, "Test.tbd"));2426 EXPECT_TRUE(!!UmbrellaResult);2427 TBDFile Umbrella = std::move(UmbrellaResult.get());2428 2429 Expected<TBDFile> ReexportResult =2430 TextAPIReader::get(MemoryBufferRef(ReexportFile, "Test.tbd"));2431 EXPECT_TRUE(!!ReexportResult);2432 TBDReexportFile Reexport = std::move(ReexportResult.get());2433 Umbrella->inlineLibrary(Reexport);2434 2435 EXPECT_EQ(FileType::TBD_V5, Umbrella->getFileType());2436 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),2437 Umbrella->getInstallName());2438 2439 TargetList AllTargets = {2440 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),2441 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),2442 };2443 EXPECT_EQ(mapToPlatformSet(AllTargets), Umbrella->getPlatforms());2444 EXPECT_EQ(mapToArchitectureSet(AllTargets), Umbrella->getArchitectures());2445 2446 EXPECT_EQ(PackedVersion(1, 2, 0), Umbrella->getCurrentVersion());2447 EXPECT_EQ(PackedVersion(1, 0, 0), Umbrella->getCompatibilityVersion());2448 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2449 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2450 EXPECT_EQ(2U, Umbrella->reexportedLibraries().size());2451 EXPECT_EQ(ReexportA, Umbrella->reexportedLibraries().at(0));2452 EXPECT_EQ(ReexportB, Umbrella->reexportedLibraries().at(1));2453 EXPECT_EQ(1U, Umbrella->documents().size());2454 2455 TBDReexportFile Document = Umbrella->documents().front();2456 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());2457 EXPECT_EQ(0U, Document->getSwiftABIVersion());2458 EXPECT_TRUE(Document->isTwoLevelNamespace());2459 EXPECT_TRUE(Document->isApplicationExtensionSafe());2460 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());2461 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());2462 2463 ExportedSymbolSeq Exports;2464 for (const auto *Sym : Document->symbols()) {2465 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2466 Exports.emplace_back(2467 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),2468 Sym->isWeakDefined() || Sym->isWeakReferenced(),2469 Sym->isThreadLocalValue(), Sym->isData(), SymTargets});2470 }2471 llvm::sort(Exports);2472 2473 ExportedSymbolSeq ExpectedExports = {2474 {EncodeKind::GlobalSymbol, "_global", false, false, true, AllTargets},2475 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, AllTargets},2476 };2477 EXPECT_EQ(ExpectedExports.size(), Exports.size());2478 EXPECT_TRUE(2479 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));2480}2481} // end namespace TBDv52482