xref: /llvm-project/llvm/unittests/TextAPI/TextStubV4Tests.cpp (revision 589725f6e803d77adedc3fb5a1cbeaddb99f439a)
1 //===-- TextStubV4Tests.cpp - TBD V4 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 
17 using namespace llvm;
18 using namespace llvm::MachO;
19 
20 
21 namespace TBDv4 {
22 
23 TEST(TBDv4, ReadFile) {
24   static const char TBDv4File[] =
25       "--- !tapi-tbd\n"
26       "tbd-version: 4\n"
27       "targets:  [ i386-macos, x86_64-macos, x86_64-ios ]\n"
28       "uuids:\n"
29       "  - target: i386-macos\n"
30       "    value: 00000000-0000-0000-0000-000000000000\n"
31       "  - target: x86_64-macos\n"
32       "    value: 11111111-1111-1111-1111-111111111111\n"
33       "  - target: x86_64-ios\n"
34       "    value: 11111111-1111-1111-1111-111111111111\n"
35       "flags: [ flat_namespace, installapi ]\n"
36       "install-name: Umbrella.framework/Umbrella\n"
37       "current-version: 1.2.3\n"
38       "compatibility-version: 1.2\n"
39       "swift-abi-version: 5\n"
40       "parent-umbrella:\n"
41       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
42       "    umbrella: System\n"
43       "allowable-clients:\n"
44       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
45       "    clients: [ ClientA ]\n"
46       "reexported-libraries:\n"
47       "  - targets: [ i386-macos ]\n"
48       "    libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
49       "exports:\n"
50       "  - targets: [ i386-macos ]\n"
51       "    symbols: [ _symA ]\n"
52       "    objc-classes: []\n"
53       "    objc-eh-types: []\n"
54       "    objc-ivars: []\n"
55       "    weak-symbols: []\n"
56       "    thread-local-symbols: []\n"
57       "  - targets: [ x86_64-ios ]\n"
58       "    symbols: [_symB]\n"
59       "  - targets: [ x86_64-macos, x86_64-ios ]\n"
60       "    symbols: [_symAB]\n"
61       "reexports:\n"
62       "  - targets: [ i386-macos ]\n"
63       "    symbols: [_symC]\n"
64       "    objc-classes: []\n"
65       "    objc-eh-types: []\n"
66       "    objc-ivars: []\n"
67       "    weak-symbols: []\n"
68       "    thread-local-symbols: []\n"
69       "undefineds:\n"
70       "  - targets: [ i386-macos ]\n"
71       "    symbols: [ _symD ]\n"
72       "    objc-classes: []\n"
73       "    objc-eh-types: []\n"
74       "    objc-ivars: []\n"
75       "    weak-symbols: []\n"
76       "    thread-local-symbols: []\n"
77       "...\n";
78 
79   Expected<TBDFile> Result =
80       TextAPIReader::get(MemoryBufferRef(TBDv4File, "Test.tbd"));
81   EXPECT_TRUE(!!Result);
82   TBDFile File = std::move(Result.get());
83   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
84   PlatformSet Platforms;
85   Platforms.insert(getPlatformFromName("macos"));
86   Platforms.insert(getPlatformFromName("ios"));
87   auto Archs = AK_i386 | AK_x86_64;
88   TargetList Targets = {
89       Target(AK_i386, PLATFORM_MACOS),
90       Target(AK_x86_64, PLATFORM_MACOS),
91       Target(AK_x86_64, PLATFORM_IOS),
92   };
93   UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
94                  {Targets[1], "11111111-1111-1111-1111-111111111111"},
95                  {Targets[2], "11111111-1111-1111-1111-111111111111"}};
96   EXPECT_EQ(Archs, File->getArchitectures());
97   EXPECT_EQ(uuids, File->uuids());
98   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
99   for (auto Platform : File->getPlatforms())
100     EXPECT_EQ(Platforms.count(Platform), 1U);
101   EXPECT_EQ(std::string("Umbrella.framework/Umbrella"), File->getInstallName());
102   EXPECT_EQ(PackedVersion(1, 2, 3), File->getCurrentVersion());
103   EXPECT_EQ(PackedVersion(1, 2, 0), File->getCompatibilityVersion());
104   EXPECT_EQ(5U, File->getSwiftABIVersion());
105   EXPECT_FALSE(File->isTwoLevelNamespace());
106   EXPECT_TRUE(File->isApplicationExtensionSafe());
107   EXPECT_TRUE(File->isInstallAPI());
108   InterfaceFileRef client("ClientA", Targets);
109   InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
110                             {Targets[0]});
111   EXPECT_EQ(1U, File->allowableClients().size());
112   EXPECT_EQ(client, File->allowableClients().front());
113   EXPECT_EQ(1U, File->reexportedLibraries().size());
114   EXPECT_EQ(reexport, File->reexportedLibraries().front());
115 
116   ExportedSymbolSeq Exports, Reexports, Undefineds;
117   ExportedSymbol temp;
118   for (const auto *Sym : File->symbols()) {
119     temp = ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
120                           Sym->isWeakDefined(), Sym->isThreadLocalValue()};
121     EXPECT_FALSE(Sym->isWeakReferenced());
122     if (Sym->isUndefined())
123       Undefineds.emplace_back(std::move(temp));
124     else
125       Sym->isReexported() ? Reexports.emplace_back(std::move(temp))
126                           : Exports.emplace_back(std::move(temp));
127   }
128   llvm::sort(Exports);
129   llvm::sort(Reexports);
130   llvm::sort(Undefineds);
131 
132   static ExportedSymbol ExpectedExportedSymbols[] = {
133       {SymbolKind::GlobalSymbol, "_symA", false, false},
134       {SymbolKind::GlobalSymbol, "_symAB", false, false},
135       {SymbolKind::GlobalSymbol, "_symB", false, false},
136   };
137 
138   static ExportedSymbol ExpectedReexportedSymbols[] = {
139       {SymbolKind::GlobalSymbol, "_symC", false, false},
140   };
141 
142   static ExportedSymbol ExpectedUndefinedSymbols[] = {
143       {SymbolKind::GlobalSymbol, "_symD", false, false},
144   };
145 
146   EXPECT_EQ(std::size(ExpectedExportedSymbols), Exports.size());
147   EXPECT_EQ(std::size(ExpectedReexportedSymbols), Reexports.size());
148   EXPECT_EQ(std::size(ExpectedUndefinedSymbols), Undefineds.size());
149   EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
150                          std::begin(ExpectedExportedSymbols)));
151   EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
152                          std::begin(ExpectedReexportedSymbols)));
153   EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
154                          std::begin(ExpectedUndefinedSymbols)));
155 }
156 
157 TEST(TBDv4, ReadMultipleDocuments) {
158   static const char TBDv4Inlines[] =
159       "--- !tapi-tbd\n"
160       "tbd-version: 4\n"
161       "targets: [ i386-macos, i386-maccatalyst, x86_64-macos, "
162       "x86_64-maccatalyst ]\n"
163       "uuids:\n"
164       "  - target: i386-macos\n"
165       "    value: 00000000-0000-0000-0000-000000000000\n"
166       "  - target: i386-maccatalyst\n"
167       "    value: 00000000-0000-0000-0000-000000000002\n"
168       "  - target: x86_64-macos\n"
169       "    value: 11111111-1111-1111-1111-111111111111\n"
170       "  - target: x86_64-maccatalyst\n"
171       "    value: 11111111-1111-1111-1111-111111111112\n"
172       "install-name: /System/Library/Frameworks/Umbrella.framework/Umbrella\n"
173       "parent-umbrella:\n"
174       "  - targets: [ i386-macos, x86_64-macos ]\n"
175       "    umbrella: System\n"
176       "reexported-libraries:\n"
177       "  - targets: [ i386-macos, x86_64-macos ]\n"
178       "    libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
179       "--- !tapi-tbd\n"
180       "tbd-version: 4\n"
181       "targets:  [ i386-macos, x86_64-macos ]\n"
182       "uuids:\n"
183       "  - target: i386-macos\n"
184       "    value: 20000000-0000-0000-0000-000000000000\n"
185       "  - target: x86_64-macos\n"
186       "    value: 21111111-1111-1111-1111-111111111111\n"
187       "flags: [ flat_namespace ]\n"
188       "install-name: /System/Library/Frameworks/A.framework/A\n"
189       "current-version: 1.2.3\n"
190       "compatibility-version: 1.2\n"
191       "swift-abi-version: 5\n"
192       "exports:\n"
193       "  - targets: [ i386-macos ]\n"
194       "    symbols: [ _symA ]\n"
195       "    objc-classes: []\n"
196       "    objc-eh-types: []\n"
197       "    objc-ivars: []\n"
198       "    weak-symbols: []\n"
199       "    thread-local-symbols: []\n"
200       "  - targets: [ x86_64-macos ]\n"
201       "    symbols: [_symAB]\n"
202       "reexports:\n"
203       "  - targets: [ i386-macos ]\n"
204       "    symbols: [_symC]\n"
205       "    objc-classes: []\n"
206       "    objc-eh-types: []\n"
207       "    objc-ivars: []\n"
208       "    weak-symbols: []\n"
209       "    thread-local-symbols: []\n"
210       "undefineds:\n"
211       "  - targets: [ i386-macos ]\n"
212       "    symbols: [ _symD ]\n"
213       "    objc-classes: []\n"
214       "    objc-eh-types: []\n"
215       "    objc-ivars: []\n"
216       "    weak-symbols: []\n"
217       "    thread-local-symbols: []\n"
218       "...\n";
219 
220   PlatformSet Platforms;
221   Platforms.insert(PLATFORM_MACOS);
222   Platforms.insert(PLATFORM_MACCATALYST);
223   ArchitectureSet Archs = AK_i386 | AK_x86_64;
224   TargetList Targets;
225   for (auto &&Arch : Archs)
226     for (auto &&Platform : Platforms)
227       Targets.emplace_back(Target(Arch, Platform));
228   UUIDs Uuids = {
229       {Targets[0], "00000000-0000-0000-0000-000000000000"},
230       {Targets[1], "00000000-0000-0000-0000-000000000002"},
231       {Targets[2], "11111111-1111-1111-1111-111111111111"},
232       {Targets[3], "11111111-1111-1111-1111-111111111112"},
233   };
234 
235   Expected<TBDFile> Result =
236       TextAPIReader::get(MemoryBufferRef(TBDv4Inlines, "Test.tbd"));
237   EXPECT_TRUE(!!Result);
238   TBDFile File = std::move(Result.get());
239   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
240   EXPECT_EQ(Archs, File->getArchitectures());
241   EXPECT_EQ(Uuids, File->uuids());
242   EXPECT_EQ(Platforms, File->getPlatforms());
243   EXPECT_EQ(
244       std::string("/System/Library/Frameworks/Umbrella.framework/Umbrella"),
245       File->getInstallName());
246   EXPECT_TRUE(File->isTwoLevelNamespace());
247   EXPECT_TRUE(File->isApplicationExtensionSafe());
248   EXPECT_FALSE(File->isInstallAPI());
249   EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
250   EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
251   InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
252                             {Targets[0], Targets[2]});
253   EXPECT_EQ(1U, File->reexportedLibraries().size());
254   EXPECT_EQ(reexport, File->reexportedLibraries().front());
255   EXPECT_TRUE(File->symbols().empty());
256 
257   // Check Inlined Document
258   Targets.clear();
259   Uuids.clear();
260   PlatformType Platform = PLATFORM_MACOS;
261   for (auto &&Arch : Archs)
262     Targets.emplace_back(Target(Arch, Platform));
263   Uuids = {
264       {Targets[0], "20000000-0000-0000-0000-000000000000"},
265       {Targets[1], "21111111-1111-1111-1111-111111111111"},
266   };
267 
268   TBDReexportFile Document = File->documents().front();
269   EXPECT_EQ(FileType::TBD_V4, Document->getFileType());
270   EXPECT_EQ(Archs, Document->getArchitectures());
271   EXPECT_EQ(Uuids, Document->uuids());
272   EXPECT_EQ(1U, Document->getPlatforms().size());
273   EXPECT_EQ(Platform, *(Document->getPlatforms().begin()));
274   EXPECT_EQ(std::string("/System/Library/Frameworks/A.framework/A"),
275             Document->getInstallName());
276   EXPECT_EQ(PackedVersion(1, 2, 3), Document->getCurrentVersion());
277   EXPECT_EQ(PackedVersion(1, 2, 0), Document->getCompatibilityVersion());
278   EXPECT_EQ(5U, Document->getSwiftABIVersion());
279   EXPECT_FALSE(Document->isTwoLevelNamespace());
280   EXPECT_TRUE(Document->isApplicationExtensionSafe());
281   EXPECT_FALSE(Document->isInstallAPI());
282 
283   ExportedSymbolSeq Exports;
284   ExportedSymbolSeq Reexports, Undefineds;
285   for (const auto *Sym : Document->symbols()) {
286     ExportedSymbol Temp =
287         ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
288                        Sym->isWeakDefined(), Sym->isThreadLocalValue()};
289     EXPECT_FALSE(Sym->isWeakReferenced());
290     if (Sym->isUndefined())
291       Undefineds.emplace_back(std::move(Temp));
292     else
293       Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
294                           : Exports.emplace_back(std::move(Temp));
295   }
296   llvm::sort(Exports);
297   llvm::sort(Reexports);
298   llvm::sort(Undefineds);
299 
300   static ExportedSymbol ExpectedExportedSymbols[] = {
301       {SymbolKind::GlobalSymbol, "_symA", false, false},
302       {SymbolKind::GlobalSymbol, "_symAB", false, false},
303   };
304 
305   static ExportedSymbol ExpectedReexportedSymbols[] = {
306       {SymbolKind::GlobalSymbol, "_symC", false, false},
307   };
308 
309   static ExportedSymbol ExpectedUndefinedSymbols[] = {
310       {SymbolKind::GlobalSymbol, "_symD", false, false},
311   };
312 
313   EXPECT_EQ(std::size(ExpectedExportedSymbols), Exports.size());
314   EXPECT_EQ(std::size(ExpectedReexportedSymbols), Reexports.size());
315   EXPECT_EQ(std::size(ExpectedUndefinedSymbols), Undefineds.size());
316   EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
317                          std::begin(ExpectedExportedSymbols)));
318   EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
319                          std::begin(ExpectedReexportedSymbols)));
320   EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
321                          std::begin(ExpectedUndefinedSymbols)));
322 }
323 
324 TEST(TBDv4, WriteFile) {
325   static const char TBDv4File[] =
326       "--- !tapi-tbd\n"
327       "tbd-version:     4\n"
328       "targets:         [ i386-macos, x86_64-ios-simulator ]\n"
329       "uuids:\n"
330       "  - target:          i386-macos\n"
331       "    value:           00000000-0000-0000-0000-000000000000\n"
332       "  - target:          x86_64-ios-simulator\n"
333       "    value:           11111111-1111-1111-1111-111111111111\n"
334       "flags:           [ installapi ]\n"
335       "install-name:    'Umbrella.framework/Umbrella'\n"
336       "current-version: 1.2.3\n"
337       "compatibility-version: 0\n"
338       "swift-abi-version: 5\n"
339       "parent-umbrella:\n"
340       "  - targets:         [ i386-macos, x86_64-ios-simulator ]\n"
341       "    umbrella:        System\n"
342       "allowable-clients:\n"
343       "  - targets:         [ i386-macos ]\n"
344       "    clients:         [ ClientA ]\n"
345       "exports:\n"
346       "  - targets:         [ i386-macos ]\n"
347       "    symbols:         [ _symA ]\n"
348       "    objc-classes:    [ Class1 ]\n"
349       "    weak-symbols:    [ _symC ]\n"
350       "  - targets:         [ x86_64-ios-simulator ]\n"
351       "    symbols:         [ _symB ]\n"
352       "...\n";
353 
354   InterfaceFile File;
355   TargetList Targets = {
356       Target(AK_i386, PLATFORM_MACOS),
357       Target(AK_x86_64, PLATFORM_IOSSIMULATOR),
358   };
359   UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
360                  {Targets[1], "11111111-1111-1111-1111-111111111111"}};
361   File.setInstallName("Umbrella.framework/Umbrella");
362   File.setFileType(FileType::TBD_V4);
363   File.addTargets(Targets);
364   File.addUUID(uuids[0].first, uuids[0].second);
365   File.addUUID(uuids[1].first, uuids[1].second);
366   File.setCurrentVersion(PackedVersion(1, 2, 3));
367   File.setTwoLevelNamespace();
368   File.setInstallAPI(true);
369   File.setApplicationExtensionSafe(true);
370   File.setSwiftABIVersion(5);
371   File.addAllowableClient("ClientA", Targets[0]);
372   File.addParentUmbrella(Targets[0], "System");
373   File.addParentUmbrella(Targets[1], "System");
374   File.addSymbol(SymbolKind::GlobalSymbol, "_symA", {Targets[0]});
375   File.addSymbol(SymbolKind::GlobalSymbol, "_symB", {Targets[1]});
376   File.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
377                  SymbolFlags::WeakDefined);
378   File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[0]});
379 
380   SmallString<4096> Buffer;
381   raw_svector_ostream OS(Buffer);
382   Error Result = TextAPIWriter::writeToStream(OS, File);
383   EXPECT_FALSE(Result);
384   EXPECT_STREQ(TBDv4File, Buffer.c_str());
385 }
386 
387 TEST(TBDv4, WriteMultipleDocuments) {
388   static const char TBDv4Inlines[] =
389       "--- !tapi-tbd\n"
390       "tbd-version:     4\n"
391       "targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
392       "uuids:\n"
393       "  - target:          i386-maccatalyst\n"
394       "    value:           00000000-0000-0000-0000-000000000002\n"
395       "  - target:          x86_64-maccatalyst\n"
396       "    value:           11111111-1111-1111-1111-111111111112\n"
397       "install-name:    "
398       "'/System/Library/Frameworks/Umbrella.framework/Umbrella'\n"
399       "reexported-libraries:\n"
400       "  - targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
401       "    libraries:       [ '/System/Library/Frameworks/A.framework/A' ]\n"
402       "--- !tapi-tbd\n"
403       "tbd-version:     4\n"
404       "targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
405       "uuids:\n"
406       "  - target:          i386-maccatalyst\n"
407       "    value:           00000000-0000-0000-0000-000000000000\n"
408       "  - target:          x86_64-maccatalyst\n"
409       "    value:           11111111-1111-1111-1111-111111111111\n"
410       "install-name:    '/System/Library/Frameworks/A.framework/A'\n"
411       "exports:\n"
412       "  - targets:         [ i386-maccatalyst ]\n"
413       "    weak-symbols:    [ _symC ]\n"
414       "  - targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
415       "    symbols:         [ _symA ]\n"
416       "    objc-classes:    [ Class1 ]\n"
417       "  - targets:         [ x86_64-maccatalyst ]\n"
418       "    symbols:         [ _symAB ]\n"
419       "...\n";
420 
421   InterfaceFile File;
422   PlatformType Platform = PLATFORM_MACCATALYST;
423   TargetList Targets = {
424       Target(AK_i386, Platform),
425       Target(AK_x86_64, Platform),
426   };
427   UUIDs Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000002"},
428                  {Targets[1], "11111111-1111-1111-1111-111111111112"}};
429   File.setInstallName("/System/Library/Frameworks/Umbrella.framework/Umbrella");
430   File.setFileType(FileType::TBD_V4);
431   File.addTargets(Targets);
432   File.addUUID(Uuids[0].first, Uuids[0].second);
433   File.addUUID(Uuids[1].first, Uuids[1].second);
434   File.setCompatibilityVersion(PackedVersion(1, 0, 0));
435   File.setCurrentVersion(PackedVersion(1, 0, 0));
436   File.setTwoLevelNamespace();
437   File.setApplicationExtensionSafe(true);
438   File.addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
439                             Targets[0]);
440   File.addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
441                             Targets[1]);
442 
443   // Write Second Document
444   Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
445            {Targets[1], "11111111-1111-1111-1111-111111111111"}};
446   InterfaceFile Document;
447   Document.setInstallName("/System/Library/Frameworks/A.framework/A");
448   Document.setFileType(FileType::TBD_V4);
449   Document.addTargets(Targets);
450   Document.addUUID(Uuids[0].first, Uuids[0].second);
451   Document.addUUID(Uuids[1].first, Uuids[1].second);
452   Document.setCompatibilityVersion(PackedVersion(1, 0, 0));
453   Document.setCurrentVersion(PackedVersion(1, 0, 0));
454   Document.setTwoLevelNamespace();
455   Document.setApplicationExtensionSafe(true);
456   Document.addSymbol(SymbolKind::GlobalSymbol, "_symA", Targets);
457   Document.addSymbol(SymbolKind::GlobalSymbol, "_symAB", {Targets[1]});
458   Document.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
459                      SymbolFlags::WeakDefined);
460   Document.addSymbol(SymbolKind::ObjectiveCClass, "Class1", Targets);
461   File.addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
462 
463   SmallString<4096> Buffer;
464   raw_svector_ostream OS(Buffer);
465   Error Result = TextAPIWriter::writeToStream(OS, File);
466   EXPECT_FALSE(Result);
467   EXPECT_STREQ(TBDv4Inlines, Buffer.c_str());
468 }
469 
470 TEST(TBDv4, MultipleTargets) {
471   static const char TBDv4MultipleTargets[] =
472       "--- !tapi-tbd\n"
473       "tbd-version: 4\n"
474       "targets: [ i386-maccatalyst, x86_64-tvos, arm64-ios ]\n"
475       "install-name: Test.dylib\n"
476       "...\n";
477 
478   Expected<TBDFile> Result =
479       TextAPIReader::get(MemoryBufferRef(TBDv4MultipleTargets, "Test.tbd"));
480   EXPECT_TRUE(!!Result);
481   PlatformSet Platforms;
482   Platforms.insert(PLATFORM_MACCATALYST);
483   Platforms.insert(PLATFORM_TVOS);
484   Platforms.insert(PLATFORM_IOS);
485   TBDFile File = std::move(Result.get());
486   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
487   EXPECT_EQ(AK_x86_64 | AK_arm64 | AK_i386, File->getArchitectures());
488   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
489   for (auto Platform : File->getPlatforms())
490     EXPECT_EQ(Platforms.count(Platform), 1U);
491 
492   SmallString<4096> Buffer;
493   raw_svector_ostream OS(Buffer);
494   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
495   EXPECT_TRUE(!WriteResult);
496   EXPECT_EQ(stripWhitespace(TBDv4MultipleTargets),
497             stripWhitespace(Buffer.c_str()));
498 }
499 
500 TEST(TBDv4, MultipleTargetsSameArch) {
501   static const char TBDv4TargetsSameArch[] =
502       "--- !tapi-tbd\n"
503       "tbd-version: 4\n"
504       "targets: [ x86_64-tvos , x86_64-maccatalyst ]\n"
505       "install-name: Test.dylib\n"
506       "...\n";
507 
508   Expected<TBDFile> Result =
509       TextAPIReader::get(MemoryBufferRef(TBDv4TargetsSameArch, "Test.tbd"));
510   EXPECT_TRUE(!!Result);
511   PlatformSet Platforms;
512   Platforms.insert(PLATFORM_TVOS);
513   Platforms.insert(PLATFORM_MACCATALYST);
514   TBDFile File = std::move(Result.get());
515   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
516   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
517   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
518   for (auto Platform : File->getPlatforms())
519     EXPECT_EQ(Platforms.count(Platform), 1U);
520 
521   SmallString<4096> Buffer;
522   raw_svector_ostream OS(Buffer);
523   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
524   EXPECT_TRUE(!WriteResult);
525   EXPECT_EQ(stripWhitespace(TBDv4TargetsSameArch),
526             stripWhitespace(Buffer.c_str()));
527 }
528 
529 TEST(TBDv4, MultipleTargetsSamePlatform) {
530   static const char TBDv4MultipleTargetsSamePlatform[] =
531       "--- !tapi-tbd\n"
532       "tbd-version: 4\n"
533       "targets: [ armv7k-ios , arm64-ios]\n"
534       "install-name: Test.dylib\n"
535       "...\n";
536 
537   Expected<TBDFile> Result = TextAPIReader::get(
538       MemoryBufferRef(TBDv4MultipleTargetsSamePlatform, "Test.tbd"));
539   EXPECT_TRUE(!!Result);
540   TBDFile File = std::move(Result.get());
541   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
542   EXPECT_EQ(AK_arm64 | AK_armv7k, File->getArchitectures());
543   EXPECT_EQ(File->getPlatforms().size(), 1U);
544   EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin());
545 
546   SmallString<4096> Buffer;
547   raw_svector_ostream OS(Buffer);
548   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
549   EXPECT_TRUE(!WriteResult);
550   EXPECT_EQ(stripWhitespace(TBDv4MultipleTargetsSamePlatform),
551             stripWhitespace(Buffer.c_str()));
552 }
553 
554 TEST(TBDv4, Target_maccatalyst) {
555   static const char TBDv4TargetMacCatalyst[] =
556       "--- !tapi-tbd\n"
557       "tbd-version: 4\n"
558       "targets: [  x86_64-maccatalyst ]\n"
559       "install-name: Test.dylib\n"
560       "...\n";
561 
562   Expected<TBDFile> Result =
563       TextAPIReader::get(MemoryBufferRef(TBDv4TargetMacCatalyst, "Test.tbd"));
564   EXPECT_TRUE(!!Result);
565   TBDFile File = std::move(Result.get());
566   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
567   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
568   EXPECT_EQ(File->getPlatforms().size(), 1U);
569   EXPECT_EQ(PLATFORM_MACCATALYST, *File->getPlatforms().begin());
570 
571   SmallString<4096> Buffer;
572   raw_svector_ostream OS(Buffer);
573   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
574   EXPECT_TRUE(!WriteResult);
575   EXPECT_EQ(stripWhitespace(TBDv4TargetMacCatalyst),
576             stripWhitespace(Buffer.c_str()));
577 }
578 
579 TEST(TBDv4, Target_x86_ios) {
580   static const char TBDv4Targetx86iOS[] = "--- !tapi-tbd\n"
581                                           "tbd-version: 4\n"
582                                           "targets: [  x86_64-ios ]\n"
583                                           "install-name: Test.dylib\n"
584                                           "...\n";
585 
586   Expected<TBDFile> Result =
587       TextAPIReader::get(MemoryBufferRef(TBDv4Targetx86iOS, "Test.tbd"));
588   EXPECT_TRUE(!!Result);
589   TBDFile File = std::move(Result.get());
590   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
591   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
592   EXPECT_EQ(File->getPlatforms().size(), 1U);
593   EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin());
594 
595   SmallString<4096> Buffer;
596   raw_svector_ostream OS(Buffer);
597   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
598   EXPECT_TRUE(!WriteResult);
599   EXPECT_EQ(stripWhitespace(TBDv4Targetx86iOS),
600             stripWhitespace(Buffer.c_str()));
601 }
602 
603 TEST(TBDv4, Target_arm_bridgeOS) {
604   static const char TBDv4PlatformBridgeOS[] = "--- !tapi-tbd\n"
605                                               "tbd-version: 4\n"
606                                               "targets: [  armv7k-bridgeos ]\n"
607                                               "install-name: Test.dylib\n"
608                                               "...\n";
609 
610   Expected<TBDFile> Result =
611       TextAPIReader::get(MemoryBufferRef(TBDv4PlatformBridgeOS, "Test.tbd"));
612   EXPECT_TRUE(!!Result);
613   TBDFile File = std::move(Result.get());
614   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
615   EXPECT_EQ(File->getPlatforms().size(), 1U);
616   EXPECT_EQ(PLATFORM_BRIDGEOS, *File->getPlatforms().begin());
617   EXPECT_EQ(ArchitectureSet(AK_armv7k), File->getArchitectures());
618 
619   SmallString<4096> Buffer;
620   raw_svector_ostream OS(Buffer);
621   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
622   EXPECT_TRUE(!WriteResult);
623   EXPECT_EQ(stripWhitespace(TBDv4PlatformBridgeOS),
624             stripWhitespace(Buffer.c_str()));
625 }
626 
627 TEST(TBDv4, Target_arm_iOS) {
628   static const char TBDv4ArchArm64e[] = "--- !tapi-tbd\n"
629                                         "tbd-version: 4\n"
630                                         "targets: [  arm64e-ios ]\n"
631                                         "install-name: Test.dylib\n"
632                                         "...\n";
633 
634   Expected<TBDFile> Result =
635       TextAPIReader::get(MemoryBufferRef(TBDv4ArchArm64e, "Test.tbd"));
636   EXPECT_TRUE(!!Result);
637   TBDFile File = std::move(Result.get());
638   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
639   EXPECT_EQ(File->getPlatforms().size(), 1U);
640   EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin());
641   EXPECT_EQ(ArchitectureSet(AK_arm64e), File->getArchitectures());
642 
643   SmallString<4096> Buffer;
644   raw_svector_ostream OS(Buffer);
645   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
646   EXPECT_TRUE(!WriteResult);
647   EXPECT_EQ(stripWhitespace(TBDv4ArchArm64e), stripWhitespace(Buffer.c_str()));
648 }
649 
650 TEST(TBDv4, Target_x86_macos) {
651   static const char TBDv4Targetx86MacOS[] = "--- !tapi-tbd\n"
652                                             "tbd-version: 4\n"
653                                             "targets: [  x86_64-macos ]\n"
654                                             "install-name: Test.dylib\n"
655                                             "...\n";
656 
657   Expected<TBDFile> Result =
658       TextAPIReader::get(MemoryBufferRef(TBDv4Targetx86MacOS, "Test.tbd"));
659   EXPECT_TRUE(!!Result);
660   TBDFile File = std::move(Result.get());
661   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
662   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
663   EXPECT_EQ(File->getPlatforms().size(), 1U);
664   EXPECT_EQ(PLATFORM_MACOS, *File->getPlatforms().begin());
665 
666   SmallString<4096> Buffer;
667   raw_svector_ostream OS(Buffer);
668   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
669   EXPECT_TRUE(!WriteResult);
670   EXPECT_EQ(stripWhitespace(TBDv4Targetx86MacOS),
671             stripWhitespace(Buffer.c_str()));
672 }
673 
674 TEST(TBDv4, Target_x86_ios_simulator) {
675   static const char TBDv4Targetx86iOSSim[] =
676       "--- !tapi-tbd\n"
677       "tbd-version: 4\n"
678       "targets: [  x86_64-ios-simulator  ]\n"
679       "install-name: Test.dylib\n"
680       "...\n";
681 
682   Expected<TBDFile> Result =
683       TextAPIReader::get(MemoryBufferRef(TBDv4Targetx86iOSSim, "Test.tbd"));
684   EXPECT_TRUE(!!Result);
685   TBDFile File = std::move(Result.get());
686   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
687   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
688   EXPECT_EQ(File->getPlatforms().size(), 1U);
689   EXPECT_EQ(PLATFORM_IOSSIMULATOR, *File->getPlatforms().begin());
690 
691   SmallString<4096> Buffer;
692   raw_svector_ostream OS(Buffer);
693   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
694   EXPECT_TRUE(!WriteResult);
695   EXPECT_EQ(stripWhitespace(TBDv4Targetx86iOSSim),
696             stripWhitespace(Buffer.c_str()));
697 }
698 
699 TEST(TBDv4, Target_x86_tvos_simulator) {
700   static const char TBDv4x86tvOSSim[] = "--- !tapi-tbd\n"
701                                         "tbd-version: 4\n"
702                                         "targets: [  x86_64-tvos-simulator  ]\n"
703                                         "install-name: Test.dylib\n"
704                                         "...\n";
705 
706   Expected<TBDFile> Result =
707       TextAPIReader::get(MemoryBufferRef(TBDv4x86tvOSSim, "Test.tbd"));
708   EXPECT_TRUE(!!Result);
709   TBDFile File = std::move(Result.get());
710   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
711   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
712   EXPECT_EQ(File->getPlatforms().size(), 1U);
713   EXPECT_EQ(PLATFORM_TVOSSIMULATOR, *File->getPlatforms().begin());
714 
715   SmallString<4096> Buffer;
716   raw_svector_ostream OS(Buffer);
717   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
718   EXPECT_TRUE(!WriteResult);
719   EXPECT_EQ(stripWhitespace(TBDv4x86tvOSSim), stripWhitespace(Buffer.c_str()));
720 }
721 
722 TEST(TBDv4, Target_i386_watchos_simulator) {
723   static const char TBDv4i386watchOSSim[] =
724       "--- !tapi-tbd\n"
725       "tbd-version: 4\n"
726       "targets: [  i386-watchos-simulator  ]\n"
727       "install-name: Test.dylib\n"
728       "...\n";
729 
730   Expected<TBDFile> Result =
731       TextAPIReader::get(MemoryBufferRef(TBDv4i386watchOSSim, "Test.tbd"));
732   EXPECT_TRUE(!!Result);
733   TBDFile File = std::move(Result.get());
734   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
735   EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures());
736   EXPECT_EQ(File->getPlatforms().size(), 1U);
737   EXPECT_EQ(PLATFORM_WATCHOSSIMULATOR, *File->getPlatforms().begin());
738 
739   SmallString<4096> Buffer;
740   raw_svector_ostream OS(Buffer);
741   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
742   EXPECT_TRUE(!WriteResult);
743   EXPECT_EQ(stripWhitespace(TBDv4i386watchOSSim),
744             stripWhitespace(Buffer.c_str()));
745 }
746 
747 TEST(TBDv4, Target_i386_driverkit) {
748   static const char TBDv4i386DriverKit[] = "--- !tapi-tbd\n"
749                                            "tbd-version: 4\n"
750                                            "targets: [  i386-driverkit  ]\n"
751                                            "install-name: Test.dylib\n"
752                                            "...\n";
753 
754   Expected<TBDFile> Result =
755       TextAPIReader::get(MemoryBufferRef(TBDv4i386DriverKit, "Test.tbd"));
756   EXPECT_TRUE(!!Result);
757   TBDFile File = std::move(Result.get());
758   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
759   EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures());
760   EXPECT_EQ(File->getPlatforms().size(), 1U);
761   EXPECT_EQ(PLATFORM_DRIVERKIT, *File->getPlatforms().begin());
762 
763   SmallString<4096> Buffer;
764   raw_svector_ostream OS(Buffer);
765   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
766   EXPECT_TRUE(!WriteResult);
767   EXPECT_EQ(stripWhitespace(TBDv4i386DriverKit),
768             stripWhitespace(Buffer.c_str()));
769 }
770 
771 TEST(TBDv4, Swift_1) {
772   static const char TBDv4SwiftVersion1[] = "--- !tapi-tbd\n"
773                                            "tbd-version: 4\n"
774                                            "targets: [  x86_64-macos ]\n"
775                                            "install-name: Test.dylib\n"
776                                            "swift-abi-version: 1\n"
777                                            "...\n";
778 
779   Expected<TBDFile> Result =
780       TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion1, "Test.tbd"));
781   EXPECT_TRUE(!!Result);
782   TBDFile File = std::move(Result.get());
783   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
784   EXPECT_EQ(1U, File->getSwiftABIVersion());
785 
786   // No writer test because we emit "swift-abi-version:1.0".
787 }
788 
789 TEST(TBDv4, Swift_2) {
790   static const char TBDv4Swift2[] = "--- !tapi-tbd\n"
791                                     "tbd-version: 4\n"
792                                     "targets: [  x86_64-macos ]\n"
793                                     "install-name: Test.dylib\n"
794                                     "swift-abi-version: 2\n"
795                                     "...\n";
796 
797   Expected<TBDFile> Result =
798       TextAPIReader::get(MemoryBufferRef(TBDv4Swift2, "Test.tbd"));
799   EXPECT_TRUE(!!Result);
800   TBDFile File = std::move(Result.get());
801   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
802   EXPECT_EQ(2U, File->getSwiftABIVersion());
803 
804   // No writer test because we emit "swift-abi-version:2.0".
805 }
806 
807 TEST(TBDv4, Swift_5) {
808   static const char TBDv4SwiftVersion5[] = "--- !tapi-tbd\n"
809                                            "tbd-version: 4\n"
810                                            "targets: [  x86_64-macos ]\n"
811                                            "install-name: Test.dylib\n"
812                                            "swift-abi-version: 5\n"
813                                            "...\n";
814 
815   Expected<TBDFile> Result =
816       TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion5, "Test.tbd"));
817   EXPECT_TRUE(!!Result);
818   TBDFile File = std::move(Result.get());
819   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
820   EXPECT_EQ(5U, File->getSwiftABIVersion());
821 
822   SmallString<4096> Buffer;
823   raw_svector_ostream OS(Buffer);
824   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
825   EXPECT_TRUE(!WriteResult);
826   EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion5),
827             stripWhitespace(Buffer.c_str()));
828 }
829 
830 TEST(TBDv4, Swift_99) {
831   static const char TBDv4SwiftVersion99[] = "--- !tapi-tbd\n"
832                                             "tbd-version: 4\n"
833                                             "targets: [  x86_64-macos ]\n"
834                                             "install-name: Test.dylib\n"
835                                             "swift-abi-version: 99\n"
836                                             "...\n";
837 
838   Expected<TBDFile> Result =
839       TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion99, "Test.tbd"));
840   EXPECT_TRUE(!!Result);
841   TBDFile File = std::move(Result.get());
842   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
843   EXPECT_EQ(99U, File->getSwiftABIVersion());
844 
845   SmallString<4096> Buffer;
846   raw_svector_ostream OS(Buffer);
847   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
848   EXPECT_TRUE(!WriteResult);
849   EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion99),
850             stripWhitespace(Buffer.c_str()));
851 }
852 
853 TEST(TBDv4, InvalidArchitecture) {
854   static const char TBDv4UnknownArch[] = "--- !tapi-tbd\n"
855                                          "tbd-version: 4\n"
856                                          "targets: [ foo-macos ]\n"
857                                          "install-name: Test.dylib\n"
858                                          "...\n";
859 
860   Expected<TBDFile> Result =
861       TextAPIReader::get(MemoryBufferRef(TBDv4UnknownArch, "Test.tbd"));
862   EXPECT_FALSE(!!Result);
863   std::string ErrorMessage = toString(Result.takeError());
864   EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown "
865             "architecture\ntargets: [ foo-macos ]\n"
866             "           ^~~~~~~~~~\n",
867             ErrorMessage);
868 }
869 
870 TEST(TBDv4, InvalidPlatform) {
871   static const char TBDv4FInvalidPlatform[] = "--- !tapi-tbd\n"
872                                               "tbd-version: 4\n"
873                                               "targets: [ x86_64-maos ]\n"
874                                               "install-name: Test.dylib\n"
875                                               "...\n";
876 
877   Expected<TBDFile> Result =
878       TextAPIReader::get(MemoryBufferRef(TBDv4FInvalidPlatform, "Test.tbd"));
879   EXPECT_FALSE(!!Result);
880   std::string ErrorMessage = toString(Result.takeError());
881   EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: "
882             "[ x86_64-maos ]\n"
883             "           ^~~~~~~~~~~~\n",
884             ErrorMessage);
885 }
886 
887 TEST(TBDv4, MalformedFile1) {
888   static const char TBDv4MalformedFile1[] = "--- !tapi-tbd\n"
889                                             "tbd-version: 4\n"
890                                             "...\n";
891 
892   Expected<TBDFile> Result =
893       TextAPIReader::get(MemoryBufferRef(TBDv4MalformedFile1, "Test.tbd"));
894   EXPECT_FALSE(!!Result);
895   std::string ErrorMessage = toString(Result.takeError());
896   ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
897             "'targets'\ntbd-version: 4\n^\n",
898             ErrorMessage);
899 }
900 
901 TEST(TBDv4, MalformedFile2) {
902   static const char TBDv4MalformedFile2[] = "--- !tapi-tbd\n"
903                                             "tbd-version: 4\n"
904                                             "targets: [ x86_64-macos ]\n"
905                                             "install-name: Test.dylib\n"
906                                             "foobar: \"unsupported key\"\n";
907 
908   Expected<TBDFile> Result =
909       TextAPIReader::get(MemoryBufferRef(TBDv4MalformedFile2, "Test.tbd"));
910   EXPECT_FALSE(!!Result);
911   std::string ErrorMessage = toString(Result.takeError());
912   ASSERT_EQ(
913       "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: "
914       "\"unsupported key\"\n^~~~~~\n",
915       ErrorMessage);
916 }
917 
918 TEST(TBDv4, MalformedFile3) {
919   static const char TBDv4MalformedSwift[] = "--- !tapi-tbd\n"
920                                             "tbd-version: 4\n"
921                                             "targets: [  x86_64-macos ]\n"
922                                             "install-name: Test.dylib\n"
923                                             "swift-abi-version: 1.1\n"
924                                             "...\n";
925 
926   Expected<TBDFile> Result =
927       TextAPIReader::get(MemoryBufferRef(TBDv4MalformedSwift, "Test.tbd"));
928   EXPECT_FALSE(!!Result);
929   std::string ErrorMessage = toString(Result.takeError());
930   EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
931             "version.\nswift-abi-version: 1.1\n                   ^~~\n",
932             ErrorMessage);
933 }
934 
935 TEST(TBDv4, InterfaceEquality) {
936   static const char TBDv4File[] =
937       "--- !tapi-tbd\n"
938       "tbd-version: 4\n"
939       "targets:  [ i386-macos, x86_64-macos, x86_64-ios ]\n"
940       "uuids:\n"
941       "  - target: i386-macos\n"
942       "    value: 00000000-0000-0000-0000-000000000000\n"
943       "  - target: x86_64-macos\n"
944       "    value: 11111111-1111-1111-1111-111111111111\n"
945       "  - target: x86_64-ios\n"
946       "    value: 11111111-1111-1111-1111-111111111111\n"
947       "flags: [ flat_namespace, installapi ]\n"
948       "install-name: Umbrella.framework/Umbrella\n"
949       "current-version: 1.2.3\n"
950       "compatibility-version: 1.2\n"
951       "swift-abi-version: 5\n"
952       "parent-umbrella:\n"
953       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
954       "    umbrella: System\n"
955       "allowable-clients:\n"
956       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
957       "    clients: [ ClientA ]\n"
958       "reexported-libraries:\n"
959       "  - targets: [ i386-macos ]\n"
960       "    libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
961       "exports:\n"
962       "  - targets: [ i386-macos ]\n"
963       "    symbols: [ _symA ]\n"
964       "    objc-classes: []\n"
965       "    objc-eh-types: []\n"
966       "    objc-ivars: []\n"
967       "    weak-symbols: []\n"
968       "    thread-local-symbols: []\n"
969       "  - targets: [ x86_64-ios ]\n"
970       "    symbols: [_symB]\n"
971       "  - targets: [ x86_64-macos, x86_64-ios ]\n"
972       "    symbols: [_symAB]\n"
973       "reexports:\n"
974       "  - targets: [ i386-macos ]\n"
975       "    symbols: [_symC]\n"
976       "    objc-classes: []\n"
977       "    objc-eh-types: []\n"
978       "    objc-ivars: []\n"
979       "    weak-symbols: []\n"
980       "    thread-local-symbols: []\n"
981       "undefineds:\n"
982       "  - targets: [ i386-macos ]\n"
983       "    symbols: [ _symD ]\n"
984       "    objc-classes: []\n"
985       "    objc-eh-types: []\n"
986       "    objc-ivars: []\n"
987       "    weak-symbols: []\n"
988       "    thread-local-symbols: []\n"
989       "tbd-version:     4\n"
990       "targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
991       "uuids:\n"
992       "  - target:          i386-maccatalyst\n"
993       "    value:           00000000-0000-0000-0000-000000000000\n"
994       "  - target:          x86_64-maccatalyst\n"
995       "    value:           11111111-1111-1111-1111-111111111111\n"
996       "install-name:    '/System/Library/Frameworks/A.framework/A'\n"
997       "exports:\n"
998       "  - targets:         [ i386-maccatalyst ]\n"
999       "    weak-symbols:    [ _symC ]\n"
1000       "  - targets:         [ i386-maccatalyst, x86_64-maccatalyst ]\n"
1001       "    symbols:         [ _symA ]\n"
1002       "    objc-classes:    [ Class1 ]\n"
1003       "  - targets:         [ x86_64-maccatalyst ]\n"
1004       "    symbols:         [ _symAB ]\n"
1005       "...\n";
1006 
1007   Expected<TBDFile> ResultA =
1008       TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd"));
1009   EXPECT_TRUE(!!ResultA);
1010   InterfaceFile FileA = std::move(*ResultA.get());
1011   Expected<TBDFile> ResultB =
1012       TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestB.tbd"));
1013   EXPECT_TRUE(!!ResultB);
1014   InterfaceFile FileB = std::move(*ResultB.get());
1015   EXPECT_TRUE(FileA == FileB);
1016 }
1017 
1018 TEST(TBDv4, InterfaceDiffVersionsEquality) {
1019   static const char TBDv4File[] =
1020       "--- !tapi-tbd\n"
1021       "tbd-version: 4\n"
1022       "targets:  [ i386-macos, x86_64-macos ]\n"
1023       "uuids:\n"
1024       "  - target: i386-macos\n"
1025       "    value: 00000000-0000-0000-0000-000000000000\n"
1026       "  - target: x86_64-macos\n"
1027       "    value: 11111111-1111-1111-1111-111111111111\n"
1028       "flags: [ installapi ]\n"
1029       "install-name: Umbrella.framework/Umbrella\n"
1030       "current-version: 1.2.3\n"
1031       "compatibility-version: 1.0\n"
1032       "swift-abi-version: 5\n"
1033       "parent-umbrella:\n"
1034       "  - targets: [ i386-macos, x86_64-macos ]\n"
1035       "    umbrella: System\n"
1036       "allowable-clients:\n"
1037       "  - targets: [ i386-macos, x86_64-macos ]\n"
1038       "    clients: [ ClientA ]\n"
1039       "reexported-libraries:\n"
1040       "  - targets: [ i386-macos ]\n"
1041       "    libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
1042       "exports:\n"
1043       "  - targets: [ i386-macos ]\n"
1044       "    symbols: [ _sym5 ]\n"
1045       "    objc-classes: [ class3]\n"
1046       "    objc-eh-types: []\n"
1047       "    objc-ivars: [ class1._ivar3 ]\n"
1048       "    weak-symbols: [ _weak3 ]\n"
1049       "  - targets: [ x86_64-macos ]\n"
1050       "    symbols: [_symAB]\n"
1051       "  - targets: [ i386-macos, x86_64-macos ]\n"
1052       "    symbols: [_symA]\n"
1053       "    objc-classes: [ class1, class2 ]\n"
1054       "    objc-eh-types: [ class1 ]\n"
1055       "    objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
1056       "    weak-symbols: [ _weak1, _weak2 ]\n"
1057       "    thread-local-symbols: [ _tlv1, _tlv3 ]\n"
1058       "undefineds:\n"
1059       "  - targets: [ i386-macos ]\n"
1060       "    symbols: [ _symC ]\n"
1061       "    objc-classes: []\n"
1062       "    objc-eh-types: []\n"
1063       "    objc-ivars: []\n"
1064       "    weak-symbols: []\n"
1065       "    thread-local-symbols: []\n"
1066       "...\n";
1067 
1068   static const char TBDv3File[] =
1069       "--- !tapi-tbd-v3\n"
1070       "archs: [ i386, x86_64 ]\n"
1071       "uuids: [ 'i386: 00000000-0000-0000-0000-000000000000',\n"
1072       "         'x86_64: 22222222-2222-2222-2222-222222222222']\n"
1073       "platform: macosx\n"
1074       "flags: [ installapi ]\n"
1075       "install-name: Umbrella.framework/Umbrella\n"
1076       "current-version: 1.2.3\n"
1077       "compatibility-version: 1.0\n"
1078       "swift-abi-version: 5\n"
1079       "parent-umbrella: System\n"
1080       "exports:\n"
1081       "  - archs: [ i386, x86_64 ]\n"
1082       "    allowable-clients: [ ClientA ]\n"
1083       "    symbols: [ _symA ]\n"
1084       "    objc-classes: [ class1, class2 ]\n"
1085       "    objc-eh-types: [ class1 ]\n"
1086       "    objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
1087       "    weak-def-symbols: [ _weak1, _weak2 ]\n"
1088       "    thread-local-symbols: [ _tlv1, _tlv3 ]\n"
1089       "  - archs: [ i386 ]\n"
1090       "    re-exports: [ /System/Library/Frameworks/A.framework/A ]\n"
1091       "    symbols: [ _sym5 ]\n"
1092       "    objc-classes: [ class3 ]\n"
1093       "    objc-ivars: [ class1._ivar3 ]\n"
1094       "    weak-def-symbols: [ _weak3 ]\n"
1095       "  - archs: [ x86_64 ]\n"
1096       "    symbols: [ _symAB ]\n"
1097       "undefineds:\n"
1098       "  - archs: [ i386 ]\n"
1099       "    symbols: [ _symC ]\n"
1100       "...\n";
1101 
1102   Expected<TBDFile> ResultA =
1103       TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd"));
1104   EXPECT_TRUE(!!ResultA);
1105   InterfaceFile FileA = std::move(*ResultA.get());
1106   Expected<TBDFile> ResultB =
1107       TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd"));
1108   EXPECT_TRUE(!!ResultB);
1109   InterfaceFile FileB = std::move(*ResultB.get());
1110   EXPECT_NE(FileA.uuids(), FileB.uuids());
1111   EXPECT_TRUE(FileA == FileB);
1112 }
1113 
1114 TEST(TBDv4, InterfaceInequality) {
1115   static const char TBDv4File[] = "--- !tapi-tbd\n"
1116                                   "tbd-version: 4\n"
1117                                   "targets:  [ i386-macos, x86_64-macos ]\n"
1118                                   "install-name: Umbrella.framework/Umbrella\n"
1119                                   "...\n";
1120 
1121   Expected<TBDFile> ResultA =
1122       TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestA.tbd"));
1123   EXPECT_TRUE(!!ResultA);
1124   InterfaceFile FileA = std::move(*ResultA.get());
1125   Expected<TBDFile> ResultB =
1126       TextAPIReader::get(MemoryBufferRef(TBDv4File, "TestB.tbd"));
1127   EXPECT_TRUE(!!ResultB);
1128   InterfaceFile FileB = std::move(*ResultB.get());
1129 
1130   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1131     File->addTarget(Target(AK_x86_64, PLATFORM_IOS));
1132   }));
1133   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1134     File->setCurrentVersion(PackedVersion(1, 2, 3));
1135     File->setCompatibilityVersion(PackedVersion(1, 0, 0));
1136   }));
1137   EXPECT_TRUE(checkEqualityOnTransform(
1138       FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); }));
1139   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1140     File->setTwoLevelNamespace(false);
1141   }));
1142   EXPECT_TRUE(checkEqualityOnTransform(
1143       FileA, FileB, [](InterfaceFile *File) { File->setInstallAPI(true); }));
1144   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1145     File->setApplicationExtensionSafe(false);
1146   }));
1147   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1148     File->addParentUmbrella(Target(AK_x86_64, PLATFORM_MACOS), "System.dylib");
1149   }));
1150   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1151     File->addAllowableClient("ClientA", Target(AK_i386, PLATFORM_MACOS));
1152   }));
1153   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1154     File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
1155                                Target(AK_i386, PLATFORM_MACOS));
1156   }));
1157   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1158     File->addSymbol(SymbolKind::GlobalSymbol, "_symA",
1159                     {Target(AK_x86_64, PLATFORM_MACOS)});
1160   }));
1161   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
1162     InterfaceFile Document;
1163     Document.addTargets(TargetList{Target(AK_i386, PLATFORM_MACOS),
1164                                    Target(AK_x86_64, PLATFORM_MACOS)});
1165     Document.setInstallName("/System/Library/Frameworks/A.framework/A");
1166     File->addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
1167   }));
1168 }
1169 
1170 } // end namespace TBDv4
1171