1 //===-- TextStubV3Tests.cpp - TBD V3 File Test ----------------------------===//
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
7 //===-----------------------------------------------------------------------===/
8 #include "TextStubHelpers.h"
9 #include "llvm/TextAPI/InterfaceFile.h"
10 #include "llvm/TextAPI/TextAPIReader.h"
11 #include "llvm/TextAPI/TextAPIWriter.h"
12 #include "gtest/gtest.h"
17 using namespace llvm::MachO
;
19 static ExportedSymbol TBDv3Symbols
[] = {
20 {SymbolKind::GlobalSymbol
, "$ld$hide$os9.0$_sym1", false, false},
21 {SymbolKind::GlobalSymbol
, "_sym1", false, false},
22 {SymbolKind::GlobalSymbol
, "_sym2", false, false},
23 {SymbolKind::GlobalSymbol
, "_sym3", false, false},
24 {SymbolKind::GlobalSymbol
, "_sym4", false, false},
25 {SymbolKind::GlobalSymbol
, "_sym5", false, false},
26 {SymbolKind::GlobalSymbol
, "_tlv1", false, true},
27 {SymbolKind::GlobalSymbol
, "_tlv3", false, true},
28 {SymbolKind::GlobalSymbol
, "_weak1", true, false},
29 {SymbolKind::GlobalSymbol
, "_weak2", true, false},
30 {SymbolKind::GlobalSymbol
, "_weak3", true, false},
31 {SymbolKind::ObjectiveCClass
, "class1", false, false},
32 {SymbolKind::ObjectiveCClass
, "class2", false, false},
33 {SymbolKind::ObjectiveCClass
, "class3", false, false},
34 {SymbolKind::ObjectiveCClassEHType
, "class1", false, false},
35 {SymbolKind::ObjectiveCInstanceVariable
, "class1._ivar1", false, false},
36 {SymbolKind::ObjectiveCInstanceVariable
, "class1._ivar2", false, false},
37 {SymbolKind::ObjectiveCInstanceVariable
, "class1._ivar3", false, false},
42 TEST(TBDv3
, ReadFile
) {
43 static const char TBDv3File1
[] =
45 "archs: [ armv7, arm64 ]\n"
46 "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
47 " 'arm64: 11111111-1111-1111-1111-111111111111']\n"
49 "flags: [ installapi ]\n"
50 "install-name: Test.dylib\n"
51 "current-version: 2.3.4\n"
52 "compatibility-version: 1.0\n"
53 "swift-abi-version: 1.1\n"
54 "parent-umbrella: Umbrella.dylib\n"
56 " - archs: [ armv7, arm64 ]\n"
57 " allowable-clients: [ clientA ]\n"
58 " re-exports: [ /usr/lib/libfoo.dylib ]\n"
59 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
60 " objc-classes: [ class1, class2 ]\n"
61 " objc-eh-types: [ class1 ]\n"
62 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
63 " weak-def-symbols: [ _weak1, _weak2 ]\n"
64 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"
65 " - archs: [ armv7 ]\n"
66 " symbols: [ _sym5 ]\n"
67 " objc-classes: [ class3 ]\n"
68 " objc-ivars: [ class1._ivar3 ]\n"
69 " weak-def-symbols: [ _weak3 ]\n"
70 " thread-local-symbols: [ _tlv3 ]\n"
73 Expected
<TBDFile
> Result
=
74 TextAPIReader::get(MemoryBufferRef(TBDv3File1
, "Test.tbd"));
75 EXPECT_TRUE(!!Result
);
76 TBDFile File
= std::move(Result
.get());
77 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
78 auto Archs
= AK_armv7
| AK_arm64
;
79 auto Platform
= PLATFORM_IOS
;
81 for (auto &&arch
: Archs
)
82 Targets
.emplace_back(Target(arch
, Platform
));
83 EXPECT_EQ(Archs
, File
->getArchitectures());
84 TargetToAttr Uuids
= {{Target(AK_armv7
, PLATFORM_UNKNOWN
),
85 "00000000-0000-0000-0000-000000000000"},
86 {Target(AK_arm64
, PLATFORM_UNKNOWN
),
87 "11111111-1111-1111-1111-111111111111"}};
88 EXPECT_EQ(File
->getPlatforms().size(), 1U);
89 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
90 EXPECT_EQ(std::string("Test.dylib"), File
->getInstallName());
91 EXPECT_EQ(PackedVersion(2, 3, 4), File
->getCurrentVersion());
92 EXPECT_EQ(PackedVersion(1, 0, 0), File
->getCompatibilityVersion());
93 EXPECT_EQ(2U, File
->getSwiftABIVersion());
94 EXPECT_EQ(ObjCConstraintType::Retain_Release
, File
->getObjCConstraint());
95 EXPECT_TRUE(File
->isTwoLevelNamespace());
96 EXPECT_TRUE(File
->isApplicationExtensionSafe());
97 InterfaceFileRef
client("clientA", Targets
);
98 InterfaceFileRef
reexport("/usr/lib/libfoo.dylib", Targets
);
99 EXPECT_EQ(1U, File
->allowableClients().size());
100 EXPECT_EQ(client
, File
->allowableClients().front());
101 EXPECT_EQ(1U, File
->reexportedLibraries().size());
102 EXPECT_EQ(reexport
, File
->reexportedLibraries().front());
104 ExportedSymbolSeq Exports
;
105 for (const auto *Sym
: File
->symbols()) {
106 EXPECT_FALSE(Sym
->isWeakReferenced());
107 EXPECT_FALSE(Sym
->isUndefined());
108 Exports
.emplace_back(
109 ExportedSymbol
{Sym
->getKind(), std::string(Sym
->getName()),
110 Sym
->isWeakDefined(), Sym
->isThreadLocalValue()});
114 EXPECT_EQ(std::size(TBDv3Symbols
), Exports
.size());
116 std::equal(Exports
.begin(), Exports
.end(), std::begin(TBDv3Symbols
)));
119 TEST(TBDv3
, ReadMultipleDocuments
) {
120 static const char TBDv3Inlines
[] =
122 "archs: [ armv7, arm64 ]\n"
124 "install-name: Test.dylib\n"
125 "current-version: 2.3.4\n"
126 "compatibility-version: 1.0\n"
127 "swift-abi-version: 1.1\n"
128 "parent-umbrella: Umbrella.dylib\n"
130 " - archs: [ armv7, arm64 ]\n"
131 " allowable-clients: [ clientA ]\n"
132 " re-exports: [ /usr/lib/libfoo.dylib,\n"
133 " TestInline.dylib ]\n"
134 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
135 " objc-classes: [ class1, class2 ]\n"
136 " objc-eh-types: [ class1 ]\n"
137 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
138 " weak-def-symbols: [ _weak1, _weak2 ]\n"
139 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"
140 " - archs: [ armv7 ]\n"
141 " symbols: [ _sym5 ]\n"
142 " objc-classes: [ class3 ]\n"
143 " objc-ivars: [ class1._ivar3 ]\n"
144 " weak-def-symbols: [ _weak3 ]\n"
145 " thread-local-symbols: [ _tlv3 ]\n"
147 "archs: [ armv7, arm64 ]\n"
149 "install-name: TestInline.dylib\n"
150 "swift-abi-version: 1.1\n"
152 " - archs: [ armv7, arm64 ]\n"
153 " symbols: [ _sym5, _sym6 ]\n"
156 Expected
<TBDFile
> Result
=
157 TextAPIReader::get(MemoryBufferRef(TBDv3Inlines
, "Test.tbd"));
158 EXPECT_TRUE(!!Result
);
159 TBDFile File
= std::move(Result
.get());
160 EXPECT_EQ(File
->documents().size(), 1U);
161 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
162 auto Archs
= AK_armv7
| AK_arm64
;
163 auto Platform
= PLATFORM_IOS
;
165 for (auto &&arch
: Archs
)
166 Targets
.emplace_back(Target(arch
, Platform
));
167 EXPECT_EQ(Archs
, File
->getArchitectures());
168 TargetToAttr Uuids
= {{Target(AK_armv7
, PLATFORM_UNKNOWN
),
169 "00000000-0000-0000-0000-000000000000"},
170 {Target(AK_arm64
, PLATFORM_UNKNOWN
),
171 "11111111-1111-1111-1111-111111111111"}};
172 EXPECT_EQ(File
->getPlatforms().size(), 1U);
173 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
174 EXPECT_EQ(std::string("Test.dylib"), File
->getInstallName());
175 EXPECT_EQ(PackedVersion(2, 3, 4), File
->getCurrentVersion());
176 EXPECT_EQ(PackedVersion(1, 0, 0), File
->getCompatibilityVersion());
177 EXPECT_EQ(2U, File
->getSwiftABIVersion());
178 EXPECT_EQ(ObjCConstraintType::Retain_Release
, File
->getObjCConstraint());
179 EXPECT_TRUE(File
->isTwoLevelNamespace());
180 EXPECT_TRUE(File
->isApplicationExtensionSafe());
181 InterfaceFileRef
Client("clientA", Targets
);
182 const std::vector
<InterfaceFileRef
> Reexports
= {
183 InterfaceFileRef("/usr/lib/libfoo.dylib", Targets
),
184 InterfaceFileRef("TestInline.dylib", Targets
)};
185 EXPECT_EQ(1U, File
->allowableClients().size());
186 EXPECT_EQ(Client
, File
->allowableClients().front());
187 EXPECT_EQ(2U, File
->reexportedLibraries().size());
188 EXPECT_EQ(Reexports
, File
->reexportedLibraries());
190 ExportedSymbolSeq Exports
;
191 for (const auto *Sym
: File
->symbols()) {
192 EXPECT_FALSE(Sym
->isWeakReferenced());
193 EXPECT_FALSE(Sym
->isUndefined());
194 Exports
.emplace_back(ExportedSymbol
{Sym
->getKind(), Sym
->getName().str(),
195 Sym
->isWeakDefined(),
196 Sym
->isThreadLocalValue()});
200 EXPECT_EQ(std::size(TBDv3Symbols
), Exports
.size());
202 std::equal(Exports
.begin(), Exports
.end(), std::begin(TBDv3Symbols
)));
204 // Check Second Document
206 TBDReexportFile Document
= File
->documents().front();
207 EXPECT_EQ(FileType::TBD_V3
, Document
->getFileType());
208 EXPECT_EQ(Archs
, Document
->getArchitectures());
209 EXPECT_EQ(Platform
, *Document
->getPlatforms().begin());
210 EXPECT_EQ(std::string("TestInline.dylib"), Document
->getInstallName());
211 EXPECT_EQ(PackedVersion(1, 0, 0), Document
->getCurrentVersion());
212 EXPECT_EQ(PackedVersion(1, 0, 0), Document
->getCompatibilityVersion());
213 EXPECT_EQ(2U, Document
->getSwiftABIVersion());
215 for (const auto *Sym
: Document
->symbols()) {
216 EXPECT_FALSE(Sym
->isWeakReferenced());
217 EXPECT_FALSE(Sym
->isUndefined());
218 Exports
.emplace_back(ExportedSymbol
{Sym
->getKind(), Sym
->getName().str(),
219 Sym
->isWeakDefined(),
220 Sym
->isThreadLocalValue()});
224 ExportedSymbolSeq DocumentSymbols
{
225 {SymbolKind::GlobalSymbol
, "_sym5", false, false},
226 {SymbolKind::GlobalSymbol
, "_sym6", false, false},
229 EXPECT_EQ(DocumentSymbols
.size(), Exports
.size());
231 std::equal(Exports
.begin(), Exports
.end(), DocumentSymbols
.begin()));
234 TEST(TBDv3
, WriteFile
) {
235 static const char TBDv3File3
[] =
237 "archs: [ i386, x86_64 ]\n"
239 "install-name: '/usr/lib/libfoo.dylib'\n"
240 "current-version: 1.2.3\n"
241 "compatibility-version: 0\n"
242 "swift-abi-version: 5\n"
244 " - archs: [ i386 ]\n"
245 " symbols: [ _sym1 ]\n"
246 " weak-def-symbols: [ _sym2 ]\n"
247 " thread-local-symbols: [ _sym3 ]\n"
248 " - archs: [ x86_64 ]\n"
249 " allowable-clients: [ clientA ]\n"
250 " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"
251 " objc-classes: [ Class1 ]\n"
252 " objc-eh-types: [ Class1 ]\n"
253 " objc-ivars: [ Class1._ivar1 ]\n"
258 for (auto &&arch
: AK_i386
| AK_x86_64
)
259 Targets
.emplace_back(Target(arch
, PLATFORM_MACOS
));
260 File
.setPath("libfoo.dylib");
261 File
.setInstallName("/usr/lib/libfoo.dylib");
262 File
.setFileType(FileType::TBD_V3
);
263 File
.addTargets(Targets
);
264 File
.setCurrentVersion(PackedVersion(1, 2, 3));
265 File
.setTwoLevelNamespace();
266 File
.setApplicationExtensionSafe();
267 File
.setSwiftABIVersion(5);
268 File
.setObjCConstraint(ObjCConstraintType::Retain_Release
);
269 File
.addAllowableClient("clientA", Targets
[1]);
270 File
.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets
[1]);
271 File
.addSymbol(SymbolKind::GlobalSymbol
, "_sym1", {Targets
[0]});
272 File
.addSymbol(SymbolKind::GlobalSymbol
, "_sym2", {Targets
[0]},
273 SymbolFlags::WeakDefined
);
274 File
.addSymbol(SymbolKind::GlobalSymbol
, "_sym3", {Targets
[0]},
275 SymbolFlags::ThreadLocalValue
);
276 File
.addSymbol(SymbolKind::ObjectiveCClass
, "Class1", {Targets
[1]});
277 File
.addSymbol(SymbolKind::ObjectiveCClassEHType
, "Class1", {Targets
[1]});
278 File
.addSymbol(SymbolKind::ObjectiveCInstanceVariable
, "Class1._ivar1",
281 SmallString
<4096> Buffer
;
282 raw_svector_ostream
OS(Buffer
);
283 Error Result
= TextAPIWriter::writeToStream(OS
, File
);
284 EXPECT_FALSE(Result
);
285 EXPECT_STREQ(TBDv3File3
, Buffer
.c_str());
288 TEST(TBDv3
, WriteMultipleDocuments
) {
289 static const char TBDv3Inlines
[] =
291 "archs: [ i386, x86_64 ]\n"
292 "platform: zippered\n"
293 "install-name: '/usr/lib/libfoo.dylib'\n"
294 "current-version: 1.2.3\n"
295 "compatibility-version: 0\n"
296 "swift-abi-version: 5\n"
298 " - archs: [ x86_64 ]\n"
299 " allowable-clients: [ clientA ]\n"
300 " re-exports: [ '/usr/lib/libbar.dylib' ]\n"
301 " - archs: [ i386, x86_64 ]\n"
302 " symbols: [ _sym1 ]\n"
303 " objc-classes: [ Class1 ]\n"
304 " objc-eh-types: [ Class1 ]\n"
305 " objc-ivars: [ Class1._ivar1 ]\n"
306 " weak-def-symbols: [ _sym2 ]\n"
307 " thread-local-symbols: [ _symA ]\n"
311 "install-name: '/usr/lib/libbar.dylib'\n"
312 "current-version: 0\n"
313 "compatibility-version: 0\n"
314 "swift-abi-version: 5\n"
315 "objc-constraint: none\n"
317 " - archs: [ i386 ]\n"
318 " symbols: [ _sym3, _sym4 ]\n"
323 for (auto &&arch
: AK_i386
| AK_x86_64
) {
324 Targets
.emplace_back(Target(arch
, PLATFORM_MACOS
));
325 Targets
.emplace_back(Target(arch
, PLATFORM_MACCATALYST
));
327 File
.addTargets(Targets
);
328 File
.setPath("libfoo.dylib");
329 File
.setInstallName("/usr/lib/libfoo.dylib");
330 File
.setFileType(FileType::TBD_V3
);
331 File
.setCurrentVersion(PackedVersion(1, 2, 3));
332 File
.setTwoLevelNamespace();
333 File
.setApplicationExtensionSafe();
334 File
.setSwiftABIVersion(5);
335 File
.setObjCConstraint(ObjCConstraintType::Retain_Release
);
336 File
.addAllowableClient("clientA", Targets
[2]);
337 File
.addReexportedLibrary("/usr/lib/libbar.dylib", Targets
[2]);
338 File
.addSymbol(SymbolKind::GlobalSymbol
, "_sym1", Targets
);
339 File
.addSymbol(SymbolKind::GlobalSymbol
, "_sym2", Targets
,
340 SymbolFlags::WeakDefined
);
341 File
.addSymbol(SymbolKind::GlobalSymbol
, "_symA", Targets
,
342 SymbolFlags::ThreadLocalValue
);
343 File
.addSymbol(SymbolKind::ObjectiveCClass
, "Class1", Targets
);
344 File
.addSymbol(SymbolKind::ObjectiveCClassEHType
, "Class1", Targets
);
345 File
.addSymbol(SymbolKind::ObjectiveCInstanceVariable
, "Class1._ivar1",
349 InterfaceFile Document
;
350 Targets
= {Target(AK_i386
, PLATFORM_MACOS
)};
351 Document
.addTargets(Targets
);
352 Document
.setPath("libbar.dylib");
353 Document
.setInstallName("/usr/lib/libbar.dylib");
354 Document
.setFileType(FileType::TBD_V3
);
355 Document
.setTwoLevelNamespace();
356 Document
.setApplicationExtensionSafe();
357 Document
.setSwiftABIVersion(5);
358 Document
.addSymbol(SymbolKind::GlobalSymbol
, "_sym3", Targets
);
359 Document
.addSymbol(SymbolKind::GlobalSymbol
, "_sym4", Targets
);
360 File
.addDocument(std::make_shared
<InterfaceFile
>(std::move(Document
)));
362 SmallString
<4096> Buffer
;
363 raw_svector_ostream
OS(Buffer
);
364 Error Result
= TextAPIWriter::writeToStream(OS
, File
);
365 EXPECT_FALSE(Result
);
366 EXPECT_STREQ(TBDv3Inlines
, Buffer
.c_str());
369 TEST(TBDv3
, Platform_macOS
) {
370 static const char TBDv3PlatformMacOS
[] = "--- !tapi-tbd-v3\n"
371 "archs: [ x86_64 ]\n"
373 "install-name: Test.dylib\n"
376 Expected
<TBDFile
> Result
=
377 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformMacOS
, "Test.tbd"));
378 EXPECT_TRUE(!!Result
);
379 auto Platform
= PLATFORM_MACOS
;
380 TBDFile File
= std::move(Result
.get());
381 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
382 EXPECT_EQ(File
->getPlatforms().size(), 1U);
383 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
385 SmallString
<4096> Buffer
;
386 raw_svector_ostream
OS(Buffer
);
387 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
388 EXPECT_TRUE(!WriteResult
);
389 EXPECT_EQ(stripWhitespace(TBDv3PlatformMacOS
),
390 stripWhitespace(Buffer
.c_str()));
393 TEST(TBDv3
, Platform_iOS
) {
394 static const char TBDv3PlatformiOS
[] = "--- !tapi-tbd-v3\n"
397 "install-name: Test.dylib\n"
400 Expected
<TBDFile
> Result
=
401 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOS
, "Test.tbd"));
402 EXPECT_TRUE(!!Result
);
403 auto Platform
= PLATFORM_IOS
;
404 TBDFile File
= std::move(Result
.get());
405 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
406 EXPECT_EQ(File
->getPlatforms().size(), 1U);
407 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
409 SmallString
<4096> Buffer
;
410 raw_svector_ostream
OS(Buffer
);
411 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
412 EXPECT_TRUE(!WriteResult
);
413 EXPECT_EQ(stripWhitespace(TBDv3PlatformiOS
), stripWhitespace(Buffer
.c_str()));
416 TEST(TBDv3
, Platform_watchOS
) {
417 static const char TBDv3watchOS
[] = "--- !tapi-tbd-v3\n"
418 "archs: [ armv7k ]\n"
419 "platform: watchos\n"
420 "install-name: Test.dylib\n"
423 Expected
<TBDFile
> Result
=
424 TextAPIReader::get(MemoryBufferRef(TBDv3watchOS
, "Test.tbd"));
425 EXPECT_TRUE(!!Result
);
426 auto Platform
= PLATFORM_WATCHOS
;
427 TBDFile File
= std::move(Result
.get());
428 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
429 EXPECT_EQ(File
->getPlatforms().size(), 1U);
430 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
432 SmallString
<4096> Buffer
;
433 raw_svector_ostream
OS(Buffer
);
434 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
435 EXPECT_TRUE(!WriteResult
);
436 EXPECT_EQ(stripWhitespace(TBDv3watchOS
), stripWhitespace(Buffer
.c_str()));
439 TEST(TBDv3
, Platform_tvOS
) {
440 static const char TBDv3PlatformtvOS
[] = "--- !tapi-tbd-v3\n"
443 "install-name: Test.dylib\n"
446 Expected
<TBDFile
> Result
=
447 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOS
, "Test.tbd"));
448 EXPECT_TRUE(!!Result
);
449 TBDFile File
= std::move(Result
.get());
450 auto Platform
= PLATFORM_TVOS
;
451 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
452 EXPECT_EQ(File
->getPlatforms().size(), 1U);
453 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
455 SmallString
<4096> Buffer
;
456 raw_svector_ostream
OS(Buffer
);
457 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
458 EXPECT_FALSE(WriteResult
);
459 EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOS
),
460 stripWhitespace(Buffer
.c_str()));
463 TEST(TBDv3
, Platform_bridgeOS
) {
464 static const char TBDv3BridgeOS
[] = "--- !tapi-tbd-v3\n"
465 "archs: [ armv7k ]\n"
466 "platform: bridgeos\n"
467 "install-name: Test.dylib\n"
470 Expected
<TBDFile
> Result
=
471 TextAPIReader::get(MemoryBufferRef(TBDv3BridgeOS
, "Test.tbd"));
472 EXPECT_TRUE(!!Result
);
473 auto Platform
= PLATFORM_BRIDGEOS
;
474 TBDFile File
= std::move(Result
.get());
475 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
476 EXPECT_EQ(File
->getPlatforms().size(), 1U);
477 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
479 SmallString
<4096> Buffer
;
480 raw_svector_ostream
OS(Buffer
);
481 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
482 EXPECT_TRUE(!WriteResult
);
483 EXPECT_EQ(stripWhitespace(TBDv3BridgeOS
), stripWhitespace(Buffer
.c_str()));
486 TEST(TBDv3
, Platform_macCatalyst
) {
487 static const char TBDv3PlatformiOSmac
[] = "--- !tapi-tbd-v3\n"
488 "archs: [ armv7k ]\n"
489 "platform: maccatalyst\n"
490 "install-name: Test.dylib\n"
493 Expected
<TBDFile
> Result
=
494 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSmac
, "Test.tbd"));
495 EXPECT_TRUE(!!Result
);
496 auto Platform
= PLATFORM_MACCATALYST
;
497 TBDFile File
= std::move(Result
.get());
498 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
499 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
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(TBDv3PlatformiOSmac
),
506 stripWhitespace(Buffer
.c_str()));
509 TEST(TBDv3
, Platform_zippered
) {
510 static const char TBDv3PlatformZippered
[] = "--- !tapi-tbd-v3\n"
511 "archs: [ armv7k ]\n"
512 "platform: zippered\n"
513 "install-name: Test.dylib\n"
516 Expected
<TBDFile
> Result
=
517 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformZippered
, "Test.tbd"));
518 EXPECT_TRUE(!!Result
);
519 TBDFile File
= std::move(Result
.get());
520 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
522 PlatformSet Platforms
;
523 Platforms
.insert(PLATFORM_MACOS
);
524 Platforms
.insert(PLATFORM_MACCATALYST
);
525 EXPECT_EQ(Platforms
.size(), File
->getPlatforms().size());
526 for (auto Platform
: File
->getPlatforms())
527 EXPECT_EQ(Platforms
.count(Platform
), 1U);
529 SmallString
<4096> Buffer
;
530 raw_svector_ostream
OS(Buffer
);
531 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
532 EXPECT_TRUE(!WriteResult
);
533 EXPECT_EQ(stripWhitespace(TBDv3PlatformZippered
),
534 stripWhitespace(Buffer
.c_str()));
537 TEST(TBDv3
, Platform_iOSSim
) {
538 static const char TBDv3PlatformiOSsim
[] = "--- !tapi-tbd-v3\n"
539 "archs: [ x86_64 ]\n"
541 "install-name: Test.dylib\n"
544 Expected
<TBDFile
> Result
=
545 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSsim
, "Test.tbd"));
546 EXPECT_TRUE(!!Result
);
547 auto Platform
= PLATFORM_IOSSIMULATOR
;
548 TBDFile File
= std::move(Result
.get());
549 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
550 EXPECT_EQ(File
->getPlatforms().size(), 1U);
551 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
553 SmallString
<4096> Buffer
;
554 raw_svector_ostream
OS(Buffer
);
555 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
556 EXPECT_TRUE(!WriteResult
);
557 EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSsim
),
558 stripWhitespace(Buffer
.c_str()));
561 TEST(TBDv3
, Platform_watchOSSim
) {
562 static const char TBDv3watchOSsim
[] = "--- !tapi-tbd-v3\n"
563 "archs: [ x86_64 ]\n"
564 "platform: watchos\n"
565 "install-name: Test.dylib\n"
568 Expected
<TBDFile
> Result
=
569 TextAPIReader::get(MemoryBufferRef(TBDv3watchOSsim
, "Test.tbd"));
570 EXPECT_TRUE(!!Result
);
571 auto Platform
= PLATFORM_WATCHOSSIMULATOR
;
572 TBDFile File
= std::move(Result
.get());
573 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
574 EXPECT_EQ(File
->getPlatforms().size(), 1U);
575 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
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(TBDv3watchOSsim
), stripWhitespace(Buffer
.c_str()));
584 TEST(TBDv3
, Platform_tvOSSim
) {
585 static const char TBDv3PlatformtvOSsim
[] = "--- !tapi-tbd-v3\n"
586 "archs: [ x86_64 ]\n"
588 "install-name: Test.dylib\n"
591 Expected
<TBDFile
> Result
=
592 TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOSsim
, "Test.tbd"));
593 EXPECT_TRUE(!!Result
);
594 TBDFile File
= std::move(Result
.get());
595 auto Platform
= PLATFORM_TVOSSIMULATOR
;
596 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
597 EXPECT_EQ(File
->getPlatforms().size(), 1U);
598 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
600 SmallString
<4096> Buffer
;
601 raw_svector_ostream
OS(Buffer
);
602 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
603 EXPECT_TRUE(!WriteResult
);
604 EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOSsim
),
605 stripWhitespace(Buffer
.c_str()));
608 TEST(TBDv3
, Arch_arm64e
) {
609 static const char TBDv3ArchArm64e
[] = "--- !tapi-tbd-v3\n"
610 "archs: [ arm64, arm64e ]\n"
612 "install-name: Test.dylib\n"
615 Expected
<TBDFile
> Result
=
616 TextAPIReader::get(MemoryBufferRef(TBDv3ArchArm64e
, "Test.tbd"));
617 EXPECT_TRUE(!!Result
);
618 TBDFile File
= std::move(Result
.get());
619 auto Platform
= PLATFORM_IOS
;
620 auto Archs
= AK_arm64
| AK_arm64e
;
621 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
622 EXPECT_EQ(File
->getPlatforms().size(), 1U);
623 EXPECT_EQ(Platform
, *File
->getPlatforms().begin());
624 EXPECT_EQ(Archs
, File
->getArchitectures());
626 SmallString
<4096> Buffer
;
627 raw_svector_ostream
OS(Buffer
);
628 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
629 EXPECT_TRUE(!WriteResult
);
630 EXPECT_EQ(stripWhitespace(TBDv3ArchArm64e
), stripWhitespace(Buffer
.c_str()));
633 TEST(TBDv3
, Swift_1_0
) {
634 static const char TBDv3Swift1
[] = "--- !tapi-tbd-v3\n"
637 "install-name: Test.dylib\n"
638 "swift-abi-version: 1.0\n"
641 Expected
<TBDFile
> Result
=
642 TextAPIReader::get(MemoryBufferRef(TBDv3Swift1
, "Test.tbd"));
643 EXPECT_TRUE(!!Result
);
644 TBDFile File
= std::move(Result
.get());
645 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
646 EXPECT_EQ(1U, File
->getSwiftABIVersion());
648 SmallString
<4096> Buffer
;
649 raw_svector_ostream
OS(Buffer
);
650 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
651 EXPECT_TRUE(!WriteResult
);
652 EXPECT_EQ(stripWhitespace(TBDv3Swift1
), stripWhitespace(Buffer
.c_str()));
655 TEST(TBDv3
, Swift_1_1
) {
656 static const char TBDv3Swift1Dot
[] = "--- !tapi-tbd-v3\n"
659 "install-name: Test.dylib\n"
660 "swift-abi-version: 1.1\n"
663 Expected
<TBDFile
> Result
=
664 TextAPIReader::get(MemoryBufferRef(TBDv3Swift1Dot
, "Test.tbd"));
665 EXPECT_TRUE(!!Result
);
666 TBDFile File
= std::move(Result
.get());
667 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
668 EXPECT_EQ(2U, File
->getSwiftABIVersion());
670 SmallString
<4096> Buffer
;
671 raw_svector_ostream
OS(Buffer
);
672 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
673 EXPECT_TRUE(!WriteResult
);
674 EXPECT_EQ(stripWhitespace(TBDv3Swift1Dot
), stripWhitespace(Buffer
.c_str()));
677 TEST(TBDv3
, Swift_2_0
) {
678 static const char TBDv3Swift2
[] = "--- !tapi-tbd-v3\n"
681 "install-name: Test.dylib\n"
682 "swift-abi-version: 2.0\n"
685 Expected
<TBDFile
> Result
=
686 TextAPIReader::get(MemoryBufferRef(TBDv3Swift2
, "Test.tbd"));
687 EXPECT_TRUE(!!Result
);
688 TBDFile File
= std::move(Result
.get());
689 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
690 EXPECT_EQ(3U, File
->getSwiftABIVersion());
692 SmallString
<4096> Buffer
;
693 raw_svector_ostream
OS(Buffer
);
694 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
695 EXPECT_TRUE(!WriteResult
);
696 EXPECT_EQ(stripWhitespace(TBDv3Swift2
), stripWhitespace(Buffer
.c_str()));
699 TEST(TBDv3
, Swift_3_0
) {
700 static const char TBDv3Swift3
[] = "--- !tapi-tbd-v3\n"
703 "install-name: Test.dylib\n"
704 "swift-abi-version: 3.0\n"
707 Expected
<TBDFile
> Result
=
708 TextAPIReader::get(MemoryBufferRef(TBDv3Swift3
, "Test.tbd"));
709 EXPECT_TRUE(!!Result
);
710 TBDFile File
= std::move(Result
.get());
711 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
712 EXPECT_EQ(4U, File
->getSwiftABIVersion());
714 SmallString
<4096> Buffer
;
715 raw_svector_ostream
OS(Buffer
);
716 Error WriteResult
= TextAPIWriter::writeToStream(OS
, *File
);
717 EXPECT_TRUE(!WriteResult
);
718 EXPECT_EQ(stripWhitespace(TBDv3Swift3
), stripWhitespace(Buffer
.c_str()));
721 TEST(TBDv3
, Swift_4_0
) {
722 static const char TBDv3Swift4
[] = "--- !tapi-tbd-v3\n"
725 "install-name: Test.dylib\n"
726 "swift-abi-version: 4.0\n"
729 Expected
<TBDFile
> Result
=
730 TextAPIReader::get(MemoryBufferRef(TBDv3Swift4
, "Test.tbd"));
731 EXPECT_FALSE(!!Result
);
732 std::string ErrorMessage
= toString(Result
.takeError());
733 EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
734 "version.\nswift-abi-version: 4.0\n ^~~\n",
738 TEST(TBDv3
, Swift_5
) {
739 static const char TBDv3Swift5
[] = "--- !tapi-tbd-v3\n"
742 "install-name: Test.dylib\n"
743 "swift-abi-version: 5\n"
746 Expected
<TBDFile
> Result
=
747 TextAPIReader::get(MemoryBufferRef(TBDv3Swift5
, "Test.tbd"));
748 EXPECT_TRUE(!!Result
);
749 TBDFile File
= std::move(Result
.get());
750 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
751 EXPECT_EQ(5U, File
->getSwiftABIVersion());
754 TEST(TBDv3
, Swift_99
) {
755 static const char TBDv3Swift99
[] = "--- !tapi-tbd-v3\n"
758 "install-name: Test.dylib\n"
759 "swift-abi-version: 99\n"
762 Expected
<TBDFile
> Result
=
763 TextAPIReader::get(MemoryBufferRef(TBDv3Swift99
, "Test.tbd"));
764 EXPECT_TRUE(!!Result
);
765 TBDFile File
= std::move(Result
.get());
766 EXPECT_EQ(FileType::TBD_V3
, File
->getFileType());
767 EXPECT_EQ(99U, File
->getSwiftABIVersion());
770 TEST(TBDv3
, UnknownArchitecture
) {
771 static const char TBDv3FileUnknownArch
[] = "--- !tapi-tbd-v3\n"
774 "install-name: Test.dylib\n"
777 Expected
<TBDFile
> Result
=
778 TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownArch
, "Test.tbd"));
779 EXPECT_TRUE(!!Result
);
782 TEST(TBDv3
, UnknownPlatform
) {
783 static const char TBDv3FileUnknownPlatform
[] = "--- !tapi-tbd-v3\n"
788 Expected
<TBDFile
> Result
=
789 TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownPlatform
, "Test.tbd"));
790 EXPECT_FALSE(!!Result
);
791 std::string ErrorMessage
= toString(Result
.takeError());
792 EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
797 TEST(TBDv3
, MalformedFile1
) {
798 static const char TBDv3FileMalformed1
[] = "--- !tapi-tbd-v3\n"
800 "foobar: \"Unsupported key\"\n"
803 Expected
<TBDFile
> Result
=
804 TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed1
, "Test.tbd"));
805 EXPECT_FALSE(!!Result
);
806 std::string ErrorMessage
= toString(Result
.takeError());
807 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
808 "'platform'\narchs: [ arm64 ]\n^\n",
812 TEST(TBDv3
, MalformedFile2
) {
813 static const char TBDv3FileMalformed2
[] = "--- !tapi-tbd-v3\n"
816 "install-name: Test.dylib\n"
817 "foobar: \"Unsupported key\"\n"
820 Expected
<TBDFile
> Result
=
821 TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed2
, "Test.tbd"));
822 EXPECT_FALSE(!!Result
);
823 std::string ErrorMessage
= toString(Result
.takeError());
825 "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: "
826 "\"Unsupported key\"\n^~~~~~\n",
830 TEST(TBDv3
, InterfaceEquality
) {
831 static const char TBDv3File
[] =
833 "archs: [ armv7, arm64 ]\n"
834 "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
835 " 'arm64: 11111111-1111-1111-1111-111111111111']\n"
837 "flags: [ installapi ]\n"
838 "install-name: Test.dylib\n"
839 "current-version: 2.3.4\n"
840 "compatibility-version: 1.0\n"
841 "swift-abi-version: 1.1\n"
842 "parent-umbrella: Umbrella.dylib\n"
844 " - archs: [ armv7, arm64 ]\n"
845 " allowable-clients: [ clientA ]\n"
846 " re-exports: [ /usr/lib/libfoo.dylib ]\n"
847 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
848 " objc-classes: [ class1, class2 ]\n"
849 " objc-eh-types: [ class1 ]\n"
850 " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
851 " weak-def-symbols: [ _weak1, _weak2 ]\n"
852 " thread-local-symbols: [ _tlv1, _tlv3 ]\n"
853 " - archs: [ armv7 ]\n"
854 " symbols: [ _sym5 ]\n"
855 " objc-classes: [ class3 ]\n"
856 " objc-ivars: [ class1._ivar3 ]\n"
857 " weak-def-symbols: [ _weak3 ]\n"
858 " thread-local-symbols: [ _tlv3 ]\n"
862 "install-name: '/usr/lib/libbar.dylib'\n"
863 "current-version: 0\n"
864 "compatibility-version: 0\n"
865 "swift-abi-version: 5\n"
866 "objc-constraint: none\n"
868 " - archs: [ i386 ]\n"
869 " symbols: [ _sym3, _sym4 ]\n"
871 Expected
<TBDFile
> ResultA
=
872 TextAPIReader::get(MemoryBufferRef(TBDv3File
, "TestA.tbd"));
873 EXPECT_TRUE(!!ResultA
);
874 InterfaceFile FileA
= std::move(*ResultA
.get());
875 Expected
<TBDFile
> ResultB
=
876 TextAPIReader::get(MemoryBufferRef(TBDv3File
, "TestB.tbd"));
877 EXPECT_TRUE(!!ResultB
);
878 InterfaceFile FileB
= std::move(*ResultB
.get());
879 EXPECT_FALSE(FileA
.getPath() == FileB
.getPath());
880 EXPECT_TRUE(FileA
== FileB
);
885 TEST(TBDv3
, InterfaceInequality
) {
886 static const char TBDv3File
[] = "--- !tapi-tbd-v3\n"
887 "archs: [ armv7, arm64 ]\n"
889 "install-name: Test.dylib\n"
892 Expected
<TBDFile
> ResultA
=
893 TextAPIReader::get(MemoryBufferRef(TBDv3File
, "TestA.tbd"));
894 EXPECT_TRUE(!!ResultA
);
895 InterfaceFile FileA
= std::move(*ResultA
.get());
896 Expected
<TBDFile
> ResultB
=
897 TextAPIReader::get(MemoryBufferRef(TBDv3File
, "TestB.tbd"));
898 EXPECT_TRUE(!!ResultB
);
899 InterfaceFile FileB
= std::move(*ResultB
.get());
901 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
902 File
->addTarget(Target(AK_x86_64
, PLATFORM_IOS
));
904 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
905 File
->setCurrentVersion(PackedVersion(1, 2, 3));
906 File
->setCompatibilityVersion(PackedVersion(1, 0, 0));
908 EXPECT_TRUE(checkEqualityOnTransform(
909 FileA
, FileB
, [](InterfaceFile
*File
) { File
->setSwiftABIVersion(5); }));
910 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
911 File
->setTwoLevelNamespace(false);
913 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
914 File
->setApplicationExtensionSafe(false);
916 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
917 File
->addParentUmbrella(Target(AK_armv7
, PLATFORM_IOS
), "Umbrella.dylib");
919 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
920 File
->addAllowableClient("ClientA", Target(AK_armv7
, PLATFORM_IOS
));
922 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
923 File
->addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
924 Target(AK_armv7
, PLATFORM_IOS
));
926 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
927 File
->addSymbol(SymbolKind::GlobalSymbol
, "_symA",
928 {Target(AK_arm64
, PLATFORM_IOS
)});
930 EXPECT_TRUE(checkEqualityOnTransform(FileA
, FileB
, [](InterfaceFile
*File
) {
931 InterfaceFile Document
;
932 Document
.setFileType(FileType::TBD_V3
);
933 Document
.addTargets(TargetList
{Target(AK_armv7
, PLATFORM_IOS
),
934 Target(AK_arm64
, PLATFORM_IOS
)});
935 Document
.setInstallName("/System/Library/Frameworks/A.framework/A");
936 File
->addDocument(std::make_shared
<InterfaceFile
>(std::move(Document
)));