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