llvm-project
2452 строки · 65.5 Кб
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-exception
6//
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) {23static 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
188MemoryBufferRef InputBuf = MemoryBufferRef(TBDv5File, "Test.tbd");189Expected<FileType> ExpectedFT = TextAPIReader::canRead(InputBuf);190EXPECT_TRUE(!!ExpectedFT);191
192Expected<TBDFile> Result = TextAPIReader::get(InputBuf);193EXPECT_TRUE(!!Result);194TBDFile File = std::move(Result.get());195EXPECT_EQ(FileType::TBD_V5, File->getFileType());196EXPECT_EQ(*ExpectedFT, File->getFileType());197EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());198
199TargetList AllTargets = {200Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),201Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),202Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),203};204std::set<Target> FileTargets{File->targets().begin(), File->targets().end()};205EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());206EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());207EXPECT_EQ(FileTargets.size(), AllTargets.size());208for (const auto &Targ : AllTargets) {209auto FileTarg = FileTargets.find(Targ);210EXPECT_FALSE(FileTarg == FileTargets.end());211EXPECT_EQ(*FileTarg, Targ);212PackedVersion MD = Targ.MinDeployment;213PackedVersion FileMD = FileTarg->MinDeployment;214EXPECT_EQ(MD, FileMD);215}216
217EXPECT_EQ(PackedVersion(1, 2, 0), File->getCurrentVersion());218EXPECT_EQ(PackedVersion(1, 1, 0), File->getCompatibilityVersion());219EXPECT_TRUE(File->isApplicationExtensionSafe());220EXPECT_FALSE(File->isTwoLevelNamespace());221EXPECT_FALSE(File->isOSLibNotForSharedCache());222EXPECT_EQ(0U, File->documents().size());223
224InterfaceFileRef ClientA("ClientA", AllTargets);225InterfaceFileRef ClientB("ClientB", AllTargets);226EXPECT_EQ(2U, File->allowableClients().size());227EXPECT_EQ(ClientA, File->allowableClients().at(0));228EXPECT_EQ(ClientB, File->allowableClients().at(1));229
230InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);231InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);232EXPECT_EQ(2U, File->reexportedLibraries().size());233EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));234EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));235
236TargetToAttr RPaths = {237{Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},238};239EXPECT_EQ(RPaths, File->rpaths());240
241TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},242{Target(AK_arm64, PLATFORM_MACOS), "System"},243{Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};244EXPECT_EQ(Umbrellas, File->umbrellas());245
246ExportedSymbolSeq Exports, Reexports, Undefineds;247for (const auto *Sym : File->symbols()) {248TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};249ExportedSymbol Temp =250ExportedSymbol{Sym->getKind(),251std::string(Sym->getName()),252Sym->isWeakDefined() || Sym->isWeakReferenced(),253Sym->isThreadLocalValue(),254Sym->isData(),255SymTargets};256if (Sym->isUndefined())257Undefineds.emplace_back(std::move(Temp));258else259Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))260: Exports.emplace_back(std::move(Temp));261}262llvm::sort(Exports);263llvm::sort(Reexports);264llvm::sort(Undefineds);265
266TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),267Target(AK_arm64, PLATFORM_MACOS)};268
269std::vector<ExportedSymbol> ExpectedExportedSymbols = {270{EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},271{EncodeKind::GlobalSymbol,272"_funcFoo",273false,274false,275false,276{Target(AK_x86_64, PLATFORM_MACOS)}},277{EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},278{EncodeKind::GlobalSymbol,279"_globalVar",280false,281false,282true,283{Target(AK_x86_64, PLATFORM_MACOS)}},284{EncodeKind::ObjectiveCClass,285"ClassA",286false,287false,288true,289{Target(AK_x86_64, PLATFORM_MACOS)}},290{EncodeKind::ObjectiveCClass,291"ClassB",292false,293false,294true,295{Target(AK_x86_64, PLATFORM_MACOS)}},296{EncodeKind::ObjectiveCClass,297"ClassData",298false,299false,300true,301{Target(AK_x86_64, PLATFORM_MACOS)}},302{EncodeKind::ObjectiveCClassEHType,303"ClassA",304false,305false,306true,307{Target(AK_x86_64, PLATFORM_MACOS)}},308{EncodeKind::ObjectiveCClassEHType,309"ClassB",310false,311false,312true,313{Target(AK_x86_64, PLATFORM_MACOS)}},314{EncodeKind::ObjectiveCInstanceVariable,315"ClassA.ivar1",316false,317false,318true,319{Target(AK_x86_64, PLATFORM_MACOS)}},320{EncodeKind::ObjectiveCInstanceVariable,321"ClassA.ivar2",322false,323false,324true,325{Target(AK_x86_64, PLATFORM_MACOS)}},326{EncodeKind::ObjectiveCInstanceVariable,327"ClassC.ivar1",328false,329false,330true,331{Target(AK_x86_64, PLATFORM_MACOS)}},332};333std::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,337MacOSTargets},338};339
340std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {341{EncodeKind::GlobalSymbol,342"_globalBind",343false,344false,345true,346{Target(AK_x86_64, PLATFORM_MACOS)}},347{EncodeKind::GlobalSymbol,348"referenced_sym",349true,350false,351true,352{Target(AK_x86_64, PLATFORM_MACOS)}},353};354
355EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());356EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());357EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());358EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),359std::begin(ExpectedExportedSymbols)));360EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),361std::begin(ExpectedReexportedSymbols)));362EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),363std::begin(ExpectedUndefinedSymbols)));364
365EXPECT_TRUE(366File->getSymbol(EncodeKind::GlobalSymbol, "_globalBind").has_value());367}
368
369TEST(TBDv5, ReadMultipleTargets) {370static 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
407Expected<TBDFile> Result =408TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));409EXPECT_TRUE(!!Result);410TBDFile File = std::move(Result.get());411EXPECT_EQ(FileType::TBD_V5, File->getFileType());412EXPECT_EQ(std::string("/usr/lib/libFoo.dylib"), File->getInstallName());413EXPECT_TRUE(File->isApplicationExtensionSafe());414EXPECT_TRUE(File->isTwoLevelNamespace());415EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());416EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());417EXPECT_EQ(8U, File->getSwiftABIVersion());418
419TargetList AllTargets = {420Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),421Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),422Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),423};424EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());425EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());426
427InterfaceFileRef ReexportA("/u/l/l/libArmOnly.dylib",428{Target(AK_arm64, PLATFORM_MACCATALYST)});429InterfaceFileRef ReexportB("/u/l/l/libbar.dylib",430{Target(AK_x86_64, PLATFORM_MACCATALYST)});431InterfaceFileRef ReexportC("/u/l/l/libfoo.dylib",432{Target(AK_x86_64, PLATFORM_MACCATALYST)});433EXPECT_EQ(3U, File->reexportedLibraries().size());434EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));435EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));436EXPECT_EQ(ReexportC, File->reexportedLibraries().at(2));437}
438
439TEST(TBDv5, ReadMultipleDocuments) {440static 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
485Expected<TBDFile> Result =486TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));487EXPECT_TRUE(!!Result);488TBDFile File = std::move(Result.get());489EXPECT_EQ(FileType::TBD_V5, File->getFileType());490EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());491EXPECT_TRUE(File->isTwoLevelNamespace());492EXPECT_TRUE(File->isApplicationExtensionSafe());493
494TargetList Targets(File->targets().begin(), File->targets().end());495Target iOSTarget(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0));496EXPECT_EQ(TargetList{iOSTarget}, Targets);497std::vector<const Symbol *> Symbols(File->symbols().begin(),498File->symbols().end());499EXPECT_EQ(0U, Symbols.size());500
501InterfaceFileRef Reexport("/u/l/l/libfoo.dylib", {iOSTarget});502EXPECT_EQ(1U, File->reexportedLibraries().size());503EXPECT_EQ(Reexport, File->reexportedLibraries().at(0));504
505// Check inlined library.506EXPECT_EQ(1U, File->documents().size());507TBDReexportFile Document = File->documents().front();508Targets = {Document->targets().begin(), Document->targets().end()};509EXPECT_EQ(TargetList{iOSTarget}, Targets);510EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());511EXPECT_EQ(0U, Document->getSwiftABIVersion());512EXPECT_TRUE(Document->isTwoLevelNamespace());513EXPECT_FALSE(Document->isApplicationExtensionSafe());514
515ExportedSymbolSeq Exports;516for (const auto *Sym : Document->symbols())517Exports.emplace_back(518ExportedSymbol{Sym->getKind(),519std::string(Sym->getName()),520Sym->isWeakDefined() || Sym->isWeakReferenced(),521Sym->isThreadLocalValue(),522Sym->isData(),523{iOSTarget}});524
525llvm::sort(Exports);526ExportedSymbolSeq 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",533false,534false,535true,536{iOSTarget}},537{EncodeKind::ObjectiveCClassEHType,538"ClassA",539false,540false,541true,542{iOSTarget}},543{EncodeKind::ObjectiveCClassEHType,544"ClassB",545false,546false,547true,548{iOSTarget}},549};550
551EXPECT_EQ(ExpectedExports.size(), Exports.size());552EXPECT_TRUE(553std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));554}
555
556TEST(TBDv5, WriteFile) {557static 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
713InterfaceFile File;714File.setFileType(FileType::TBD_V5);715
716TargetList AllTargets = {717Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),718Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),719Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),720};721File.addTargets(AllTargets);722File.setInstallName("@rpath/S/L/F/Foo.framework/Foo");723File.setCurrentVersion(PackedVersion(1, 2, 0));724File.setCompatibilityVersion(PackedVersion(1, 1, 0));725File.addRPath("@executable_path/.../Frameworks", AllTargets[0]);726
727for (const auto &Targ : AllTargets) {728File.addParentUmbrella(Targ, "System");729File.addAllowableClient("ClientA", Targ);730File.addAllowableClient("ClientB", Targ);731File.addReexportedLibrary("/u/l/l/libfoo.dylib", Targ);732File.addReexportedLibrary("/u/l/l/libbar.dylib", Targ);733}734
735SymbolFlags Flags = SymbolFlags::None;736// Exports.737File.addSymbol(EncodeKind::GlobalSymbol, "_global",738{AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);739File.addSymbol(EncodeKind::GlobalSymbol, "_func",740{AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Text);741File.addSymbol(EncodeKind::ObjectiveCClass, "ClassA",742{AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);743File.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", {AllTargets[0]},744Flags | SymbolFlags::Text);745File.addSymbol(EncodeKind::GlobalSymbol, "_globalVar", {AllTargets[0]},746Flags | SymbolFlags::Data);747File.addSymbol(EncodeKind::ObjectiveCClass, "ClassData", {AllTargets[0]},748Flags | SymbolFlags::Data);749File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassA", {AllTargets[0]},750Flags | SymbolFlags::Data);751File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassB", {AllTargets[0]},752Flags | SymbolFlags::Data);753File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar1",754{AllTargets[0]}, Flags | SymbolFlags::Data);755File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar2",756{AllTargets[0]}, Flags | SymbolFlags::Data);757File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassC.ivar1",758{AllTargets[0]}, Flags | SymbolFlags::Data);759
760// Reexports.761Flags = SymbolFlags::Rexported;762File.addSymbol(EncodeKind::GlobalSymbol, "_globalRe", AllTargets,763Flags | SymbolFlags::Data);764File.addSymbol(EncodeKind::GlobalSymbol, "_funcA", AllTargets,765Flags | SymbolFlags::Text);766File.addSymbol(EncodeKind::ObjectiveCClass, "ClassRexport", AllTargets,767Flags | SymbolFlags::Data);768
769// Undefineds.770Flags = SymbolFlags::Undefined;771File.addSymbol(EncodeKind::GlobalSymbol, "_globalBind", {AllTargets[0]},772Flags | SymbolFlags::Data);773File.addSymbol(EncodeKind::GlobalSymbol, "referenced_sym", {AllTargets[0]},774Flags | SymbolFlags::Data | SymbolFlags::WeakReferenced);775
776File.setTwoLevelNamespace(false);777File.setApplicationExtensionSafe(true);778
779// Write out file then process it back into IF and compare equality780// against TBDv5File.781SmallString<4096> Buffer;782raw_svector_ostream OS(Buffer);783Error Result = TextAPIWriter::writeToStream(OS, File);784EXPECT_FALSE(Result);785
786Expected<TBDFile> Input =787TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));788EXPECT_TRUE(!!Input);789TBDFile InputFile = std::move(Input.get());790
791Expected<TBDFile> Output =792TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));793EXPECT_TRUE(!!Output);794TBDFile OutputFile = std::move(Output.get());795EXPECT_EQ(*InputFile, *OutputFile);796}
797
798TEST(TBDv5, WriteMultipleDocuments) {799static 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
877InterfaceFile File;878File.setFileType(FileType::TBD_V5);879
880TargetList AllTargets = {881Target(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0)),882Target(AK_armv7s, PLATFORM_IOS, VersionTuple(11, 0)),883};884File.setInstallName("/S/L/F/Foo.framework/Foo");885File.addTarget(AllTargets[0]);886File.setCurrentVersion(PackedVersion(1, 0, 0));887File.setCompatibilityVersion(PackedVersion(1, 0, 0));888File.addReexportedLibrary("/u/l/l/libfoo.dylib", AllTargets[0]);889File.setTwoLevelNamespace();890File.setApplicationExtensionSafe(true);891
892InterfaceFile NestedFile;893NestedFile.setFileType(FileType::TBD_V5);894NestedFile.setInstallName("/u/l/l/libfoo.dylib");895NestedFile.addTargets(AllTargets);896NestedFile.setCompatibilityVersion(PackedVersion(1, 0, 0));897NestedFile.setTwoLevelNamespace();898NestedFile.setApplicationExtensionSafe(false);899NestedFile.setCurrentVersion(PackedVersion(2, 1, 1));900NestedFile.addRPath("@executable_path/.../Frameworks", AllTargets[0]);901for (const auto &Targ : AllTargets)902NestedFile.addReexportedLibrary("@rpath/libfoo.dylib", Targ);903NestedFile.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", AllTargets,904SymbolFlags::Text);905File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFile)));906
907InterfaceFile NestedFileB;908NestedFileB.setFileType(FileType::TBD_V5);909NestedFileB.setInstallName("@rpath/libfoo.dylib");910NestedFileB.addTarget(AllTargets[0]);911NestedFileB.setCompatibilityVersion(PackedVersion(1, 0, 0));912NestedFileB.setCurrentVersion(PackedVersion(1, 0, 0));913NestedFileB.setTwoLevelNamespace();914NestedFileB.setApplicationExtensionSafe(true);915NestedFileB.addSymbol(EncodeKind::GlobalSymbol, "_varFooBaz", {AllTargets[0]},916SymbolFlags::Data);917File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFileB)));918
919// Write out file then process it back into IF and compare equality920// against TBDv5File.921SmallString<4096> Buffer;922raw_svector_ostream OS(Buffer);923Error Result = TextAPIWriter::writeToStream(OS, File, FileType::Invalid,924/*Compact=*/true);925EXPECT_FALSE(Result);926
927Expected<TBDFile> Input =928TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));929EXPECT_TRUE(!!Input);930TBDFile InputFile = std::move(Input.get());931
932Expected<TBDFile> Output =933TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));934EXPECT_TRUE(!!Output);935TBDFile OutputFile = std::move(Output.get());936EXPECT_EQ(*InputFile, *OutputFile);937}
938
939TEST(TBDv5, Target_Simulator) {940static 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
958Expected<TBDFile> Result =959TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));960EXPECT_TRUE(!!Result);961TBDFile File = std::move(Result.get());962EXPECT_EQ(FileType::TBD_V5, File->getFileType());963TargetList ExpectedTargets = {964Target(AK_x86_64, PLATFORM_IOSSIMULATOR, VersionTuple(11, 3)),965Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0)),966};967TargetList Targets{File->targets().begin(), File->targets().end()};968llvm::sort(Targets);969EXPECT_EQ(Targets, ExpectedTargets);970
971SmallString<4096> Buffer;972raw_svector_ostream OS(Buffer);973Error WriteResult = TextAPIWriter::writeToStream(OS, *File);974EXPECT_TRUE(!WriteResult);975
976Expected<TBDFile> Output =977TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));978EXPECT_TRUE(!!Output);979TBDFile WriteResultFile = std::move(Output.get());980EXPECT_EQ(*File, *WriteResultFile);981}
982
983TEST(TBDv5, Target_UnsupportedMinOS) {984static 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
1002Expected<TBDFile> Result =1003TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1004EXPECT_TRUE(!!Result);1005TBDFile File = std::move(Result.get());1006EXPECT_EQ(FileType::TBD_V5, File->getFileType());1007TargetList ExpectedTargets = {1008Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),1009Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0)),1010};1011TargetList Targets{File->targets().begin(), File->targets().end()};1012llvm::sort(Targets);1013EXPECT_EQ(Targets, ExpectedTargets);1014
1015SmallString<4096> Buffer;1016raw_svector_ostream OS(Buffer);1017Error WriteResult = TextAPIWriter::writeToStream(OS, *File);1018EXPECT_TRUE(!WriteResult);1019
1020Expected<TBDFile> Output =1021TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));1022EXPECT_TRUE(!!Output);1023TBDFile WriteResultFile = std::move(Output.get());1024EXPECT_EQ(*File, *WriteResultFile);1025}
1026
1027TEST(TBDv5, MisspelledKey) {1028static 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
1042Expected<TBDFile> Result =1043TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1044EXPECT_FALSE(!!Result);1045std::string ErrorMessage = toString(Result.takeError());1046EXPECT_EQ("invalid install_names section\n", ErrorMessage);1047}
1048
1049TEST(TBDv5, InvalidVersion) {1050static 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
1064Expected<TBDFile> Result =1065TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1066EXPECT_FALSE(!!Result);1067std::string ErrorMessage = toString(Result.takeError());1068EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);1069}
1070
1071TEST(TBDv5, MissingRequiredKey) {1072static 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
1085Expected<TBDFile> Result =1086TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1087EXPECT_FALSE(!!Result);1088std::string ErrorMessage = toString(Result.takeError());1089EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);1090}
1091
1092TEST(TBDv5, InvalidSymbols) {1093static 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
1116Expected<TBDFile> Result =1117TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1118EXPECT_FALSE(!!Result);1119std::string ErrorMessage = toString(Result.takeError());1120EXPECT_EQ("invalid exported_symbols section\n", ErrorMessage);1121}
1122
1123TEST(TBDv5, DefaultMinOS) {1124static 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
1137Expected<TBDFile> Result =1138TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1139EXPECT_TRUE(!!Result);1140TBDFile File = std::move(Result.get());1141EXPECT_EQ(FileType::TBD_V5, File->getFileType());1142EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());1143EXPECT_TRUE(File->targets().begin() != File->targets().end());1144EXPECT_EQ(*File->targets().begin(),1145Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(0, 0)));1146}
1147
1148TEST(TBDv5, InvalidMinOS) {1149static 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
1163Expected<TBDFile> Result =1164TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1165EXPECT_FALSE(!!Result);1166std::string ErrorMessage = toString(Result.takeError());1167EXPECT_EQ("invalid min_deployment section\n", ErrorMessage);1168}
1169
1170TEST(TBDv5, SimSupport) {1171static const char TBDv5File[] = R"({1172"tapi_tbd_version": 5,
1173"main_library": {
1174"target_info": [
1175{
1176"target": "arm64-macos",
1177"min_deployment": "11.1"
1178}
1179],
1180"install_names":[
1181{ "name":"/S/L/F/Foo.framework/Foo" }
1182],
1183"flags":[
1184{ "attributes": ["sim_support"] }
1185]
1186}})";1187
1188Expected<TBDFile> Result =1189TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1190EXPECT_TRUE(!!Result);1191Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));1192TBDFile ReadFile = std::move(Result.get());1193EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());1194EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1195ReadFile->getInstallName());1196EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());1197EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);1198EXPECT_TRUE(ReadFile->hasSimulatorSupport());1199}
1200
1201TEST(TBDv5, NotForSharedCache) {1202static const char TBDv5File[] = R"({1203"tapi_tbd_version": 5,
1204"main_library": {
1205"target_info": [
1206{
1207"target": "arm64-macos",
1208"min_deployment": "11.1"
1209}
1210],
1211"install_names":[
1212{ "name":"/S/L/F/Foo.framework/Foo" }
1213],
1214"flags":[
1215{ "attributes": ["not_for_dyld_shared_cache"] }
1216]
1217}})";1218
1219Expected<TBDFile> Result =1220TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1221EXPECT_TRUE(!!Result);1222Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));1223TBDFile ReadFile = std::move(Result.get());1224EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());1225EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1226ReadFile->getInstallName());1227EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());1228EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);1229EXPECT_FALSE(ReadFile->hasSimulatorSupport());1230EXPECT_TRUE(ReadFile->isOSLibNotForSharedCache());1231}
1232
1233TEST(TBDv5, ObjCInterfaces) {1234static const char TBDv5File[] = R"({1235"tapi_tbd_version": 5,
1236"main_library": {
1237"target_info": [
1238{
1239"target": "arm64-ios-simulator",
1240"min_deployment": "14.0"
1241}
1242],
1243"install_names":[
1244{ "name":"/S/L/F/Foo.framework/Foo" }
1245],
1246"exported_symbols": [
1247{
1248"data": {
1249"global": [
1250"_global",
1251"_OBJC_METACLASS_$_Standalone",
1252"_OBJC_CLASS_$_Standalone2"
1253],
1254"weak": ["_OBJC_EHTYPE_$_NSObject"],
1255"objc_class": [
1256"ClassA",
1257"ClassB"
1258],
1259"objc_eh_type": ["ClassA"]
1260}
1261}]
1262}})";1263
1264Expected<TBDFile> Result =1265TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1266EXPECT_TRUE(!!Result);1267TBDFile File = std::move(Result.get());1268EXPECT_EQ(FileType::TBD_V5, File->getFileType());1269Target ExpectedTarget =1270Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0));1271EXPECT_EQ(*File->targets().begin(), ExpectedTarget);1272
1273// Check Symbols.1274ExportedSymbolSeq Exports;1275for (const auto *Sym : File->symbols()) {1276ExportedSymbol Temp =1277ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),1278Sym->isWeakDefined() || Sym->isWeakReferenced(),1279Sym->isThreadLocalValue(), Sym->isData()};1280Exports.emplace_back(std::move(Temp));1281}1282llvm::sort(Exports);1283
1284std::vector<ExportedSymbol> ExpectedExports = {1285{EncodeKind::GlobalSymbol, "_OBJC_CLASS_$_Standalone2", false, false,1286true},1287{EncodeKind::GlobalSymbol, "_OBJC_EHTYPE_$_NSObject", true, false, true},1288{EncodeKind::GlobalSymbol, "_OBJC_METACLASS_$_Standalone", false, false,1289true},1290{EncodeKind::GlobalSymbol, "_global", false, false, true},1291{EncodeKind::ObjectiveCClass, "ClassA", false, false, true},1292{EncodeKind::ObjectiveCClass, "ClassB", false, false, true},1293{EncodeKind::ObjectiveCClassEHType, "ClassA", false, false, true}};1294
1295EXPECT_EQ(ExpectedExports.size(), Exports.size());1296EXPECT_TRUE(1297std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));1298
1299SmallString<4096> Buffer;1300raw_svector_ostream OS(Buffer);1301Error WriteResult = TextAPIWriter::writeToStream(OS, *File);1302EXPECT_TRUE(!WriteResult);1303
1304Expected<TBDFile> Output =1305TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));1306EXPECT_TRUE(!!Output);1307TBDFile WriteResultFile = std::move(Output.get());1308EXPECT_EQ(*File, *WriteResultFile);1309}
1310
1311TEST(TBDv5, MergeIF) {1312static const char TBDv5FileA[] = R"({1313"tapi_tbd_version": 5,
1314"main_library": {
1315"target_info": [
1316{
1317"target": "x86_64-macos",
1318"min_deployment": "10.14"
1319},
1320{
1321"target": "arm64-macos",
1322"min_deployment": "10.14"
1323},
1324{
1325"target": "arm64-maccatalyst",
1326"min_deployment": "12.1"
1327}
1328],
1329"flags": [
1330{
1331"targets": [
1332"x86_64-macos"
1333],
1334"attributes": [
1335"flat_namespace"
1336]
1337}
1338],
1339"install_names": [
1340{
1341"name": "/S/L/F/Foo.framework/Foo"
1342}
1343],
1344"current_versions": [
1345{
1346"version": "1.2"
1347}
1348],
1349"compatibility_versions": [
1350{ "version": "1.1" }
1351],
1352"rpaths": [
1353{
1354"targets": [
1355"x86_64-macos"
1356],
1357"paths": [
1358"@executable_path/.../Frameworks"
1359]
1360}
1361],
1362"parent_umbrellas": [
1363{
1364"umbrella": "System"
1365}
1366],
1367"allowable_clients": [
1368{
1369"clients": [
1370"ClientA",
1371"ClientB"
1372]
1373}
1374],
1375"reexported_libraries": [
1376{
1377"names": [
1378"/u/l/l/libfoo.dylib",
1379"/u/l/l/libbar.dylib"
1380]
1381}
1382],
1383"exported_symbols": [
1384{
1385"targets": [
1386"x86_64-macos",
1387"arm64-macos"
1388],
1389"data": {
1390"global": [
1391"_global"
1392],
1393"objc_class": [
1394"ClassA"
1395],
1396"weak": [],
1397"thread_local": []
1398},
1399"text": {
1400"global": [
1401"_func"
1402],
1403"weak": [],
1404"thread_local": []
1405}
1406},
1407{
1408"targets": [
1409"x86_64-macos"
1410],
1411"data": {
1412"global": [
1413"_globalVar"
1414],
1415"objc_class": [
1416"ClassA",
1417"ClassB",
1418"ClassData"
1419],
1420"objc_eh_type": [
1421"ClassA",
1422"ClassB"
1423],
1424"objc_ivar": [
1425"ClassA.ivar1",
1426"ClassA.ivar2",
1427"ClassC.ivar1"
1428]
1429},
1430"text": {
1431"global": [
1432"_funcFoo"
1433]
1434}
1435}
1436],
1437"reexported_symbols": [
1438{
1439"targets": [
1440"x86_64-macos",
1441"arm64-macos"
1442],
1443"data": {
1444"global": [
1445"_globalRe"
1446],
1447"objc_class": [
1448"ClassRexport"
1449]
1450},
1451"text": {
1452"global": [
1453"_funcA"
1454]
1455}
1456}
1457],
1458"undefined_symbols": [
1459{
1460"targets": [
1461"x86_64-macos"
1462],
1463"data": {
1464"global": [
1465"_globalBind"
1466],
1467"weak": [
1468"referenced_sym"
1469]
1470}
1471}
1472]
1473},
1474"libraries": []
1475})";1476
1477static const char TBDv5FileB[] = R"({1478"tapi_tbd_version": 5,
1479"main_library": {
1480"target_info": [
1481{
1482"target": "x86_64-macos",
1483"min_deployment": "10.14"
1484},
1485{
1486"target": "arm64-macos",
1487"min_deployment": "10.14"
1488},
1489{
1490"target": "arm64-maccatalyst",
1491"min_deployment": "12.1"
1492}
1493],
1494"flags": [
1495{
1496"targets": [
1497"x86_64-macos"
1498],
1499"attributes": [
1500"flat_namespace"
1501]
1502}
1503],
1504"install_names": [
1505{
1506"name": "/S/L/F/Foo.framework/Foo"
1507}
1508],
1509"current_versions": [
1510{
1511"version": "1.2"
1512}
1513],
1514"compatibility_versions": [
1515{ "version": "1.1" }
1516],
1517"exported_symbols": [
1518{
1519"targets": [
1520"x86_64-macos",
1521"arm64-macos"
1522],
1523"data": {
1524"global": [
1525"_globalZ"
1526],
1527"objc_class": [
1528"ClassZ"
1529],
1530"weak": [],
1531"thread_local": []
1532},
1533"text": {
1534"global": [
1535"_funcZ"
1536],
1537"weak": [],
1538"thread_local": []
1539}
1540},
1541{
1542"targets": [
1543"x86_64-macos"
1544],
1545"data": {
1546"global": [
1547"_globalVarZ"
1548],
1549"objc_class": [
1550"ClassZ",
1551"ClassF"
1552],
1553"objc_eh_type": [
1554"ClassZ",
1555"ClassF"
1556],
1557"objc_ivar": [
1558"ClassZ.ivar1",
1559"ClassZ.ivar2",
1560"ClassF.ivar1"
1561]
1562},
1563"text": {
1564"global": [
1565"_funcFooZ"
1566]
1567}
1568}
1569]
1570},
1571"libraries": []
1572})";1573
1574Expected<TBDFile> ResultA =1575TextAPIReader::get(MemoryBufferRef(TBDv5FileA, "Test.tbd"));1576EXPECT_TRUE(!!ResultA);1577TBDFile FileA = std::move(ResultA.get());1578
1579Expected<TBDFile> ResultB =1580TextAPIReader::get(MemoryBufferRef(TBDv5FileB, "Test.tbd"));1581EXPECT_TRUE(!!ResultB);1582TBDFile FileB = std::move(ResultB.get());1583
1584Expected<TBDFile> MergedResult = FileA->merge(FileB.get());1585EXPECT_TRUE(!!MergedResult);1586TBDFile MergedFile = std::move(MergedResult.get());1587
1588EXPECT_EQ(FileType::TBD_V5, MergedFile->getFileType());1589EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1590MergedFile->getInstallName());1591TargetList AllTargets = {1592Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),1593Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),1594Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),1595};1596EXPECT_EQ(mapToPlatformSet(AllTargets), MergedFile->getPlatforms());1597EXPECT_EQ(mapToArchitectureSet(AllTargets), MergedFile->getArchitectures());1598EXPECT_EQ(PackedVersion(1, 2, 0), MergedFile->getCurrentVersion());1599EXPECT_EQ(PackedVersion(1, 1, 0), MergedFile->getCompatibilityVersion());1600EXPECT_TRUE(MergedFile->isApplicationExtensionSafe());1601EXPECT_FALSE(MergedFile->isTwoLevelNamespace());1602EXPECT_EQ(0U, MergedFile->documents().size());1603InterfaceFileRef ClientA("ClientA", AllTargets);1604InterfaceFileRef ClientB("ClientB", AllTargets);1605EXPECT_EQ(2U, MergedFile->allowableClients().size());1606EXPECT_EQ(ClientA, MergedFile->allowableClients().at(0));1607EXPECT_EQ(ClientB, MergedFile->allowableClients().at(1));1608
1609InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);1610InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);1611EXPECT_EQ(2U, MergedFile->reexportedLibraries().size());1612EXPECT_EQ(ReexportA, MergedFile->reexportedLibraries().at(0));1613EXPECT_EQ(ReexportB, MergedFile->reexportedLibraries().at(1));1614
1615TargetToAttr RPaths = {1616{Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},1617};1618EXPECT_EQ(RPaths, MergedFile->rpaths());1619
1620TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},1621{Target(AK_arm64, PLATFORM_MACOS), "System"},1622{Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};1623EXPECT_EQ(Umbrellas, MergedFile->umbrellas());1624
1625ExportedSymbolSeq Exports, Reexports, Undefineds;1626for (const auto *Sym : MergedFile->symbols()) {1627TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};1628ExportedSymbol Temp =1629ExportedSymbol{Sym->getKind(),1630std::string(Sym->getName()),1631Sym->isWeakDefined() || Sym->isWeakReferenced(),1632Sym->isThreadLocalValue(),1633Sym->isData(),1634SymTargets};1635if (Sym->isUndefined())1636Undefineds.emplace_back(std::move(Temp));1637else1638Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))1639: Exports.emplace_back(std::move(Temp));1640}1641llvm::sort(Exports);1642llvm::sort(Reexports);1643llvm::sort(Undefineds);1644
1645TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),1646Target(AK_arm64, PLATFORM_MACOS)};1647
1648std::vector<ExportedSymbol> ExpectedExportedSymbols = {1649{EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},1650{EncodeKind::GlobalSymbol,1651"_funcFoo",1652false,1653false,1654false,1655{Target(AK_x86_64, PLATFORM_MACOS)}},1656{EncodeKind::GlobalSymbol,1657"_funcFooZ",1658false,1659false,1660false,1661{Target(AK_x86_64, PLATFORM_MACOS)}},1662{EncodeKind::GlobalSymbol, "_funcZ", false, false, false, MacOSTargets},1663{EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},1664{EncodeKind::GlobalSymbol,1665"_globalVar",1666false,1667false,1668true,1669{Target(AK_x86_64, PLATFORM_MACOS)}},1670{EncodeKind::GlobalSymbol,1671"_globalVarZ",1672false,1673false,1674true,1675{Target(AK_x86_64, PLATFORM_MACOS)}},1676{EncodeKind::GlobalSymbol, "_globalZ", false, false, true, MacOSTargets},1677{EncodeKind::ObjectiveCClass,1678"ClassA",1679false,1680false,1681true,1682{Target(AK_x86_64, PLATFORM_MACOS)}},1683{EncodeKind::ObjectiveCClass,1684"ClassB",1685false,1686false,1687true,1688{Target(AK_x86_64, PLATFORM_MACOS)}},1689{EncodeKind::ObjectiveCClass,1690"ClassData",1691false,1692false,1693true,1694{Target(AK_x86_64, PLATFORM_MACOS)}},1695{EncodeKind::ObjectiveCClass,1696"ClassF",1697false,1698false,1699true,1700{Target(AK_x86_64, PLATFORM_MACOS)}},1701{EncodeKind::ObjectiveCClass,1702"ClassZ",1703false,1704false,1705true,1706{Target(AK_x86_64, PLATFORM_MACOS)}},1707{EncodeKind::ObjectiveCClassEHType,1708"ClassA",1709false,1710false,1711true,1712{Target(AK_x86_64, PLATFORM_MACOS)}},1713{EncodeKind::ObjectiveCClassEHType,1714"ClassB",1715false,1716false,1717true,1718{Target(AK_x86_64, PLATFORM_MACOS)}},1719{EncodeKind::ObjectiveCClassEHType,1720"ClassF",1721false,1722false,1723true,1724{Target(AK_x86_64, PLATFORM_MACOS)}},1725{EncodeKind::ObjectiveCClassEHType,1726"ClassZ",1727false,1728false,1729true,1730{Target(AK_x86_64, PLATFORM_MACOS)}},1731{EncodeKind::ObjectiveCInstanceVariable,1732"ClassA.ivar1",1733false,1734false,1735true,1736{Target(AK_x86_64, PLATFORM_MACOS)}},1737{EncodeKind::ObjectiveCInstanceVariable,1738"ClassA.ivar2",1739false,1740false,1741true,1742{Target(AK_x86_64, PLATFORM_MACOS)}},1743{EncodeKind::ObjectiveCInstanceVariable,1744"ClassC.ivar1",1745false,1746false,1747true,1748{Target(AK_x86_64, PLATFORM_MACOS)}},1749{EncodeKind::ObjectiveCInstanceVariable,1750"ClassF.ivar1",1751false,1752false,1753true,1754{Target(AK_x86_64, PLATFORM_MACOS)}},1755{EncodeKind::ObjectiveCInstanceVariable,1756"ClassZ.ivar1",1757false,1758false,1759true,1760{Target(AK_x86_64, PLATFORM_MACOS)}},1761{EncodeKind::ObjectiveCInstanceVariable,1762"ClassZ.ivar2",1763false,1764false,1765true,1766{Target(AK_x86_64, PLATFORM_MACOS)}},1767};1768
1769std::vector<ExportedSymbol> ExpectedReexportedSymbols = {1770{EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},1771{EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},1772{EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,1773MacOSTargets},1774};1775
1776std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {1777{EncodeKind::GlobalSymbol,1778"_globalBind",1779false,1780false,1781true,1782{Target(AK_x86_64, PLATFORM_MACOS)}},1783{EncodeKind::GlobalSymbol,1784"referenced_sym",1785true,1786false,1787true,1788{Target(AK_x86_64, PLATFORM_MACOS)}},1789};1790
1791EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());1792EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());1793EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());1794EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),1795std::begin(ExpectedExportedSymbols)));1796EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),1797std::begin(ExpectedReexportedSymbols)));1798EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),1799std::begin(ExpectedUndefinedSymbols)));1800}
1801
1802TEST(TBDv5, ExtractIF) {1803static const char TBDv5File[] = R"({1804"tapi_tbd_version": 5,
1805"main_library": {
1806"target_info": [
1807{
1808"target": "x86_64-macos",
1809"min_deployment": "10.14"
1810},
1811{
1812"target": "arm64-macos",
1813"min_deployment": "10.14"
1814},
1815{
1816"target": "arm64-maccatalyst",
1817"min_deployment": "12.1"
1818}
1819],
1820"flags": [
1821{
1822"targets": [
1823"x86_64-macos"
1824],
1825"attributes": [
1826"flat_namespace"
1827]
1828}
1829],
1830"install_names": [
1831{
1832"name": "/S/L/F/Foo.framework/Foo"
1833}
1834],
1835"current_versions": [
1836{
1837"version": "1.2"
1838}
1839],
1840"compatibility_versions": [
1841{ "version": "1.1" }
1842],
1843"rpaths": [
1844{
1845"targets": [
1846"x86_64-macos"
1847],
1848"paths": [
1849"@executable_path/.../Frameworks"
1850]
1851}
1852],
1853"parent_umbrellas": [
1854{
1855"umbrella": "System"
1856}
1857],
1858"allowable_clients": [
1859{
1860"clients": [
1861"ClientA",
1862"ClientB"
1863]
1864}
1865],
1866"reexported_libraries": [
1867{
1868"names": [
1869"/u/l/l/libfoo.dylib",
1870"/u/l/l/libbar.dylib"
1871]
1872}
1873],
1874"exported_symbols": [
1875{
1876"targets": [
1877"x86_64-macos",
1878"arm64-macos"
1879],
1880"data": {
1881"global": [
1882"_global"
1883],
1884"objc_class": [
1885"ClassA"
1886],
1887"weak": [],
1888"thread_local": []
1889},
1890"text": {
1891"global": [
1892"_func"
1893],
1894"weak": [],
1895"thread_local": []
1896}
1897},
1898{
1899"targets": [
1900"x86_64-macos"
1901],
1902"data": {
1903"global": [
1904"_globalVar"
1905],
1906"objc_class": [
1907"ClassA",
1908"ClassB",
1909"ClassData"
1910],
1911"objc_eh_type": [
1912"ClassA",
1913"ClassB"
1914],
1915"objc_ivar": [
1916"ClassA.ivar1",
1917"ClassA.ivar2",
1918"ClassC.ivar1"
1919]
1920},
1921"text": {
1922"global": [
1923"_funcFoo"
1924]
1925}
1926}
1927],
1928"reexported_symbols": [
1929{
1930"targets": [
1931"x86_64-macos",
1932"arm64-macos"
1933],
1934"data": {
1935"global": [
1936"_globalRe"
1937],
1938"objc_class": [
1939"ClassRexport"
1940]
1941},
1942"text": {
1943"global": [
1944"_funcA"
1945]
1946}
1947}
1948],
1949"undefined_symbols": [
1950{
1951"targets": [
1952"x86_64-macos"
1953],
1954"data": {
1955"global": [
1956"_globalBind"
1957],
1958"weak": [
1959"referenced_sym"
1960]
1961}
1962}
1963]
1964},
1965"libraries": []
1966})";1967
1968Expected<TBDFile> Result =1969TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));1970EXPECT_TRUE(!!Result);1971TBDFile File = std::move(Result.get());1972
1973Expected<TBDFile> ExtractedResult = File->extract(AK_arm64);1974EXPECT_TRUE(!!ExtractedResult);1975TBDFile ExtractedFile = std::move(ExtractedResult.get());1976
1977EXPECT_EQ(FileType::TBD_V5, ExtractedFile->getFileType());1978EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),1979ExtractedFile->getInstallName());1980
1981TargetList AllTargets = {1982Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),1983Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),1984};1985EXPECT_EQ(mapToPlatformSet(AllTargets), ExtractedFile->getPlatforms());1986EXPECT_EQ(mapToArchitectureSet(AllTargets),1987ExtractedFile->getArchitectures());1988
1989EXPECT_EQ(PackedVersion(1, 2, 0), ExtractedFile->getCurrentVersion());1990EXPECT_EQ(PackedVersion(1, 1, 0), ExtractedFile->getCompatibilityVersion());1991EXPECT_TRUE(ExtractedFile->isApplicationExtensionSafe());1992EXPECT_FALSE(ExtractedFile->isTwoLevelNamespace());1993EXPECT_EQ(0U, ExtractedFile->documents().size());1994
1995InterfaceFileRef ClientA("ClientA", AllTargets);1996InterfaceFileRef ClientB("ClientB", AllTargets);1997EXPECT_EQ(2U, ExtractedFile->allowableClients().size());1998EXPECT_EQ(ClientA, ExtractedFile->allowableClients().at(0));1999EXPECT_EQ(ClientB, ExtractedFile->allowableClients().at(1));2000
2001InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2002InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2003EXPECT_EQ(2U, ExtractedFile->reexportedLibraries().size());2004EXPECT_EQ(ReexportA, ExtractedFile->reexportedLibraries().at(0));2005EXPECT_EQ(ReexportB, ExtractedFile->reexportedLibraries().at(1));2006
2007EXPECT_EQ(0u, ExtractedFile->rpaths().size());2008
2009TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},2010{Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};2011EXPECT_EQ(Umbrellas, ExtractedFile->umbrellas());2012
2013ExportedSymbolSeq Exports, Reexports, Undefineds;2014for (const auto *Sym : ExtractedFile->symbols()) {2015TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2016ExportedSymbol Temp =2017ExportedSymbol{Sym->getKind(),2018std::string(Sym->getName()),2019Sym->isWeakDefined() || Sym->isWeakReferenced(),2020Sym->isThreadLocalValue(),2021Sym->isData(),2022SymTargets};2023if (Sym->isUndefined())2024Undefineds.emplace_back(std::move(Temp));2025else2026Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))2027: Exports.emplace_back(std::move(Temp));2028}2029llvm::sort(Exports);2030llvm::sort(Reexports);2031llvm::sort(Undefineds);2032
2033TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};2034
2035std::vector<ExportedSymbol> ExpectedExportedSymbols = {2036{EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},2037{EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},2038{EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},2039};2040std::vector<ExportedSymbol> ExpectedReexportedSymbols = {2041{EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},2042{EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},2043{EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,2044MacOSTargets},2045};2046
2047EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());2048EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());2049EXPECT_EQ(0U, Undefineds.size());2050EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),2051std::begin(ExpectedExportedSymbols)));2052EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),2053std::begin(ExpectedReexportedSymbols)));2054}
2055
2056TEST(TBDv5, RemoveIF) {2057static const char TBDv5File[] = R"({2058"tapi_tbd_version": 5,
2059"main_library": {
2060"target_info": [
2061{
2062"target": "x86_64-macos",
2063"min_deployment": "10.14"
2064},
2065{
2066"target": "arm64-macos",
2067"min_deployment": "10.14"
2068},
2069{
2070"target": "arm64-maccatalyst",
2071"min_deployment": "12.1"
2072}
2073],
2074"flags": [
2075{
2076"targets": [
2077"x86_64-macos"
2078],
2079"attributes": [
2080"flat_namespace"
2081]
2082}
2083],
2084"install_names": [
2085{
2086"name": "/S/L/F/Foo.framework/Foo"
2087}
2088],
2089"current_versions": [
2090{
2091"version": "1.2"
2092}
2093],
2094"compatibility_versions": [
2095{ "version": "1.1" }
2096],
2097"rpaths": [
2098{
2099"targets": [
2100"x86_64-macos"
2101],
2102"paths": [
2103"@executable_path/.../Frameworks"
2104]
2105}
2106],
2107"parent_umbrellas": [
2108{
2109"umbrella": "System"
2110}
2111],
2112"allowable_clients": [
2113{
2114"clients": [
2115"ClientA",
2116"ClientB"
2117]
2118}
2119],
2120"reexported_libraries": [
2121{
2122"names": [
2123"/u/l/l/libfoo.dylib",
2124"/u/l/l/libbar.dylib"
2125]
2126}
2127],
2128"exported_symbols": [
2129{
2130"targets": [
2131"x86_64-macos",
2132"arm64-macos"
2133],
2134"data": {
2135"global": [
2136"_global"
2137],
2138"objc_class": [
2139"ClassA"
2140],
2141"weak": [],
2142"thread_local": []
2143},
2144"text": {
2145"global": [
2146"_func"
2147],
2148"weak": [],
2149"thread_local": []
2150}
2151},
2152{
2153"targets": [
2154"x86_64-macos"
2155],
2156"data": {
2157"global": [
2158"_globalVar"
2159],
2160"objc_class": [
2161"ClassA",
2162"ClassB",
2163"ClassData"
2164],
2165"objc_eh_type": [
2166"ClassA",
2167"ClassB"
2168],
2169"objc_ivar": [
2170"ClassA.ivar1",
2171"ClassA.ivar2",
2172"ClassC.ivar1"
2173]
2174},
2175"text": {
2176"global": [
2177"_funcFoo"
2178]
2179}
2180}
2181],
2182"reexported_symbols": [
2183{
2184"targets": [
2185"x86_64-macos",
2186"arm64-macos"
2187],
2188"data": {
2189"global": [
2190"_globalRe"
2191],
2192"objc_class": [
2193"ClassRexport"
2194]
2195},
2196"text": {
2197"global": [
2198"_funcA"
2199]
2200}
2201}
2202],
2203"undefined_symbols": [
2204{
2205"targets": [
2206"x86_64-macos"
2207],
2208"data": {
2209"global": [
2210"_globalBind"
2211],
2212"weak": [
2213"referenced_sym"
2214]
2215}
2216}
2217]
2218},
2219"libraries": []
2220})";2221
2222Expected<TBDFile> Result =2223TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));2224EXPECT_TRUE(!!Result);2225TBDFile File = std::move(Result.get());2226
2227Expected<TBDFile> RemovedResult = File->remove(AK_x86_64);2228EXPECT_TRUE(!!RemovedResult);2229TBDFile RemovedFile = std::move(RemovedResult.get());2230
2231EXPECT_EQ(FileType::TBD_V5, RemovedFile->getFileType());2232EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),2233RemovedFile->getInstallName());2234
2235TargetList AllTargets = {2236Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),2237Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),2238};2239EXPECT_EQ(mapToPlatformSet(AllTargets), RemovedFile->getPlatforms());2240EXPECT_EQ(mapToArchitectureSet(AllTargets), RemovedFile->getArchitectures());2241
2242EXPECT_EQ(PackedVersion(1, 2, 0), RemovedFile->getCurrentVersion());2243EXPECT_EQ(PackedVersion(1, 1, 0), RemovedFile->getCompatibilityVersion());2244EXPECT_TRUE(RemovedFile->isApplicationExtensionSafe());2245EXPECT_FALSE(RemovedFile->isTwoLevelNamespace());2246EXPECT_EQ(0U, RemovedFile->documents().size());2247
2248InterfaceFileRef ClientA("ClientA", AllTargets);2249InterfaceFileRef ClientB("ClientB", AllTargets);2250EXPECT_EQ(2U, RemovedFile->allowableClients().size());2251EXPECT_EQ(ClientA, RemovedFile->allowableClients().at(0));2252EXPECT_EQ(ClientB, RemovedFile->allowableClients().at(1));2253
2254InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2255InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2256EXPECT_EQ(2U, RemovedFile->reexportedLibraries().size());2257EXPECT_EQ(ReexportA, RemovedFile->reexportedLibraries().at(0));2258EXPECT_EQ(ReexportB, RemovedFile->reexportedLibraries().at(1));2259
2260EXPECT_EQ(0u, RemovedFile->rpaths().size());2261
2262TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},2263{Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};2264EXPECT_EQ(Umbrellas, RemovedFile->umbrellas());2265
2266ExportedSymbolSeq Exports, Reexports, Undefineds;2267for (const auto *Sym : RemovedFile->symbols()) {2268TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2269ExportedSymbol Temp =2270ExportedSymbol{Sym->getKind(),2271std::string(Sym->getName()),2272Sym->isWeakDefined() || Sym->isWeakReferenced(),2273Sym->isThreadLocalValue(),2274Sym->isData(),2275SymTargets};2276if (Sym->isUndefined())2277Undefineds.emplace_back(std::move(Temp));2278else2279Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))2280: Exports.emplace_back(std::move(Temp));2281}2282llvm::sort(Exports);2283llvm::sort(Reexports);2284llvm::sort(Undefineds);2285
2286TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};2287
2288std::vector<ExportedSymbol> ExpectedExportedSymbols = {2289{EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},2290{EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},2291{EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},2292};2293std::vector<ExportedSymbol> ExpectedReexportedSymbols = {2294{EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},2295{EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},2296{EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,2297MacOSTargets},2298};2299
2300EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());2301EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());2302EXPECT_EQ(0U, Undefineds.size());2303EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),2304std::begin(ExpectedExportedSymbols)));2305EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),2306std::begin(ExpectedReexportedSymbols)));2307}
2308
2309TEST(TBDv5, InlineIF) {2310static const char UmbrellaFile[] = R"({2311"tapi_tbd_version": 5,
2312"main_library": {
2313"target_info": [
2314{
2315"target": "x86_64-macos",
2316"min_deployment": "10.14"
2317},
2318{
2319"target": "arm64-macos",
2320"min_deployment": "10.14"
2321}
2322],
2323"install_names": [
2324{
2325"name": "/S/L/F/Foo.framework/Foo"
2326}
2327],
2328"current_versions": [
2329{
2330"version": "1.2"
2331}
2332],
2333"reexported_libraries": [
2334{
2335"names": [
2336"/u/l/l/libfoo.dylib",
2337"/u/l/l/libbar.dylib"
2338]
2339}
2340]
2341}})";2342
2343static const char ReexportFile[] = R"({2344"tapi_tbd_version": 5,
2345"main_library": {
2346"target_info": [
2347{
2348"target": "x86_64-macos",
2349"min_deployment": "10.14"
2350},
2351{
2352"target": "arm64-macos",
2353"min_deployment": "10.14"
2354}
2355],
2356"install_names": [
2357{
2358"name" : "/u/l/l/libfoo.dylib"
2359}
2360],
2361"current_versions": [
2362{
2363"version": "1"
2364}
2365],
2366"rpaths": [
2367{
2368"targets": [
2369"x86_64-macos"
2370],
2371"paths": [
2372"@executable_path/.../Frameworks"
2373]
2374}
2375],
2376"exported_symbols": [
2377{
2378"targets": [
2379"x86_64-macos",
2380"arm64-macos"
2381],
2382"data": {
2383"global": [
2384"_global"
2385],
2386"objc_class": [
2387"ClassA"
2388],
2389"weak": [],
2390"thread_local": []
2391}
2392}
2393]}})";2394
2395Expected<TBDFile> UmbrellaResult =2396TextAPIReader::get(MemoryBufferRef(UmbrellaFile, "Test.tbd"));2397EXPECT_TRUE(!!UmbrellaResult);2398TBDFile Umbrella = std::move(UmbrellaResult.get());2399
2400Expected<TBDFile> ReexportResult =2401TextAPIReader::get(MemoryBufferRef(ReexportFile, "Test.tbd"));2402EXPECT_TRUE(!!ReexportResult);2403TBDReexportFile Reexport = std::move(ReexportResult.get());2404Umbrella->inlineLibrary(Reexport);2405
2406EXPECT_EQ(FileType::TBD_V5, Umbrella->getFileType());2407EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),2408Umbrella->getInstallName());2409
2410TargetList AllTargets = {2411Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),2412Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),2413};2414EXPECT_EQ(mapToPlatformSet(AllTargets), Umbrella->getPlatforms());2415EXPECT_EQ(mapToArchitectureSet(AllTargets), Umbrella->getArchitectures());2416
2417EXPECT_EQ(PackedVersion(1, 2, 0), Umbrella->getCurrentVersion());2418EXPECT_EQ(PackedVersion(1, 0, 0), Umbrella->getCompatibilityVersion());2419InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);2420InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);2421EXPECT_EQ(2U, Umbrella->reexportedLibraries().size());2422EXPECT_EQ(ReexportA, Umbrella->reexportedLibraries().at(0));2423EXPECT_EQ(ReexportB, Umbrella->reexportedLibraries().at(1));2424EXPECT_EQ(1U, Umbrella->documents().size());2425
2426TBDReexportFile Document = Umbrella->documents().front();2427EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());2428EXPECT_EQ(0U, Document->getSwiftABIVersion());2429EXPECT_TRUE(Document->isTwoLevelNamespace());2430EXPECT_TRUE(Document->isApplicationExtensionSafe());2431EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());2432EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());2433
2434ExportedSymbolSeq Exports;2435for (const auto *Sym : Document->symbols()) {2436TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};2437Exports.emplace_back(2438ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),2439Sym->isWeakDefined() || Sym->isWeakReferenced(),2440Sym->isThreadLocalValue(), Sym->isData(), SymTargets});2441}2442llvm::sort(Exports);2443
2444ExportedSymbolSeq ExpectedExports = {2445{EncodeKind::GlobalSymbol, "_global", false, false, true, AllTargets},2446{EncodeKind::ObjectiveCClass, "ClassA", false, false, true, AllTargets},2447};2448EXPECT_EQ(ExpectedExports.size(), Exports.size());2449EXPECT_TRUE(2450std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));2451}
2452} // end namespace TBDv52453