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