Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / TextAPI / TextStubV5Tests.cpp
blob60976a5f0648186ad3c8771c4330060c153431a7
1 //===-- TextStubV5Tests.cpp - TBD V5 File Test ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===-----------------------------------------------------------------------===/
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>
17 using namespace llvm;
18 using namespace llvm::MachO;
20 namespace TBDv5 {
22 TEST(TBDv5, ReadFile) {
23 static const char TBDv5File[] = R"({
24 "tapi_tbd_version": 5,
25 "main_library": {
26 "target_info": [
28 "target": "x86_64-macos",
29 "min_deployment": "10.14"
32 "target": "arm64-macos",
33 "min_deployment": "10.14"
36 "target": "arm64-maccatalyst",
37 "min_deployment": "12.1"
40 "flags": [
42 "targets": [
43 "x86_64-macos"
45 "attributes": [
46 "flat_namespace"
50 "install_names": [
52 "name": "/S/L/F/Foo.framework/Foo"
55 "current_versions": [
57 "version": "1.2"
60 "compatibility_versions": [
61 { "version": "1.1" }
63 "rpaths": [
65 "targets": [
66 "x86_64-macos"
68 "paths": [
69 "@executable_path/.../Frameworks"
73 "parent_umbrellas": [
75 "umbrella": "System"
78 "allowable_clients": [
80 "clients": [
81 "ClientA",
82 "ClientB"
86 "reexported_libraries": [
88 "names": [
89 "/u/l/l/libfoo.dylib",
90 "/u/l/l/libbar.dylib"
94 "exported_symbols": [
96 "targets": [
97 "x86_64-macos",
98 "arm64-macos"
100 "data": {
101 "global": [
102 "_global"
104 "objc_class": [
105 "ClassA"
107 "weak": [],
108 "thread_local": []
110 "text": {
111 "global": [
112 "_func"
114 "weak": [],
115 "thread_local": []
119 "targets": [
120 "x86_64-macos"
122 "data": {
123 "global": [
124 "_globalVar"
126 "objc_class": [
127 "ClassA",
128 "ClassB",
129 "ClassData"
131 "objc_eh_type": [
132 "ClassA",
133 "ClassB"
135 "objc_ivar": [
136 "ClassA.ivar1",
137 "ClassA.ivar2",
138 "ClassC.ivar1"
141 "text": {
142 "global": [
143 "_funcFoo"
148 "reexported_symbols": [
150 "targets": [
151 "x86_64-macos",
152 "arm64-macos"
154 "data": {
155 "global": [
156 "_globalRe"
158 "objc_class": [
159 "ClassRexport"
162 "text": {
163 "global": [
164 "_funcA"
169 "undefined_symbols": [
171 "targets": [
172 "x86_64-macos"
174 "data": {
175 "global": [
176 "_globalBind"
178 "weak": [
179 "referenced_sym"
185 "libraries": []
186 })";
188 MemoryBufferRef InputBuf = MemoryBufferRef(TBDv5File, "Test.tbd");
189 Expected<FileType> ExpectedFT = TextAPIReader::canRead(InputBuf);
190 EXPECT_TRUE(!!ExpectedFT);
192 Expected<TBDFile> Result = TextAPIReader::get(InputBuf);
193 EXPECT_TRUE(!!Result);
194 TBDFile File = std::move(Result.get());
195 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
196 EXPECT_EQ(*ExpectedFT, File->getFileType());
197 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());
199 TargetList AllTargets = {
200 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
201 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
202 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
204 std::set<Target> FileTargets{File->targets().begin(), File->targets().end()};
205 EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());
206 EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());
207 EXPECT_EQ(FileTargets.size(), AllTargets.size());
208 for (const auto &Targ : AllTargets) {
209 auto FileTarg = FileTargets.find(Targ);
210 EXPECT_FALSE(FileTarg == FileTargets.end());
211 EXPECT_EQ(*FileTarg, Targ);
212 PackedVersion MD = Targ.MinDeployment;
213 PackedVersion FileMD = FileTarg->MinDeployment;
214 EXPECT_EQ(MD, FileMD);
217 EXPECT_EQ(PackedVersion(1, 2, 0), File->getCurrentVersion());
218 EXPECT_EQ(PackedVersion(1, 1, 0), File->getCompatibilityVersion());
219 EXPECT_TRUE(File->isApplicationExtensionSafe());
220 EXPECT_FALSE(File->isTwoLevelNamespace());
221 EXPECT_EQ(0U, File->documents().size());
223 InterfaceFileRef ClientA("ClientA", AllTargets);
224 InterfaceFileRef ClientB("ClientB", AllTargets);
225 EXPECT_EQ(2U, File->allowableClients().size());
226 EXPECT_EQ(ClientA, File->allowableClients().at(0));
227 EXPECT_EQ(ClientB, File->allowableClients().at(1));
229 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
230 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
231 EXPECT_EQ(2U, File->reexportedLibraries().size());
232 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));
233 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));
235 TargetToAttr RPaths = {
236 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},
238 EXPECT_EQ(RPaths, File->rpaths());
240 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},
241 {Target(AK_arm64, PLATFORM_MACOS), "System"},
242 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
243 EXPECT_EQ(Umbrellas, File->umbrellas());
245 ExportedSymbolSeq Exports, Reexports, Undefineds;
246 for (const auto *Sym : File->symbols()) {
247 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
248 ExportedSymbol Temp =
249 ExportedSymbol{Sym->getKind(),
250 std::string(Sym->getName()),
251 Sym->isWeakDefined() || Sym->isWeakReferenced(),
252 Sym->isThreadLocalValue(),
253 Sym->isData(),
254 SymTargets};
255 if (Sym->isUndefined())
256 Undefineds.emplace_back(std::move(Temp));
257 else
258 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
259 : Exports.emplace_back(std::move(Temp));
261 llvm::sort(Exports);
262 llvm::sort(Reexports);
263 llvm::sort(Undefineds);
265 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),
266 Target(AK_arm64, PLATFORM_MACOS)};
268 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
269 {SymbolKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
270 {SymbolKind::GlobalSymbol,
271 "_funcFoo",
272 false,
273 false,
274 false,
275 {Target(AK_x86_64, PLATFORM_MACOS)}},
276 {SymbolKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
277 {SymbolKind::GlobalSymbol,
278 "_globalVar",
279 false,
280 false,
281 true,
282 {Target(AK_x86_64, PLATFORM_MACOS)}},
283 {SymbolKind::ObjectiveCClass,
284 "ClassA",
285 false,
286 false,
287 true,
288 {Target(AK_x86_64, PLATFORM_MACOS)}},
289 {SymbolKind::ObjectiveCClass,
290 "ClassB",
291 false,
292 false,
293 true,
294 {Target(AK_x86_64, PLATFORM_MACOS)}},
295 {SymbolKind::ObjectiveCClass,
296 "ClassData",
297 false,
298 false,
299 true,
300 {Target(AK_x86_64, PLATFORM_MACOS)}},
301 {SymbolKind::ObjectiveCClassEHType,
302 "ClassA",
303 false,
304 false,
305 true,
306 {Target(AK_x86_64, PLATFORM_MACOS)}},
307 {SymbolKind::ObjectiveCClassEHType,
308 "ClassB",
309 false,
310 false,
311 true,
312 {Target(AK_x86_64, PLATFORM_MACOS)}},
313 {SymbolKind::ObjectiveCInstanceVariable,
314 "ClassA.ivar1",
315 false,
316 false,
317 true,
318 {Target(AK_x86_64, PLATFORM_MACOS)}},
319 {SymbolKind::ObjectiveCInstanceVariable,
320 "ClassA.ivar2",
321 false,
322 false,
323 true,
324 {Target(AK_x86_64, PLATFORM_MACOS)}},
325 {SymbolKind::ObjectiveCInstanceVariable,
326 "ClassC.ivar1",
327 false,
328 false,
329 true,
330 {Target(AK_x86_64, PLATFORM_MACOS)}},
332 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
333 {SymbolKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
334 {SymbolKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
335 {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, true,
336 MacOSTargets},
339 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {
340 {SymbolKind::GlobalSymbol,
341 "_globalBind",
342 false,
343 false,
344 true,
345 {Target(AK_x86_64, PLATFORM_MACOS)}},
346 {SymbolKind::GlobalSymbol,
347 "referenced_sym",
348 true,
349 false,
350 true,
351 {Target(AK_x86_64, PLATFORM_MACOS)}},
354 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
355 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
356 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());
357 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
358 std::begin(ExpectedExportedSymbols)));
359 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
360 std::begin(ExpectedReexportedSymbols)));
361 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
362 std::begin(ExpectedUndefinedSymbols)));
364 EXPECT_TRUE(
365 File->getSymbol(SymbolKind::GlobalSymbol, "_globalBind").has_value());
368 TEST(TBDv5, ReadMultipleTargets) {
369 static const char TBDv5File[] = R"({
370 "tapi_tbd_version": 5,
371 "main_library": {
372 "target_info": [
374 "target": "x86_64-macos",
375 "min_deployment": "10.14"
378 "target": "arm64-macos",
379 "min_deployment": "10.14"
382 "target": "arm64-maccatalyst",
383 "min_deployment": "12.1"
386 "install_names":[
387 { "name":"/usr/lib/libFoo.dylib" }
389 "swift_abi":[ { "abi":8 } ],
390 "reexported_libraries": [
392 "targets": [ "x86_64-maccatalyst" ],
393 "names": [
394 "/u/l/l/libfoo.dylib",
395 "/u/l/l/libbar.dylib"
399 "targets": [ "arm64-maccatalyst" ],
400 "names": [ "/u/l/l/libArmOnly.dylib" ]
404 })";
406 Expected<TBDFile> Result =
407 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
408 EXPECT_TRUE(!!Result);
409 TBDFile File = std::move(Result.get());
410 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
411 EXPECT_EQ(std::string("/usr/lib/libFoo.dylib"), File->getInstallName());
412 EXPECT_TRUE(File->isApplicationExtensionSafe());
413 EXPECT_TRUE(File->isTwoLevelNamespace());
414 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
415 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
416 EXPECT_EQ(8U, File->getSwiftABIVersion());
418 TargetList AllTargets = {
419 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
420 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),
421 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),
423 EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());
424 EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());
426 InterfaceFileRef ReexportA("/u/l/l/libArmOnly.dylib",
427 {Target(AK_arm64, PLATFORM_MACCATALYST)});
428 InterfaceFileRef ReexportB("/u/l/l/libbar.dylib",
429 {Target(AK_x86_64, PLATFORM_MACCATALYST)});
430 InterfaceFileRef ReexportC("/u/l/l/libfoo.dylib",
431 {Target(AK_x86_64, PLATFORM_MACCATALYST)});
432 EXPECT_EQ(3U, File->reexportedLibraries().size());
433 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));
434 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));
435 EXPECT_EQ(ReexportC, File->reexportedLibraries().at(2));
438 TEST(TBDv5, ReadMultipleDocuments) {
439 static const char TBDv5File[] = R"({
440 "tapi_tbd_version": 5,
441 "main_library": {
442 "target_info": [
444 "target": "armv7-ios",
445 "min_deployment": "11.0"
448 "install_names":[
449 { "name":"/S/L/F/Foo.framework/Foo" }
451 "reexported_libraries": [
452 { "names": ["/u/l/l/libfoo.dylib"] }
455 "libraries": [
457 "target_info": [
459 "target": "armv7-ios",
460 "min_deployment": "11.0"
463 "install_names":[
464 { "name":"/u/l/l/libfoo.dylib" }
466 "flags":[
467 { "attributes": ["not_app_extension_safe"] }
469 "exported_symbols": [
471 "data": {
472 "thread_local": [ "_globalVar" ],
473 "objc_class": [ "ClassData", "ClassA", "ClassB"],
474 "objc_eh_type": [ "ClassA", "ClassB" ]
476 "text": {
477 "global": [ "_funcFoo" ]
482 ]})";
484 Expected<TBDFile> Result =
485 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
486 EXPECT_TRUE(!!Result);
487 TBDFile File = std::move(Result.get());
488 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
489 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());
490 EXPECT_TRUE(File->isTwoLevelNamespace());
491 EXPECT_TRUE(File->isApplicationExtensionSafe());
493 TargetList Targets(File->targets().begin(), File->targets().end());
494 Target iOSTarget(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0));
495 EXPECT_EQ(TargetList{iOSTarget}, Targets);
496 std::vector<const Symbol *> Symbols(File->symbols().begin(),
497 File->symbols().end());
498 EXPECT_EQ(0U, Symbols.size());
500 InterfaceFileRef Reexport("/u/l/l/libfoo.dylib", {iOSTarget});
501 EXPECT_EQ(1U, File->reexportedLibraries().size());
502 EXPECT_EQ(Reexport, File->reexportedLibraries().at(0));
504 // Check inlined library.
505 EXPECT_EQ(1U, File->documents().size());
506 TBDReexportFile Document = File->documents().front();
507 Targets = {Document->targets().begin(), Document->targets().end()};
508 EXPECT_EQ(TargetList{iOSTarget}, Targets);
509 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());
510 EXPECT_EQ(0U, Document->getSwiftABIVersion());
511 EXPECT_TRUE(Document->isTwoLevelNamespace());
512 EXPECT_FALSE(Document->isApplicationExtensionSafe());
514 ExportedSymbolSeq Exports;
515 for (const auto *Sym : Document->symbols())
516 Exports.emplace_back(
517 ExportedSymbol{Sym->getKind(),
518 std::string(Sym->getName()),
519 Sym->isWeakDefined() || Sym->isWeakReferenced(),
520 Sym->isThreadLocalValue(),
521 Sym->isData(),
522 {iOSTarget}});
524 llvm::sort(Exports);
525 ExportedSymbolSeq ExpectedExports = {
526 {SymbolKind::GlobalSymbol, "_funcFoo", false, false, false, {iOSTarget}},
527 {SymbolKind::GlobalSymbol, "_globalVar", false, true, true, {iOSTarget}},
528 {SymbolKind::ObjectiveCClass, "ClassA", false, false, true, {iOSTarget}},
529 {SymbolKind::ObjectiveCClass, "ClassB", false, false, true, {iOSTarget}},
530 {SymbolKind::ObjectiveCClass,
531 "ClassData",
532 false,
533 false,
534 true,
535 {iOSTarget}},
536 {SymbolKind::ObjectiveCClassEHType,
537 "ClassA",
538 false,
539 false,
540 true,
541 {iOSTarget}},
542 {SymbolKind::ObjectiveCClassEHType,
543 "ClassB",
544 false,
545 false,
546 true,
547 {iOSTarget}},
550 EXPECT_EQ(ExpectedExports.size(), Exports.size());
551 EXPECT_TRUE(
552 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
555 TEST(TBDv5, WriteFile) {
556 static const char TBDv5File[] = R"({
557 "tapi_tbd_version": 5,
558 "main_library": {
559 "target_info": [
561 "target": "x86_64-macos",
562 "min_deployment": "10.14"
565 "target": "arm64-macos",
566 "min_deployment": "10.14"
569 "target": "arm64-maccatalyst",
570 "min_deployment": "12.1"
573 "install_names": [
575 "name": "@rpath/S/L/F/Foo.framework/Foo"
578 "current_versions": [
580 "version": "1.2"
583 "compatibility_versions": [
584 { "version": "1.1" }
586 "flags": [
588 "attributes": [
589 "flat_namespace"
593 "rpaths": [
595 "targets": [
596 "x86_64-macos"
598 "paths": [
599 "@executable_path/.../Frameworks"
603 "parent_umbrellas": [
605 "umbrella": "System"
608 "allowable_clients": [
610 "clients": [
611 "ClientA",
612 "ClientB"
616 "reexported_libraries": [
618 "names": [
619 "/u/l/l/libfoo.dylib",
620 "/u/l/l/libbar.dylib"
624 "exported_symbols": [
626 "targets": [
627 "x86_64-macos",
628 "arm64-macos"
630 "data": {
631 "global": [
632 "_global"
634 "objc_class": [
635 "ClassA"
637 "weak": [],
638 "thread_local": []
640 "text": {
641 "global": [
642 "_func"
644 "weak": [],
645 "thread_local": []
649 "targets": [
650 "x86_64-macos"
652 "data": {
653 "global": [
654 "_globalVar"
656 "objc_class": [
657 "ClassA",
658 "ClassB",
659 "ClassData"
661 "objc_eh_type": [
662 "ClassA",
663 "ClassB"
665 "objc_ivar": [
666 "ClassA.ivar1",
667 "ClassA.ivar2",
668 "ClassC.ivar1"
671 "text": {
672 "global": [
673 "_funcFoo"
678 "reexported_symbols": [
680 "data": {
681 "global": [
682 "_globalRe"
684 "objc_class": [
685 "ClassRexport"
688 "text": {
689 "global": [
690 "_funcA"
695 "undefined_symbols": [
697 "targets": [
698 "x86_64-macos"
700 "data": {
701 "global": [
702 "_globalBind"
704 "weak": [
705 "referenced_sym"
710 }})";
712 InterfaceFile File;
713 File.setFileType(FileType::TBD_V5);
715 TargetList AllTargets = {
716 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
717 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),
718 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),
720 File.addTargets(AllTargets);
721 File.setInstallName("@rpath/S/L/F/Foo.framework/Foo");
722 File.setCurrentVersion(PackedVersion(1, 2, 0));
723 File.setCompatibilityVersion(PackedVersion(1, 1, 0));
724 File.addRPath(AllTargets[0], "@executable_path/.../Frameworks");
726 for (const auto &Targ : AllTargets) {
727 File.addParentUmbrella(Targ, "System");
728 File.addAllowableClient("ClientA", Targ);
729 File.addAllowableClient("ClientB", Targ);
730 File.addReexportedLibrary("/u/l/l/libfoo.dylib", Targ);
731 File.addReexportedLibrary("/u/l/l/libbar.dylib", Targ);
734 SymbolFlags Flags = SymbolFlags::None;
735 // Exports.
736 File.addSymbol(SymbolKind::GlobalSymbol, "_global",
737 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);
738 File.addSymbol(SymbolKind::GlobalSymbol, "_func",
739 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Text);
740 File.addSymbol(SymbolKind::ObjectiveCClass, "ClassA",
741 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);
742 File.addSymbol(SymbolKind::GlobalSymbol, "_funcFoo", {AllTargets[0]},
743 Flags | SymbolFlags::Text);
744 File.addSymbol(SymbolKind::GlobalSymbol, "_globalVar", {AllTargets[0]},
745 Flags | SymbolFlags::Data);
746 File.addSymbol(SymbolKind::ObjectiveCClass, "ClassData", {AllTargets[0]},
747 Flags | SymbolFlags::Data);
748 File.addSymbol(SymbolKind::ObjectiveCClassEHType, "ClassA", {AllTargets[0]},
749 Flags | SymbolFlags::Data);
750 File.addSymbol(SymbolKind::ObjectiveCClassEHType, "ClassB", {AllTargets[0]},
751 Flags | SymbolFlags::Data);
752 File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "ClassA.ivar1",
753 {AllTargets[0]}, Flags | SymbolFlags::Data);
754 File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "ClassA.ivar2",
755 {AllTargets[0]}, Flags | SymbolFlags::Data);
756 File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "ClassC.ivar1",
757 {AllTargets[0]}, Flags | SymbolFlags::Data);
759 // Reexports.
760 Flags = SymbolFlags::Rexported;
761 File.addSymbol(SymbolKind::GlobalSymbol, "_globalRe", AllTargets,
762 Flags | SymbolFlags::Data);
763 File.addSymbol(SymbolKind::GlobalSymbol, "_funcA", AllTargets,
764 Flags | SymbolFlags::Text);
765 File.addSymbol(SymbolKind::ObjectiveCClass, "ClassRexport", AllTargets,
766 Flags | SymbolFlags::Data);
768 // Undefineds.
769 Flags = SymbolFlags::Undefined;
770 File.addSymbol(SymbolKind::GlobalSymbol, "_globalBind", {AllTargets[0]},
771 Flags | SymbolFlags::Data);
772 File.addSymbol(SymbolKind::GlobalSymbol, "referenced_sym", {AllTargets[0]},
773 Flags | SymbolFlags::Data | SymbolFlags::WeakReferenced);
775 File.setTwoLevelNamespace(false);
776 File.setApplicationExtensionSafe(true);
778 // Write out file then process it back into IF and compare equality
779 // against TBDv5File.
780 SmallString<4096> Buffer;
781 raw_svector_ostream OS(Buffer);
782 Error Result = TextAPIWriter::writeToStream(OS, File);
783 EXPECT_FALSE(Result);
785 Expected<TBDFile> Input =
786 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));
787 EXPECT_TRUE(!!Input);
788 TBDFile InputFile = std::move(Input.get());
790 Expected<TBDFile> Output =
791 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
792 EXPECT_TRUE(!!Output);
793 TBDFile OutputFile = std::move(Output.get());
794 EXPECT_EQ(*InputFile, *OutputFile);
797 TEST(TBDv5, WriteMultipleDocuments) {
798 static const char TBDv5File[] = R"({
799 "tapi_tbd_version": 5,
800 "main_library": {
801 "target_info": [
803 "target": "armv7-ios",
804 "min_deployment": "11.0"
807 "install_names":[
808 { "name":"/S/L/F/Foo.framework/Foo" }
810 "reexported_libraries": [
811 { "names": ["/u/l/l/libfoo.dylib"]
815 "libraries": [
817 "target_info": [
819 "target": "armv7-ios",
820 "min_deployment": "11.0"
823 "target": "armv7s-ios",
824 "min_deployment": "11.0"
827 "install_names":[
828 { "name":"/u/l/l/libfoo.dylib" }
830 "current_versions": [
832 "version": "2.1.1"
835 "rpaths": [
837 "targets": [
838 "armv7-ios"
840 "paths": [
841 "@executable_path/.../Frameworks"
844 "reexported_libraries": [ { "names": ["@rpath/libfoo.dylib"] } ],
845 "flags":[
846 { "attributes": ["not_app_extension_safe"] }
848 "exported_symbols": [
850 "text": {
851 "global": [ "_funcFoo" ]
857 "target_info": [
859 "target": "armv7-ios",
860 "min_deployment": "11.0"
863 "install_names":[
864 { "name":"@rpath/libfoo.dylib" }
866 "exported_symbols": [
868 "data": {
869 "global": [ "_varFooBaz" ]
874 ]})";
876 InterfaceFile File;
877 File.setFileType(FileType::TBD_V5);
879 TargetList AllTargets = {
880 Target(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0)),
881 Target(AK_armv7s, PLATFORM_IOS, VersionTuple(11, 0)),
883 File.setInstallName("/S/L/F/Foo.framework/Foo");
884 File.addTarget(AllTargets[0]);
885 File.setCurrentVersion(PackedVersion(1, 0, 0));
886 File.setCompatibilityVersion(PackedVersion(1, 0, 0));
887 File.addReexportedLibrary("/u/l/l/libfoo.dylib", AllTargets[0]);
888 File.setTwoLevelNamespace();
889 File.setApplicationExtensionSafe(true);
891 InterfaceFile NestedFile;
892 NestedFile.setFileType(FileType::TBD_V5);
893 NestedFile.setInstallName("/u/l/l/libfoo.dylib");
894 NestedFile.addTargets(AllTargets);
895 NestedFile.setCompatibilityVersion(PackedVersion(1, 0, 0));
896 NestedFile.setTwoLevelNamespace();
897 NestedFile.setApplicationExtensionSafe(false);
898 NestedFile.setCurrentVersion(PackedVersion(2, 1, 1));
899 NestedFile.addRPath(AllTargets[0], "@executable_path/.../Frameworks");
900 for (const auto &Targ : AllTargets)
901 NestedFile.addReexportedLibrary("@rpath/libfoo.dylib", Targ);
902 NestedFile.addSymbol(SymbolKind::GlobalSymbol, "_funcFoo", AllTargets,
903 SymbolFlags::Text);
904 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFile)));
906 InterfaceFile NestedFileB;
907 NestedFileB.setFileType(FileType::TBD_V5);
908 NestedFileB.setInstallName("@rpath/libfoo.dylib");
909 NestedFileB.addTarget(AllTargets[0]);
910 NestedFileB.setCompatibilityVersion(PackedVersion(1, 0, 0));
911 NestedFileB.setCurrentVersion(PackedVersion(1, 0, 0));
912 NestedFileB.setTwoLevelNamespace();
913 NestedFileB.setApplicationExtensionSafe(true);
914 NestedFileB.addSymbol(SymbolKind::GlobalSymbol, "_varFooBaz", {AllTargets[0]},
915 SymbolFlags::Data);
916 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFileB)));
918 // Write out file then process it back into IF and compare equality
919 // against TBDv5File.
920 SmallString<4096> Buffer;
921 raw_svector_ostream OS(Buffer);
922 Error Result = TextAPIWriter::writeToStream(OS, File, FileType::Invalid,
923 /*Compact=*/true);
924 EXPECT_FALSE(Result);
926 Expected<TBDFile> Input =
927 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));
928 EXPECT_TRUE(!!Input);
929 TBDFile InputFile = std::move(Input.get());
931 Expected<TBDFile> Output =
932 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
933 EXPECT_TRUE(!!Output);
934 TBDFile OutputFile = std::move(Output.get());
935 EXPECT_EQ(*InputFile, *OutputFile);
938 TEST(TBDv5, Target_Simulator) {
939 static const char TBDv5File[] = R"({
940 "tapi_tbd_version": 5,
941 "main_library": {
942 "target_info": [
944 "target": "arm64-ios-simulator",
945 "min_deployment": "11.0"
948 "target": "x86_64-ios-simulator",
949 "min_deployment": "11.3"
952 "install_names":[
953 { "name":"/S/L/F/Foo.framework/Foo" }
955 }})";
957 Expected<TBDFile> Result =
958 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
959 EXPECT_TRUE(!!Result);
960 TBDFile File = std::move(Result.get());
961 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
962 TargetList ExpectedTargets = {
963 Target(AK_x86_64, PLATFORM_IOSSIMULATOR, VersionTuple(11, 3)),
964 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0)),
966 TargetList Targets{File->targets().begin(), File->targets().end()};
967 llvm::sort(Targets);
968 EXPECT_EQ(Targets, ExpectedTargets);
970 SmallString<4096> Buffer;
971 raw_svector_ostream OS(Buffer);
972 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
973 EXPECT_TRUE(!WriteResult);
975 Expected<TBDFile> Output =
976 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
977 EXPECT_TRUE(!!Output);
978 TBDFile WriteResultFile = std::move(Output.get());
979 EXPECT_EQ(*File, *WriteResultFile);
982 TEST(TBDv5, Target_UnsupportedMinOS) {
983 static const char TBDv5File[] = R"({
984 "tapi_tbd_version": 5,
985 "main_library": {
986 "target_info": [
988 "target": "arm64-macos",
989 "min_deployment": "10.14"
992 "target": "x86_64-macos",
993 "min_deployment": "10.14"
996 "install_names":[
997 { "name":"/S/L/F/Foo.framework/Foo" }
999 }})";
1001 Expected<TBDFile> Result =
1002 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1003 EXPECT_TRUE(!!Result);
1004 TBDFile File = std::move(Result.get());
1005 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
1006 TargetList ExpectedTargets = {
1007 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
1008 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0)),
1010 TargetList Targets{File->targets().begin(), File->targets().end()};
1011 llvm::sort(Targets);
1012 EXPECT_EQ(Targets, ExpectedTargets);
1014 SmallString<4096> Buffer;
1015 raw_svector_ostream OS(Buffer);
1016 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
1017 EXPECT_TRUE(!WriteResult);
1019 Expected<TBDFile> Output =
1020 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
1021 EXPECT_TRUE(!!Output);
1022 TBDFile WriteResultFile = std::move(Output.get());
1023 EXPECT_EQ(*File, *WriteResultFile);
1026 TEST(TBDv5, MisspelledKey) {
1027 static const char TBDv5File[] = R"({
1028 "tapi_tbd_version": 5,
1029 "main_library": {
1030 "target_info": [
1032 "target": "arm64-ios-simulator",
1033 "min_deployment": "11.0"
1036 "intall_names":[
1037 { "name":"/S/L/F/Foo.framework/Foo" }
1039 }})";
1041 Expected<TBDFile> Result =
1042 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1043 EXPECT_FALSE(!!Result);
1044 std::string ErrorMessage = toString(Result.takeError());
1045 EXPECT_EQ("invalid install_names section\n", ErrorMessage);
1048 TEST(TBDv5, InvalidVersion) {
1049 static const char TBDv5File[] = R"({
1050 "tapi_tbd_version": 11,
1051 "main_library": {
1052 "target_info": [
1054 "target": "arm64-ios-simulator",
1055 "min_deployment": "11.0"
1058 "install_names":[
1059 { "name":"/S/L/F/Foo.framework/Foo" }
1061 }})";
1063 Expected<TBDFile> Result =
1064 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1065 EXPECT_FALSE(!!Result);
1066 std::string ErrorMessage = toString(Result.takeError());
1067 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);
1070 TEST(TBDv5, MissingRequiredKey) {
1071 static const char TBDv5File[] = R"({
1072 "main_library": {
1073 "target_info": [
1075 "target": "arm64-ios-simulator",
1076 "min_deployment": "11.0"
1079 "install_names":[
1080 { "name":"/S/L/F/Foo.framework/Foo" }
1082 }})";
1084 Expected<TBDFile> Result =
1085 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1086 EXPECT_FALSE(!!Result);
1087 std::string ErrorMessage = toString(Result.takeError());
1088 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);
1091 TEST(TBDv5, InvalidSymbols) {
1092 static const char TBDv5File[] = R"({
1093 "tapi_tbd_version": 5,
1094 "main_library": {
1095 "target_info": [
1097 "target": "arm64-driverkit",
1098 "min_deployment": "11.0"
1101 "install_names":[
1102 { "name":"/S/L/F/Foo.framework/Foo" }
1104 "exported_symbols": [
1106 "daa": {
1107 "global": {
1108 "weak": []
1113 }})";
1115 Expected<TBDFile> Result =
1116 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1117 EXPECT_FALSE(!!Result);
1118 std::string ErrorMessage = toString(Result.takeError());
1119 EXPECT_EQ("invalid exported_symbols section\n", ErrorMessage);
1122 TEST(TBDv5, DefaultMinOS) {
1123 static const char TBDv5File[] = R"({
1124 "tapi_tbd_version": 5,
1125 "main_library": {
1126 "target_info": [
1128 "target": "arm64-ios-simulator"
1131 "install_names":[
1132 { "name":"/S/L/F/Foo.framework/Foo" }
1134 }})";
1136 Expected<TBDFile> Result =
1137 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1138 EXPECT_TRUE(!!Result);
1139 TBDFile File = std::move(Result.get());
1140 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
1141 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());
1142 EXPECT_TRUE(File->targets().begin() != File->targets().end());
1143 EXPECT_EQ(*File->targets().begin(),
1144 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(0, 0)));
1147 TEST(TBDv5, InvalidMinOS) {
1148 static const char TBDv5File[] = R"({
1149 "tapi_tbd_version": 5,
1150 "main_library": {
1151 "target_info": [
1153 "target": "arm64-ios-simulator",
1154 "min_deployment": "swift-abi"
1157 "install_names":[
1158 { "name":"/S/L/F/Foo.framework/Foo" }
1160 }})";
1162 Expected<TBDFile> Result =
1163 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1164 EXPECT_FALSE(!!Result);
1165 std::string ErrorMessage = toString(Result.takeError());
1166 EXPECT_EQ("invalid min_deployment section\n", ErrorMessage);
1169 TEST(TBDv5, SimSupport) {
1170 static const char TBDv5File[] = R"({
1171 "tapi_tbd_version": 5,
1172 "main_library": {
1173 "target_info": [
1175 "target": "arm64-macos",
1176 "min_deployment": "11.1"
1179 "install_names":[
1180 { "name":"/S/L/F/Foo.framework/Foo" }
1182 "flags":[
1183 { "attributes": ["sim_support"] }
1185 }})";
1187 Expected<TBDFile> Result =
1188 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1189 EXPECT_TRUE(!!Result);
1190 Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));
1191 TBDFile ReadFile = std::move(Result.get());
1192 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());
1193 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1194 ReadFile->getInstallName());
1195 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());
1196 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);
1197 EXPECT_TRUE(ReadFile->hasSimulatorSupport());
1200 TEST(TBDv5, MergeIF) {
1201 static const char TBDv5FileA[] = R"({
1202 "tapi_tbd_version": 5,
1203 "main_library": {
1204 "target_info": [
1206 "target": "x86_64-macos",
1207 "min_deployment": "10.14"
1210 "target": "arm64-macos",
1211 "min_deployment": "10.14"
1214 "target": "arm64-maccatalyst",
1215 "min_deployment": "12.1"
1218 "flags": [
1220 "targets": [
1221 "x86_64-macos"
1223 "attributes": [
1224 "flat_namespace"
1228 "install_names": [
1230 "name": "/S/L/F/Foo.framework/Foo"
1233 "current_versions": [
1235 "version": "1.2"
1238 "compatibility_versions": [
1239 { "version": "1.1" }
1241 "rpaths": [
1243 "targets": [
1244 "x86_64-macos"
1246 "paths": [
1247 "@executable_path/.../Frameworks"
1251 "parent_umbrellas": [
1253 "umbrella": "System"
1256 "allowable_clients": [
1258 "clients": [
1259 "ClientA",
1260 "ClientB"
1264 "reexported_libraries": [
1266 "names": [
1267 "/u/l/l/libfoo.dylib",
1268 "/u/l/l/libbar.dylib"
1272 "exported_symbols": [
1274 "targets": [
1275 "x86_64-macos",
1276 "arm64-macos"
1278 "data": {
1279 "global": [
1280 "_global"
1282 "objc_class": [
1283 "ClassA"
1285 "weak": [],
1286 "thread_local": []
1288 "text": {
1289 "global": [
1290 "_func"
1292 "weak": [],
1293 "thread_local": []
1297 "targets": [
1298 "x86_64-macos"
1300 "data": {
1301 "global": [
1302 "_globalVar"
1304 "objc_class": [
1305 "ClassA",
1306 "ClassB",
1307 "ClassData"
1309 "objc_eh_type": [
1310 "ClassA",
1311 "ClassB"
1313 "objc_ivar": [
1314 "ClassA.ivar1",
1315 "ClassA.ivar2",
1316 "ClassC.ivar1"
1319 "text": {
1320 "global": [
1321 "_funcFoo"
1326 "reexported_symbols": [
1328 "targets": [
1329 "x86_64-macos",
1330 "arm64-macos"
1332 "data": {
1333 "global": [
1334 "_globalRe"
1336 "objc_class": [
1337 "ClassRexport"
1340 "text": {
1341 "global": [
1342 "_funcA"
1347 "undefined_symbols": [
1349 "targets": [
1350 "x86_64-macos"
1352 "data": {
1353 "global": [
1354 "_globalBind"
1356 "weak": [
1357 "referenced_sym"
1363 "libraries": []
1364 })";
1366 static const char TBDv5FileB[] = R"({
1367 "tapi_tbd_version": 5,
1368 "main_library": {
1369 "target_info": [
1371 "target": "x86_64-macos",
1372 "min_deployment": "10.14"
1375 "target": "arm64-macos",
1376 "min_deployment": "10.14"
1379 "target": "arm64-maccatalyst",
1380 "min_deployment": "12.1"
1383 "flags": [
1385 "targets": [
1386 "x86_64-macos"
1388 "attributes": [
1389 "flat_namespace"
1393 "install_names": [
1395 "name": "/S/L/F/Foo.framework/Foo"
1398 "current_versions": [
1400 "version": "1.2"
1403 "compatibility_versions": [
1404 { "version": "1.1" }
1406 "exported_symbols": [
1408 "targets": [
1409 "x86_64-macos",
1410 "arm64-macos"
1412 "data": {
1413 "global": [
1414 "_globalZ"
1416 "objc_class": [
1417 "ClassZ"
1419 "weak": [],
1420 "thread_local": []
1422 "text": {
1423 "global": [
1424 "_funcZ"
1426 "weak": [],
1427 "thread_local": []
1431 "targets": [
1432 "x86_64-macos"
1434 "data": {
1435 "global": [
1436 "_globalVarZ"
1438 "objc_class": [
1439 "ClassZ",
1440 "ClassF"
1442 "objc_eh_type": [
1443 "ClassZ",
1444 "ClassF"
1446 "objc_ivar": [
1447 "ClassZ.ivar1",
1448 "ClassZ.ivar2",
1449 "ClassF.ivar1"
1452 "text": {
1453 "global": [
1454 "_funcFooZ"
1460 "libraries": []
1461 })";
1463 Expected<TBDFile> ResultA =
1464 TextAPIReader::get(MemoryBufferRef(TBDv5FileA, "Test.tbd"));
1465 EXPECT_TRUE(!!ResultA);
1466 TBDFile FileA = std::move(ResultA.get());
1468 Expected<TBDFile> ResultB =
1469 TextAPIReader::get(MemoryBufferRef(TBDv5FileB, "Test.tbd"));
1470 EXPECT_TRUE(!!ResultB);
1471 TBDFile FileB = std::move(ResultB.get());
1473 Expected<TBDFile> MergedResult = FileA->merge(FileB.get());
1474 EXPECT_TRUE(!!MergedResult);
1475 TBDFile MergedFile = std::move(MergedResult.get());
1477 EXPECT_EQ(FileType::TBD_V5, MergedFile->getFileType());
1478 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1479 MergedFile->getInstallName());
1480 TargetList AllTargets = {
1481 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
1482 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
1483 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
1485 EXPECT_EQ(mapToPlatformSet(AllTargets), MergedFile->getPlatforms());
1486 EXPECT_EQ(mapToArchitectureSet(AllTargets), MergedFile->getArchitectures());
1487 EXPECT_EQ(PackedVersion(1, 2, 0), MergedFile->getCurrentVersion());
1488 EXPECT_EQ(PackedVersion(1, 1, 0), MergedFile->getCompatibilityVersion());
1489 EXPECT_TRUE(MergedFile->isApplicationExtensionSafe());
1490 EXPECT_FALSE(MergedFile->isTwoLevelNamespace());
1491 EXPECT_EQ(0U, MergedFile->documents().size());
1492 InterfaceFileRef ClientA("ClientA", AllTargets);
1493 InterfaceFileRef ClientB("ClientB", AllTargets);
1494 EXPECT_EQ(2U, MergedFile->allowableClients().size());
1495 EXPECT_EQ(ClientA, MergedFile->allowableClients().at(0));
1496 EXPECT_EQ(ClientB, MergedFile->allowableClients().at(1));
1498 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
1499 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
1500 EXPECT_EQ(2U, MergedFile->reexportedLibraries().size());
1501 EXPECT_EQ(ReexportA, MergedFile->reexportedLibraries().at(0));
1502 EXPECT_EQ(ReexportB, MergedFile->reexportedLibraries().at(1));
1504 TargetToAttr RPaths = {
1505 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},
1507 EXPECT_EQ(RPaths, MergedFile->rpaths());
1509 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},
1510 {Target(AK_arm64, PLATFORM_MACOS), "System"},
1511 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
1512 EXPECT_EQ(Umbrellas, MergedFile->umbrellas());
1514 ExportedSymbolSeq Exports, Reexports, Undefineds;
1515 for (const auto *Sym : MergedFile->symbols()) {
1516 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
1517 ExportedSymbol Temp =
1518 ExportedSymbol{Sym->getKind(),
1519 std::string(Sym->getName()),
1520 Sym->isWeakDefined() || Sym->isWeakReferenced(),
1521 Sym->isThreadLocalValue(),
1522 Sym->isData(),
1523 SymTargets};
1524 if (Sym->isUndefined())
1525 Undefineds.emplace_back(std::move(Temp));
1526 else
1527 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
1528 : Exports.emplace_back(std::move(Temp));
1530 llvm::sort(Exports);
1531 llvm::sort(Reexports);
1532 llvm::sort(Undefineds);
1534 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),
1535 Target(AK_arm64, PLATFORM_MACOS)};
1537 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
1538 {SymbolKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
1539 {SymbolKind::GlobalSymbol,
1540 "_funcFoo",
1541 false,
1542 false,
1543 false,
1544 {Target(AK_x86_64, PLATFORM_MACOS)}},
1545 {SymbolKind::GlobalSymbol,
1546 "_funcFooZ",
1547 false,
1548 false,
1549 false,
1550 {Target(AK_x86_64, PLATFORM_MACOS)}},
1551 {SymbolKind::GlobalSymbol, "_funcZ", false, false, false, MacOSTargets},
1552 {SymbolKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
1553 {SymbolKind::GlobalSymbol,
1554 "_globalVar",
1555 false,
1556 false,
1557 true,
1558 {Target(AK_x86_64, PLATFORM_MACOS)}},
1559 {SymbolKind::GlobalSymbol,
1560 "_globalVarZ",
1561 false,
1562 false,
1563 true,
1564 {Target(AK_x86_64, PLATFORM_MACOS)}},
1565 {SymbolKind::GlobalSymbol, "_globalZ", false, false, true, MacOSTargets},
1566 {SymbolKind::ObjectiveCClass,
1567 "ClassA",
1568 false,
1569 false,
1570 true,
1571 {Target(AK_x86_64, PLATFORM_MACOS)}},
1572 {SymbolKind::ObjectiveCClass,
1573 "ClassB",
1574 false,
1575 false,
1576 true,
1577 {Target(AK_x86_64, PLATFORM_MACOS)}},
1578 {SymbolKind::ObjectiveCClass,
1579 "ClassData",
1580 false,
1581 false,
1582 true,
1583 {Target(AK_x86_64, PLATFORM_MACOS)}},
1584 {SymbolKind::ObjectiveCClass,
1585 "ClassF",
1586 false,
1587 false,
1588 true,
1589 {Target(AK_x86_64, PLATFORM_MACOS)}},
1590 {SymbolKind::ObjectiveCClass,
1591 "ClassZ",
1592 false,
1593 false,
1594 true,
1595 {Target(AK_x86_64, PLATFORM_MACOS)}},
1596 {SymbolKind::ObjectiveCClassEHType,
1597 "ClassA",
1598 false,
1599 false,
1600 true,
1601 {Target(AK_x86_64, PLATFORM_MACOS)}},
1602 {SymbolKind::ObjectiveCClassEHType,
1603 "ClassB",
1604 false,
1605 false,
1606 true,
1607 {Target(AK_x86_64, PLATFORM_MACOS)}},
1608 {SymbolKind::ObjectiveCClassEHType,
1609 "ClassF",
1610 false,
1611 false,
1612 true,
1613 {Target(AK_x86_64, PLATFORM_MACOS)}},
1614 {SymbolKind::ObjectiveCClassEHType,
1615 "ClassZ",
1616 false,
1617 false,
1618 true,
1619 {Target(AK_x86_64, PLATFORM_MACOS)}},
1620 {SymbolKind::ObjectiveCInstanceVariable,
1621 "ClassA.ivar1",
1622 false,
1623 false,
1624 true,
1625 {Target(AK_x86_64, PLATFORM_MACOS)}},
1626 {SymbolKind::ObjectiveCInstanceVariable,
1627 "ClassA.ivar2",
1628 false,
1629 false,
1630 true,
1631 {Target(AK_x86_64, PLATFORM_MACOS)}},
1632 {SymbolKind::ObjectiveCInstanceVariable,
1633 "ClassC.ivar1",
1634 false,
1635 false,
1636 true,
1637 {Target(AK_x86_64, PLATFORM_MACOS)}},
1638 {SymbolKind::ObjectiveCInstanceVariable,
1639 "ClassF.ivar1",
1640 false,
1641 false,
1642 true,
1643 {Target(AK_x86_64, PLATFORM_MACOS)}},
1644 {SymbolKind::ObjectiveCInstanceVariable,
1645 "ClassZ.ivar1",
1646 false,
1647 false,
1648 true,
1649 {Target(AK_x86_64, PLATFORM_MACOS)}},
1650 {SymbolKind::ObjectiveCInstanceVariable,
1651 "ClassZ.ivar2",
1652 false,
1653 false,
1654 true,
1655 {Target(AK_x86_64, PLATFORM_MACOS)}},
1658 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
1659 {SymbolKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
1660 {SymbolKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
1661 {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, true,
1662 MacOSTargets},
1665 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {
1666 {SymbolKind::GlobalSymbol,
1667 "_globalBind",
1668 false,
1669 false,
1670 true,
1671 {Target(AK_x86_64, PLATFORM_MACOS)}},
1672 {SymbolKind::GlobalSymbol,
1673 "referenced_sym",
1674 true,
1675 false,
1676 true,
1677 {Target(AK_x86_64, PLATFORM_MACOS)}},
1680 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
1681 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
1682 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());
1683 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
1684 std::begin(ExpectedExportedSymbols)));
1685 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
1686 std::begin(ExpectedReexportedSymbols)));
1687 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
1688 std::begin(ExpectedUndefinedSymbols)));
1691 TEST(TBDv5, ExtractIF) {
1692 static const char TBDv5File[] = R"({
1693 "tapi_tbd_version": 5,
1694 "main_library": {
1695 "target_info": [
1697 "target": "x86_64-macos",
1698 "min_deployment": "10.14"
1701 "target": "arm64-macos",
1702 "min_deployment": "10.14"
1705 "target": "arm64-maccatalyst",
1706 "min_deployment": "12.1"
1709 "flags": [
1711 "targets": [
1712 "x86_64-macos"
1714 "attributes": [
1715 "flat_namespace"
1719 "install_names": [
1721 "name": "/S/L/F/Foo.framework/Foo"
1724 "current_versions": [
1726 "version": "1.2"
1729 "compatibility_versions": [
1730 { "version": "1.1" }
1732 "rpaths": [
1734 "targets": [
1735 "x86_64-macos"
1737 "paths": [
1738 "@executable_path/.../Frameworks"
1742 "parent_umbrellas": [
1744 "umbrella": "System"
1747 "allowable_clients": [
1749 "clients": [
1750 "ClientA",
1751 "ClientB"
1755 "reexported_libraries": [
1757 "names": [
1758 "/u/l/l/libfoo.dylib",
1759 "/u/l/l/libbar.dylib"
1763 "exported_symbols": [
1765 "targets": [
1766 "x86_64-macos",
1767 "arm64-macos"
1769 "data": {
1770 "global": [
1771 "_global"
1773 "objc_class": [
1774 "ClassA"
1776 "weak": [],
1777 "thread_local": []
1779 "text": {
1780 "global": [
1781 "_func"
1783 "weak": [],
1784 "thread_local": []
1788 "targets": [
1789 "x86_64-macos"
1791 "data": {
1792 "global": [
1793 "_globalVar"
1795 "objc_class": [
1796 "ClassA",
1797 "ClassB",
1798 "ClassData"
1800 "objc_eh_type": [
1801 "ClassA",
1802 "ClassB"
1804 "objc_ivar": [
1805 "ClassA.ivar1",
1806 "ClassA.ivar2",
1807 "ClassC.ivar1"
1810 "text": {
1811 "global": [
1812 "_funcFoo"
1817 "reexported_symbols": [
1819 "targets": [
1820 "x86_64-macos",
1821 "arm64-macos"
1823 "data": {
1824 "global": [
1825 "_globalRe"
1827 "objc_class": [
1828 "ClassRexport"
1831 "text": {
1832 "global": [
1833 "_funcA"
1838 "undefined_symbols": [
1840 "targets": [
1841 "x86_64-macos"
1843 "data": {
1844 "global": [
1845 "_globalBind"
1847 "weak": [
1848 "referenced_sym"
1854 "libraries": []
1855 })";
1857 Expected<TBDFile> Result =
1858 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1859 EXPECT_TRUE(!!Result);
1860 TBDFile File = std::move(Result.get());
1862 Expected<TBDFile> ExtractedResult = File->extract(AK_arm64);
1863 EXPECT_TRUE(!!ExtractedResult);
1864 TBDFile ExtractedFile = std::move(ExtractedResult.get());
1866 EXPECT_EQ(FileType::TBD_V5, ExtractedFile->getFileType());
1867 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1868 ExtractedFile->getInstallName());
1870 TargetList AllTargets = {
1871 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
1872 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
1874 EXPECT_EQ(mapToPlatformSet(AllTargets), ExtractedFile->getPlatforms());
1875 EXPECT_EQ(mapToArchitectureSet(AllTargets),
1876 ExtractedFile->getArchitectures());
1878 EXPECT_EQ(PackedVersion(1, 2, 0), ExtractedFile->getCurrentVersion());
1879 EXPECT_EQ(PackedVersion(1, 1, 0), ExtractedFile->getCompatibilityVersion());
1880 EXPECT_TRUE(ExtractedFile->isApplicationExtensionSafe());
1881 EXPECT_FALSE(ExtractedFile->isTwoLevelNamespace());
1882 EXPECT_EQ(0U, ExtractedFile->documents().size());
1884 InterfaceFileRef ClientA("ClientA", AllTargets);
1885 InterfaceFileRef ClientB("ClientB", AllTargets);
1886 EXPECT_EQ(2U, ExtractedFile->allowableClients().size());
1887 EXPECT_EQ(ClientA, ExtractedFile->allowableClients().at(0));
1888 EXPECT_EQ(ClientB, ExtractedFile->allowableClients().at(1));
1890 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
1891 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
1892 EXPECT_EQ(2U, ExtractedFile->reexportedLibraries().size());
1893 EXPECT_EQ(ReexportA, ExtractedFile->reexportedLibraries().at(0));
1894 EXPECT_EQ(ReexportB, ExtractedFile->reexportedLibraries().at(1));
1896 EXPECT_EQ(0u, ExtractedFile->rpaths().size());
1898 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},
1899 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
1900 EXPECT_EQ(Umbrellas, ExtractedFile->umbrellas());
1902 ExportedSymbolSeq Exports, Reexports, Undefineds;
1903 for (const auto *Sym : ExtractedFile->symbols()) {
1904 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
1905 ExportedSymbol Temp =
1906 ExportedSymbol{Sym->getKind(),
1907 std::string(Sym->getName()),
1908 Sym->isWeakDefined() || Sym->isWeakReferenced(),
1909 Sym->isThreadLocalValue(),
1910 Sym->isData(),
1911 SymTargets};
1912 if (Sym->isUndefined())
1913 Undefineds.emplace_back(std::move(Temp));
1914 else
1915 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
1916 : Exports.emplace_back(std::move(Temp));
1918 llvm::sort(Exports);
1919 llvm::sort(Reexports);
1920 llvm::sort(Undefineds);
1922 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};
1924 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
1925 {SymbolKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
1926 {SymbolKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
1927 {SymbolKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},
1929 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
1930 {SymbolKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
1931 {SymbolKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
1932 {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, true,
1933 MacOSTargets},
1936 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
1937 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
1938 EXPECT_EQ(0U, Undefineds.size());
1939 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
1940 std::begin(ExpectedExportedSymbols)));
1941 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
1942 std::begin(ExpectedReexportedSymbols)));
1945 TEST(TBDv5, RemoveIF) {
1946 static const char TBDv5File[] = R"({
1947 "tapi_tbd_version": 5,
1948 "main_library": {
1949 "target_info": [
1951 "target": "x86_64-macos",
1952 "min_deployment": "10.14"
1955 "target": "arm64-macos",
1956 "min_deployment": "10.14"
1959 "target": "arm64-maccatalyst",
1960 "min_deployment": "12.1"
1963 "flags": [
1965 "targets": [
1966 "x86_64-macos"
1968 "attributes": [
1969 "flat_namespace"
1973 "install_names": [
1975 "name": "/S/L/F/Foo.framework/Foo"
1978 "current_versions": [
1980 "version": "1.2"
1983 "compatibility_versions": [
1984 { "version": "1.1" }
1986 "rpaths": [
1988 "targets": [
1989 "x86_64-macos"
1991 "paths": [
1992 "@executable_path/.../Frameworks"
1996 "parent_umbrellas": [
1998 "umbrella": "System"
2001 "allowable_clients": [
2003 "clients": [
2004 "ClientA",
2005 "ClientB"
2009 "reexported_libraries": [
2011 "names": [
2012 "/u/l/l/libfoo.dylib",
2013 "/u/l/l/libbar.dylib"
2017 "exported_symbols": [
2019 "targets": [
2020 "x86_64-macos",
2021 "arm64-macos"
2023 "data": {
2024 "global": [
2025 "_global"
2027 "objc_class": [
2028 "ClassA"
2030 "weak": [],
2031 "thread_local": []
2033 "text": {
2034 "global": [
2035 "_func"
2037 "weak": [],
2038 "thread_local": []
2042 "targets": [
2043 "x86_64-macos"
2045 "data": {
2046 "global": [
2047 "_globalVar"
2049 "objc_class": [
2050 "ClassA",
2051 "ClassB",
2052 "ClassData"
2054 "objc_eh_type": [
2055 "ClassA",
2056 "ClassB"
2058 "objc_ivar": [
2059 "ClassA.ivar1",
2060 "ClassA.ivar2",
2061 "ClassC.ivar1"
2064 "text": {
2065 "global": [
2066 "_funcFoo"
2071 "reexported_symbols": [
2073 "targets": [
2074 "x86_64-macos",
2075 "arm64-macos"
2077 "data": {
2078 "global": [
2079 "_globalRe"
2081 "objc_class": [
2082 "ClassRexport"
2085 "text": {
2086 "global": [
2087 "_funcA"
2092 "undefined_symbols": [
2094 "targets": [
2095 "x86_64-macos"
2097 "data": {
2098 "global": [
2099 "_globalBind"
2101 "weak": [
2102 "referenced_sym"
2108 "libraries": []
2109 })";
2111 Expected<TBDFile> Result =
2112 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
2113 EXPECT_TRUE(!!Result);
2114 TBDFile File = std::move(Result.get());
2116 Expected<TBDFile> RemovedResult = File->remove(AK_x86_64);
2117 EXPECT_TRUE(!!RemovedResult);
2118 TBDFile RemovedFile = std::move(RemovedResult.get());
2120 EXPECT_EQ(FileType::TBD_V5, RemovedFile->getFileType());
2121 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
2122 RemovedFile->getInstallName());
2124 TargetList AllTargets = {
2125 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
2126 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
2128 EXPECT_EQ(mapToPlatformSet(AllTargets), RemovedFile->getPlatforms());
2129 EXPECT_EQ(mapToArchitectureSet(AllTargets), RemovedFile->getArchitectures());
2131 EXPECT_EQ(PackedVersion(1, 2, 0), RemovedFile->getCurrentVersion());
2132 EXPECT_EQ(PackedVersion(1, 1, 0), RemovedFile->getCompatibilityVersion());
2133 EXPECT_TRUE(RemovedFile->isApplicationExtensionSafe());
2134 EXPECT_FALSE(RemovedFile->isTwoLevelNamespace());
2135 EXPECT_EQ(0U, RemovedFile->documents().size());
2137 InterfaceFileRef ClientA("ClientA", AllTargets);
2138 InterfaceFileRef ClientB("ClientB", AllTargets);
2139 EXPECT_EQ(2U, RemovedFile->allowableClients().size());
2140 EXPECT_EQ(ClientA, RemovedFile->allowableClients().at(0));
2141 EXPECT_EQ(ClientB, RemovedFile->allowableClients().at(1));
2143 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
2144 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
2145 EXPECT_EQ(2U, RemovedFile->reexportedLibraries().size());
2146 EXPECT_EQ(ReexportA, RemovedFile->reexportedLibraries().at(0));
2147 EXPECT_EQ(ReexportB, RemovedFile->reexportedLibraries().at(1));
2149 EXPECT_EQ(0u, RemovedFile->rpaths().size());
2151 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},
2152 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
2153 EXPECT_EQ(Umbrellas, RemovedFile->umbrellas());
2155 ExportedSymbolSeq Exports, Reexports, Undefineds;
2156 for (const auto *Sym : RemovedFile->symbols()) {
2157 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
2158 ExportedSymbol Temp =
2159 ExportedSymbol{Sym->getKind(),
2160 std::string(Sym->getName()),
2161 Sym->isWeakDefined() || Sym->isWeakReferenced(),
2162 Sym->isThreadLocalValue(),
2163 Sym->isData(),
2164 SymTargets};
2165 if (Sym->isUndefined())
2166 Undefineds.emplace_back(std::move(Temp));
2167 else
2168 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
2169 : Exports.emplace_back(std::move(Temp));
2171 llvm::sort(Exports);
2172 llvm::sort(Reexports);
2173 llvm::sort(Undefineds);
2175 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};
2177 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
2178 {SymbolKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
2179 {SymbolKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
2180 {SymbolKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},
2182 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
2183 {SymbolKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
2184 {SymbolKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
2185 {SymbolKind::ObjectiveCClass, "ClassRexport", false, false, true,
2186 MacOSTargets},
2189 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
2190 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
2191 EXPECT_EQ(0U, Undefineds.size());
2192 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
2193 std::begin(ExpectedExportedSymbols)));
2194 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
2195 std::begin(ExpectedReexportedSymbols)));
2198 TEST(TBDv5, InlineIF) {
2199 static const char UmbrellaFile[] = R"({
2200 "tapi_tbd_version": 5,
2201 "main_library": {
2202 "target_info": [
2204 "target": "x86_64-macos",
2205 "min_deployment": "10.14"
2208 "target": "arm64-macos",
2209 "min_deployment": "10.14"
2212 "install_names": [
2214 "name": "/S/L/F/Foo.framework/Foo"
2217 "current_versions": [
2219 "version": "1.2"
2222 "reexported_libraries": [
2224 "names": [
2225 "/u/l/l/libfoo.dylib",
2226 "/u/l/l/libbar.dylib"
2230 }})";
2232 static const char ReexportFile[] = R"({
2233 "tapi_tbd_version": 5,
2234 "main_library": {
2235 "target_info": [
2237 "target": "x86_64-macos",
2238 "min_deployment": "10.14"
2241 "target": "arm64-macos",
2242 "min_deployment": "10.14"
2245 "install_names": [
2247 "name" : "/u/l/l/libfoo.dylib"
2250 "current_versions": [
2252 "version": "1"
2255 "rpaths": [
2257 "targets": [
2258 "x86_64-macos"
2260 "paths": [
2261 "@executable_path/.../Frameworks"
2265 "exported_symbols": [
2267 "targets": [
2268 "x86_64-macos",
2269 "arm64-macos"
2271 "data": {
2272 "global": [
2273 "_global"
2275 "objc_class": [
2276 "ClassA"
2278 "weak": [],
2279 "thread_local": []
2282 ]}})";
2284 Expected<TBDFile> UmbrellaResult =
2285 TextAPIReader::get(MemoryBufferRef(UmbrellaFile, "Test.tbd"));
2286 EXPECT_TRUE(!!UmbrellaResult);
2287 TBDFile Umbrella = std::move(UmbrellaResult.get());
2289 Expected<TBDFile> ReexportResult =
2290 TextAPIReader::get(MemoryBufferRef(ReexportFile, "Test.tbd"));
2291 EXPECT_TRUE(!!ReexportResult);
2292 TBDReexportFile Reexport = std::move(ReexportResult.get());
2293 Umbrella->inlineLibrary(Reexport);
2295 EXPECT_EQ(FileType::TBD_V5, Umbrella->getFileType());
2296 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
2297 Umbrella->getInstallName());
2299 TargetList AllTargets = {
2300 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
2301 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
2303 EXPECT_EQ(mapToPlatformSet(AllTargets), Umbrella->getPlatforms());
2304 EXPECT_EQ(mapToArchitectureSet(AllTargets), Umbrella->getArchitectures());
2306 EXPECT_EQ(PackedVersion(1, 2, 0), Umbrella->getCurrentVersion());
2307 EXPECT_EQ(PackedVersion(1, 0, 0), Umbrella->getCompatibilityVersion());
2308 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
2309 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
2310 EXPECT_EQ(2U, Umbrella->reexportedLibraries().size());
2311 EXPECT_EQ(ReexportA, Umbrella->reexportedLibraries().at(0));
2312 EXPECT_EQ(ReexportB, Umbrella->reexportedLibraries().at(1));
2313 EXPECT_EQ(1U, Umbrella->documents().size());
2315 TBDReexportFile Document = Umbrella->documents().front();
2316 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());
2317 EXPECT_EQ(0U, Document->getSwiftABIVersion());
2318 EXPECT_TRUE(Document->isTwoLevelNamespace());
2319 EXPECT_TRUE(Document->isApplicationExtensionSafe());
2320 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());
2321 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());
2323 ExportedSymbolSeq Exports;
2324 for (const auto *Sym : Document->symbols()) {
2325 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
2326 Exports.emplace_back(
2327 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
2328 Sym->isWeakDefined() || Sym->isWeakReferenced(),
2329 Sym->isThreadLocalValue(), Sym->isData(), SymTargets});
2331 llvm::sort(Exports);
2333 ExportedSymbolSeq ExpectedExports = {
2334 {SymbolKind::GlobalSymbol, "_global", false, false, true, AllTargets},
2335 {SymbolKind::ObjectiveCClass, "ClassA", false, false, true, AllTargets},
2337 EXPECT_EQ(ExpectedExports.size(), Exports.size());
2338 EXPECT_TRUE(
2339 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
2341 } // end namespace TBDv5