[flang][cuda] Do not register global constants (#118582)
[llvm-project.git] / llvm / unittests / TextAPI / TextStubV5Tests.cpp
blob24577b3ec6148eb2d1601f1738c04a1980ba4853
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_FALSE(File->isOSLibNotForSharedCache());
222 EXPECT_EQ(0U, File->documents().size());
224 InterfaceFileRef ClientA("ClientA", AllTargets);
225 InterfaceFileRef ClientB("ClientB", AllTargets);
226 EXPECT_EQ(2U, File->allowableClients().size());
227 EXPECT_EQ(ClientA, File->allowableClients().at(0));
228 EXPECT_EQ(ClientB, File->allowableClients().at(1));
230 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
231 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
232 EXPECT_EQ(2U, File->reexportedLibraries().size());
233 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));
234 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));
236 TargetToAttr RPaths = {
237 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},
239 EXPECT_EQ(RPaths, File->rpaths());
241 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},
242 {Target(AK_arm64, PLATFORM_MACOS), "System"},
243 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
244 EXPECT_EQ(Umbrellas, File->umbrellas());
246 ExportedSymbolSeq Exports, Reexports, Undefineds;
247 for (const auto *Sym : File->symbols()) {
248 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
249 ExportedSymbol Temp =
250 ExportedSymbol{Sym->getKind(),
251 std::string(Sym->getName()),
252 Sym->isWeakDefined() || Sym->isWeakReferenced(),
253 Sym->isThreadLocalValue(),
254 Sym->isData(),
255 SymTargets};
256 if (Sym->isUndefined())
257 Undefineds.emplace_back(std::move(Temp));
258 else
259 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
260 : Exports.emplace_back(std::move(Temp));
262 llvm::sort(Exports);
263 llvm::sort(Reexports);
264 llvm::sort(Undefineds);
266 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),
267 Target(AK_arm64, PLATFORM_MACOS)};
269 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
270 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
271 {EncodeKind::GlobalSymbol,
272 "_funcFoo",
273 false,
274 false,
275 false,
276 {Target(AK_x86_64, PLATFORM_MACOS)}},
277 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
278 {EncodeKind::GlobalSymbol,
279 "_globalVar",
280 false,
281 false,
282 true,
283 {Target(AK_x86_64, PLATFORM_MACOS)}},
284 {EncodeKind::ObjectiveCClass,
285 "ClassA",
286 false,
287 false,
288 true,
289 {Target(AK_x86_64, PLATFORM_MACOS)}},
290 {EncodeKind::ObjectiveCClass,
291 "ClassB",
292 false,
293 false,
294 true,
295 {Target(AK_x86_64, PLATFORM_MACOS)}},
296 {EncodeKind::ObjectiveCClass,
297 "ClassData",
298 false,
299 false,
300 true,
301 {Target(AK_x86_64, PLATFORM_MACOS)}},
302 {EncodeKind::ObjectiveCClassEHType,
303 "ClassA",
304 false,
305 false,
306 true,
307 {Target(AK_x86_64, PLATFORM_MACOS)}},
308 {EncodeKind::ObjectiveCClassEHType,
309 "ClassB",
310 false,
311 false,
312 true,
313 {Target(AK_x86_64, PLATFORM_MACOS)}},
314 {EncodeKind::ObjectiveCInstanceVariable,
315 "ClassA.ivar1",
316 false,
317 false,
318 true,
319 {Target(AK_x86_64, PLATFORM_MACOS)}},
320 {EncodeKind::ObjectiveCInstanceVariable,
321 "ClassA.ivar2",
322 false,
323 false,
324 true,
325 {Target(AK_x86_64, PLATFORM_MACOS)}},
326 {EncodeKind::ObjectiveCInstanceVariable,
327 "ClassC.ivar1",
328 false,
329 false,
330 true,
331 {Target(AK_x86_64, PLATFORM_MACOS)}},
333 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
334 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
335 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
336 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,
337 MacOSTargets},
340 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {
341 {EncodeKind::GlobalSymbol,
342 "_globalBind",
343 false,
344 false,
345 true,
346 {Target(AK_x86_64, PLATFORM_MACOS)}},
347 {EncodeKind::GlobalSymbol,
348 "referenced_sym",
349 true,
350 false,
351 true,
352 {Target(AK_x86_64, PLATFORM_MACOS)}},
355 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
356 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
357 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());
358 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
359 std::begin(ExpectedExportedSymbols)));
360 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
361 std::begin(ExpectedReexportedSymbols)));
362 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
363 std::begin(ExpectedUndefinedSymbols)));
365 EXPECT_TRUE(
366 File->getSymbol(EncodeKind::GlobalSymbol, "_globalBind").has_value());
369 TEST(TBDv5, ReadMultipleTargets) {
370 static const char TBDv5File[] = R"({
371 "tapi_tbd_version": 5,
372 "main_library": {
373 "target_info": [
375 "target": "x86_64-macos",
376 "min_deployment": "10.14"
379 "target": "arm64-macos",
380 "min_deployment": "10.14"
383 "target": "arm64-maccatalyst",
384 "min_deployment": "12.1"
387 "install_names":[
388 { "name":"/usr/lib/libFoo.dylib" }
390 "swift_abi":[ { "abi":8 } ],
391 "reexported_libraries": [
393 "targets": [ "x86_64-maccatalyst" ],
394 "names": [
395 "/u/l/l/libfoo.dylib",
396 "/u/l/l/libbar.dylib"
400 "targets": [ "arm64-maccatalyst" ],
401 "names": [ "/u/l/l/libArmOnly.dylib" ]
405 })";
407 Expected<TBDFile> Result =
408 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
409 EXPECT_TRUE(!!Result);
410 TBDFile File = std::move(Result.get());
411 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
412 EXPECT_EQ(std::string("/usr/lib/libFoo.dylib"), File->getInstallName());
413 EXPECT_TRUE(File->isApplicationExtensionSafe());
414 EXPECT_TRUE(File->isTwoLevelNamespace());
415 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
416 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
417 EXPECT_EQ(8U, File->getSwiftABIVersion());
419 TargetList AllTargets = {
420 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
421 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),
422 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),
424 EXPECT_EQ(mapToPlatformSet(AllTargets), File->getPlatforms());
425 EXPECT_EQ(mapToArchitectureSet(AllTargets), File->getArchitectures());
427 InterfaceFileRef ReexportA("/u/l/l/libArmOnly.dylib",
428 {Target(AK_arm64, PLATFORM_MACCATALYST)});
429 InterfaceFileRef ReexportB("/u/l/l/libbar.dylib",
430 {Target(AK_x86_64, PLATFORM_MACCATALYST)});
431 InterfaceFileRef ReexportC("/u/l/l/libfoo.dylib",
432 {Target(AK_x86_64, PLATFORM_MACCATALYST)});
433 EXPECT_EQ(3U, File->reexportedLibraries().size());
434 EXPECT_EQ(ReexportA, File->reexportedLibraries().at(0));
435 EXPECT_EQ(ReexportB, File->reexportedLibraries().at(1));
436 EXPECT_EQ(ReexportC, File->reexportedLibraries().at(2));
439 TEST(TBDv5, ReadMultipleDocuments) {
440 static const char TBDv5File[] = R"({
441 "tapi_tbd_version": 5,
442 "main_library": {
443 "target_info": [
445 "target": "armv7-ios",
446 "min_deployment": "11.0"
449 "install_names":[
450 { "name":"/S/L/F/Foo.framework/Foo" }
452 "reexported_libraries": [
453 { "names": ["/u/l/l/libfoo.dylib"] }
456 "libraries": [
458 "target_info": [
460 "target": "armv7-ios",
461 "min_deployment": "11.0"
464 "install_names":[
465 { "name":"/u/l/l/libfoo.dylib" }
467 "flags":[
468 { "attributes": ["not_app_extension_safe"] }
470 "exported_symbols": [
472 "data": {
473 "thread_local": [ "_globalVar" ],
474 "objc_class": [ "ClassData", "ClassA", "ClassB"],
475 "objc_eh_type": [ "ClassA", "ClassB" ]
477 "text": {
478 "global": [ "_funcFoo" ]
483 ]})";
485 Expected<TBDFile> Result =
486 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
487 EXPECT_TRUE(!!Result);
488 TBDFile File = std::move(Result.get());
489 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
490 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());
491 EXPECT_TRUE(File->isTwoLevelNamespace());
492 EXPECT_TRUE(File->isApplicationExtensionSafe());
494 TargetList Targets(File->targets().begin(), File->targets().end());
495 Target iOSTarget(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0));
496 EXPECT_EQ(TargetList{iOSTarget}, Targets);
497 std::vector<const Symbol *> Symbols(File->symbols().begin(),
498 File->symbols().end());
499 EXPECT_EQ(0U, Symbols.size());
501 InterfaceFileRef Reexport("/u/l/l/libfoo.dylib", {iOSTarget});
502 EXPECT_EQ(1U, File->reexportedLibraries().size());
503 EXPECT_EQ(Reexport, File->reexportedLibraries().at(0));
505 // Check inlined library.
506 EXPECT_EQ(1U, File->documents().size());
507 TBDReexportFile Document = File->documents().front();
508 Targets = {Document->targets().begin(), Document->targets().end()};
509 EXPECT_EQ(TargetList{iOSTarget}, Targets);
510 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());
511 EXPECT_EQ(0U, Document->getSwiftABIVersion());
512 EXPECT_TRUE(Document->isTwoLevelNamespace());
513 EXPECT_FALSE(Document->isApplicationExtensionSafe());
515 ExportedSymbolSeq Exports;
516 for (const auto *Sym : Document->symbols())
517 Exports.emplace_back(
518 ExportedSymbol{Sym->getKind(),
519 std::string(Sym->getName()),
520 Sym->isWeakDefined() || Sym->isWeakReferenced(),
521 Sym->isThreadLocalValue(),
522 Sym->isData(),
523 {iOSTarget}});
525 llvm::sort(Exports);
526 ExportedSymbolSeq ExpectedExports = {
527 {EncodeKind::GlobalSymbol, "_funcFoo", false, false, false, {iOSTarget}},
528 {EncodeKind::GlobalSymbol, "_globalVar", false, true, true, {iOSTarget}},
529 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, {iOSTarget}},
530 {EncodeKind::ObjectiveCClass, "ClassB", false, false, true, {iOSTarget}},
531 {EncodeKind::ObjectiveCClass,
532 "ClassData",
533 false,
534 false,
535 true,
536 {iOSTarget}},
537 {EncodeKind::ObjectiveCClassEHType,
538 "ClassA",
539 false,
540 false,
541 true,
542 {iOSTarget}},
543 {EncodeKind::ObjectiveCClassEHType,
544 "ClassB",
545 false,
546 false,
547 true,
548 {iOSTarget}},
551 EXPECT_EQ(ExpectedExports.size(), Exports.size());
552 EXPECT_TRUE(
553 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
556 TEST(TBDv5, WriteFile) {
557 static const char TBDv5File[] = R"({
558 "tapi_tbd_version": 5,
559 "main_library": {
560 "target_info": [
562 "target": "x86_64-macos",
563 "min_deployment": "10.14"
566 "target": "arm64-macos",
567 "min_deployment": "10.14"
570 "target": "arm64-maccatalyst",
571 "min_deployment": "12.1"
574 "install_names": [
576 "name": "@rpath/S/L/F/Foo.framework/Foo"
579 "current_versions": [
581 "version": "1.2"
584 "compatibility_versions": [
585 { "version": "1.1" }
587 "flags": [
589 "attributes": [
590 "flat_namespace"
594 "rpaths": [
596 "targets": [
597 "x86_64-macos"
599 "paths": [
600 "@executable_path/.../Frameworks"
604 "parent_umbrellas": [
606 "umbrella": "System"
609 "allowable_clients": [
611 "clients": [
612 "ClientA",
613 "ClientB"
617 "reexported_libraries": [
619 "names": [
620 "/u/l/l/libfoo.dylib",
621 "/u/l/l/libbar.dylib"
625 "exported_symbols": [
627 "targets": [
628 "x86_64-macos",
629 "arm64-macos"
631 "data": {
632 "global": [
633 "_global"
635 "objc_class": [
636 "ClassA"
638 "weak": [],
639 "thread_local": []
641 "text": {
642 "global": [
643 "_func"
645 "weak": [],
646 "thread_local": []
650 "targets": [
651 "x86_64-macos"
653 "data": {
654 "global": [
655 "_globalVar"
657 "objc_class": [
658 "ClassA",
659 "ClassB",
660 "ClassData"
662 "objc_eh_type": [
663 "ClassA",
664 "ClassB"
666 "objc_ivar": [
667 "ClassA.ivar1",
668 "ClassA.ivar2",
669 "ClassC.ivar1"
672 "text": {
673 "global": [
674 "_funcFoo"
679 "reexported_symbols": [
681 "data": {
682 "global": [
683 "_globalRe"
685 "objc_class": [
686 "ClassRexport"
689 "text": {
690 "global": [
691 "_funcA"
696 "undefined_symbols": [
698 "targets": [
699 "x86_64-macos"
701 "data": {
702 "global": [
703 "_globalBind"
705 "weak": [
706 "referenced_sym"
711 }})";
713 InterfaceFile File;
714 File.setFileType(FileType::TBD_V5);
716 TargetList AllTargets = {
717 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
718 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),
719 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),
721 File.addTargets(AllTargets);
722 File.setInstallName("@rpath/S/L/F/Foo.framework/Foo");
723 File.setCurrentVersion(PackedVersion(1, 2, 0));
724 File.setCompatibilityVersion(PackedVersion(1, 1, 0));
725 File.addRPath("@executable_path/.../Frameworks", AllTargets[0]);
727 for (const auto &Targ : AllTargets) {
728 File.addParentUmbrella(Targ, "System");
729 File.addAllowableClient("ClientA", Targ);
730 File.addAllowableClient("ClientB", Targ);
731 File.addReexportedLibrary("/u/l/l/libfoo.dylib", Targ);
732 File.addReexportedLibrary("/u/l/l/libbar.dylib", Targ);
735 SymbolFlags Flags = SymbolFlags::None;
736 // Exports.
737 File.addSymbol(EncodeKind::GlobalSymbol, "_global",
738 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);
739 File.addSymbol(EncodeKind::GlobalSymbol, "_func",
740 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Text);
741 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassA",
742 {AllTargets[0], AllTargets[1]}, Flags | SymbolFlags::Data);
743 File.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", {AllTargets[0]},
744 Flags | SymbolFlags::Text);
745 File.addSymbol(EncodeKind::GlobalSymbol, "_globalVar", {AllTargets[0]},
746 Flags | SymbolFlags::Data);
747 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassData", {AllTargets[0]},
748 Flags | SymbolFlags::Data);
749 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassA", {AllTargets[0]},
750 Flags | SymbolFlags::Data);
751 File.addSymbol(EncodeKind::ObjectiveCClassEHType, "ClassB", {AllTargets[0]},
752 Flags | SymbolFlags::Data);
753 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar1",
754 {AllTargets[0]}, Flags | SymbolFlags::Data);
755 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassA.ivar2",
756 {AllTargets[0]}, Flags | SymbolFlags::Data);
757 File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "ClassC.ivar1",
758 {AllTargets[0]}, Flags | SymbolFlags::Data);
760 // Reexports.
761 Flags = SymbolFlags::Rexported;
762 File.addSymbol(EncodeKind::GlobalSymbol, "_globalRe", AllTargets,
763 Flags | SymbolFlags::Data);
764 File.addSymbol(EncodeKind::GlobalSymbol, "_funcA", AllTargets,
765 Flags | SymbolFlags::Text);
766 File.addSymbol(EncodeKind::ObjectiveCClass, "ClassRexport", AllTargets,
767 Flags | SymbolFlags::Data);
769 // Undefineds.
770 Flags = SymbolFlags::Undefined;
771 File.addSymbol(EncodeKind::GlobalSymbol, "_globalBind", {AllTargets[0]},
772 Flags | SymbolFlags::Data);
773 File.addSymbol(EncodeKind::GlobalSymbol, "referenced_sym", {AllTargets[0]},
774 Flags | SymbolFlags::Data | SymbolFlags::WeakReferenced);
776 File.setTwoLevelNamespace(false);
777 File.setApplicationExtensionSafe(true);
779 // Write out file then process it back into IF and compare equality
780 // against TBDv5File.
781 SmallString<4096> Buffer;
782 raw_svector_ostream OS(Buffer);
783 Error Result = TextAPIWriter::writeToStream(OS, File);
784 EXPECT_FALSE(Result);
786 Expected<TBDFile> Input =
787 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));
788 EXPECT_TRUE(!!Input);
789 TBDFile InputFile = std::move(Input.get());
791 Expected<TBDFile> Output =
792 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
793 EXPECT_TRUE(!!Output);
794 TBDFile OutputFile = std::move(Output.get());
795 EXPECT_EQ(*InputFile, *OutputFile);
798 TEST(TBDv5, WriteMultipleDocuments) {
799 static const char TBDv5File[] = R"({
800 "tapi_tbd_version": 5,
801 "main_library": {
802 "target_info": [
804 "target": "armv7-ios",
805 "min_deployment": "11.0"
808 "install_names":[
809 { "name":"/S/L/F/Foo.framework/Foo" }
811 "reexported_libraries": [
812 { "names": ["/u/l/l/libfoo.dylib"]
816 "libraries": [
818 "target_info": [
820 "target": "armv7-ios",
821 "min_deployment": "11.0"
824 "target": "armv7s-ios",
825 "min_deployment": "11.0"
828 "install_names":[
829 { "name":"/u/l/l/libfoo.dylib" }
831 "current_versions": [
833 "version": "2.1.1"
836 "rpaths": [
838 "targets": [
839 "armv7-ios"
841 "paths": [
842 "@executable_path/.../Frameworks"
845 "reexported_libraries": [ { "names": ["@rpath/libfoo.dylib"] } ],
846 "flags":[
847 { "attributes": ["not_app_extension_safe"] }
849 "exported_symbols": [
851 "text": {
852 "global": [ "_funcFoo" ]
858 "target_info": [
860 "target": "armv7-ios",
861 "min_deployment": "11.0"
864 "install_names":[
865 { "name":"@rpath/libfoo.dylib" }
867 "exported_symbols": [
869 "data": {
870 "global": [ "_varFooBaz" ]
875 ]})";
877 InterfaceFile File;
878 File.setFileType(FileType::TBD_V5);
880 TargetList AllTargets = {
881 Target(AK_armv7, PLATFORM_IOS, VersionTuple(11, 0)),
882 Target(AK_armv7s, PLATFORM_IOS, VersionTuple(11, 0)),
884 File.setInstallName("/S/L/F/Foo.framework/Foo");
885 File.addTarget(AllTargets[0]);
886 File.setCurrentVersion(PackedVersion(1, 0, 0));
887 File.setCompatibilityVersion(PackedVersion(1, 0, 0));
888 File.addReexportedLibrary("/u/l/l/libfoo.dylib", AllTargets[0]);
889 File.setTwoLevelNamespace();
890 File.setApplicationExtensionSafe(true);
892 InterfaceFile NestedFile;
893 NestedFile.setFileType(FileType::TBD_V5);
894 NestedFile.setInstallName("/u/l/l/libfoo.dylib");
895 NestedFile.addTargets(AllTargets);
896 NestedFile.setCompatibilityVersion(PackedVersion(1, 0, 0));
897 NestedFile.setTwoLevelNamespace();
898 NestedFile.setApplicationExtensionSafe(false);
899 NestedFile.setCurrentVersion(PackedVersion(2, 1, 1));
900 NestedFile.addRPath("@executable_path/.../Frameworks", AllTargets[0]);
901 for (const auto &Targ : AllTargets)
902 NestedFile.addReexportedLibrary("@rpath/libfoo.dylib", Targ);
903 NestedFile.addSymbol(EncodeKind::GlobalSymbol, "_funcFoo", AllTargets,
904 SymbolFlags::Text);
905 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFile)));
907 InterfaceFile NestedFileB;
908 NestedFileB.setFileType(FileType::TBD_V5);
909 NestedFileB.setInstallName("@rpath/libfoo.dylib");
910 NestedFileB.addTarget(AllTargets[0]);
911 NestedFileB.setCompatibilityVersion(PackedVersion(1, 0, 0));
912 NestedFileB.setCurrentVersion(PackedVersion(1, 0, 0));
913 NestedFileB.setTwoLevelNamespace();
914 NestedFileB.setApplicationExtensionSafe(true);
915 NestedFileB.addSymbol(EncodeKind::GlobalSymbol, "_varFooBaz", {AllTargets[0]},
916 SymbolFlags::Data);
917 File.addDocument(std::make_shared<InterfaceFile>(std::move(NestedFileB)));
919 // Write out file then process it back into IF and compare equality
920 // against TBDv5File.
921 SmallString<4096> Buffer;
922 raw_svector_ostream OS(Buffer);
923 Error Result = TextAPIWriter::writeToStream(OS, File, FileType::Invalid,
924 /*Compact=*/true);
925 EXPECT_FALSE(Result);
927 Expected<TBDFile> Input =
928 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Input.tbd"));
929 EXPECT_TRUE(!!Input);
930 TBDFile InputFile = std::move(Input.get());
932 Expected<TBDFile> Output =
933 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
934 EXPECT_TRUE(!!Output);
935 TBDFile OutputFile = std::move(Output.get());
936 EXPECT_EQ(*InputFile, *OutputFile);
939 TEST(TBDv5, Target_Simulator) {
940 static const char TBDv5File[] = R"({
941 "tapi_tbd_version": 5,
942 "main_library": {
943 "target_info": [
945 "target": "arm64-ios-simulator",
946 "min_deployment": "11.0"
949 "target": "x86_64-ios-simulator",
950 "min_deployment": "11.3"
953 "install_names":[
954 { "name":"/S/L/F/Foo.framework/Foo" }
956 }})";
958 Expected<TBDFile> Result =
959 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
960 EXPECT_TRUE(!!Result);
961 TBDFile File = std::move(Result.get());
962 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
963 TargetList ExpectedTargets = {
964 Target(AK_x86_64, PLATFORM_IOSSIMULATOR, VersionTuple(11, 3)),
965 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0)),
967 TargetList Targets{File->targets().begin(), File->targets().end()};
968 llvm::sort(Targets);
969 EXPECT_EQ(Targets, ExpectedTargets);
971 SmallString<4096> Buffer;
972 raw_svector_ostream OS(Buffer);
973 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
974 EXPECT_TRUE(!WriteResult);
976 Expected<TBDFile> Output =
977 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
978 EXPECT_TRUE(!!Output);
979 TBDFile WriteResultFile = std::move(Output.get());
980 EXPECT_EQ(*File, *WriteResultFile);
983 TEST(TBDv5, Target_UnsupportedMinOS) {
984 static const char TBDv5File[] = R"({
985 "tapi_tbd_version": 5,
986 "main_library": {
987 "target_info": [
989 "target": "arm64-macos",
990 "min_deployment": "10.14"
993 "target": "x86_64-macos",
994 "min_deployment": "10.14"
997 "install_names":[
998 { "name":"/S/L/F/Foo.framework/Foo" }
1000 }})";
1002 Expected<TBDFile> Result =
1003 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1004 EXPECT_TRUE(!!Result);
1005 TBDFile File = std::move(Result.get());
1006 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
1007 TargetList ExpectedTargets = {
1008 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
1009 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0)),
1011 TargetList Targets{File->targets().begin(), File->targets().end()};
1012 llvm::sort(Targets);
1013 EXPECT_EQ(Targets, ExpectedTargets);
1015 SmallString<4096> Buffer;
1016 raw_svector_ostream OS(Buffer);
1017 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
1018 EXPECT_TRUE(!WriteResult);
1020 Expected<TBDFile> Output =
1021 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
1022 EXPECT_TRUE(!!Output);
1023 TBDFile WriteResultFile = std::move(Output.get());
1024 EXPECT_EQ(*File, *WriteResultFile);
1027 TEST(TBDv5, MisspelledKey) {
1028 static const char TBDv5File[] = R"({
1029 "tapi_tbd_version": 5,
1030 "main_library": {
1031 "target_info": [
1033 "target": "arm64-ios-simulator",
1034 "min_deployment": "11.0"
1037 "intall_names":[
1038 { "name":"/S/L/F/Foo.framework/Foo" }
1040 }})";
1042 Expected<TBDFile> Result =
1043 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1044 EXPECT_FALSE(!!Result);
1045 std::string ErrorMessage = toString(Result.takeError());
1046 EXPECT_EQ("invalid install_names section\n", ErrorMessage);
1049 TEST(TBDv5, InvalidVersion) {
1050 static const char TBDv5File[] = R"({
1051 "tapi_tbd_version": 11,
1052 "main_library": {
1053 "target_info": [
1055 "target": "arm64-ios-simulator",
1056 "min_deployment": "11.0"
1059 "install_names":[
1060 { "name":"/S/L/F/Foo.framework/Foo" }
1062 }})";
1064 Expected<TBDFile> Result =
1065 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1066 EXPECT_FALSE(!!Result);
1067 std::string ErrorMessage = toString(Result.takeError());
1068 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);
1071 TEST(TBDv5, MissingRequiredKey) {
1072 static const char TBDv5File[] = R"({
1073 "main_library": {
1074 "target_info": [
1076 "target": "arm64-ios-simulator",
1077 "min_deployment": "11.0"
1080 "install_names":[
1081 { "name":"/S/L/F/Foo.framework/Foo" }
1083 }})";
1085 Expected<TBDFile> Result =
1086 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1087 EXPECT_FALSE(!!Result);
1088 std::string ErrorMessage = toString(Result.takeError());
1089 EXPECT_EQ("invalid tapi_tbd_version section\n", ErrorMessage);
1092 TEST(TBDv5, InvalidSymbols) {
1093 static const char TBDv5File[] = R"({
1094 "tapi_tbd_version": 5,
1095 "main_library": {
1096 "target_info": [
1098 "target": "arm64-driverkit",
1099 "min_deployment": "11.0"
1102 "install_names":[
1103 { "name":"/S/L/F/Foo.framework/Foo" }
1105 "exported_symbols": [
1107 "daa": {
1108 "global": {
1109 "weak": []
1114 }})";
1116 Expected<TBDFile> Result =
1117 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1118 EXPECT_FALSE(!!Result);
1119 std::string ErrorMessage = toString(Result.takeError());
1120 EXPECT_EQ("invalid exported_symbols section\n", ErrorMessage);
1123 TEST(TBDv5, DefaultMinOS) {
1124 static const char TBDv5File[] = R"({
1125 "tapi_tbd_version": 5,
1126 "main_library": {
1127 "target_info": [
1129 "target": "arm64-ios-simulator"
1132 "install_names":[
1133 { "name":"/S/L/F/Foo.framework/Foo" }
1135 }})";
1137 Expected<TBDFile> Result =
1138 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1139 EXPECT_TRUE(!!Result);
1140 TBDFile File = std::move(Result.get());
1141 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
1142 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"), File->getInstallName());
1143 EXPECT_TRUE(File->targets().begin() != File->targets().end());
1144 EXPECT_EQ(*File->targets().begin(),
1145 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(0, 0)));
1148 TEST(TBDv5, InvalidMinOS) {
1149 static const char TBDv5File[] = R"({
1150 "tapi_tbd_version": 5,
1151 "main_library": {
1152 "target_info": [
1154 "target": "arm64-ios-simulator",
1155 "min_deployment": "swift-abi"
1158 "install_names":[
1159 { "name":"/S/L/F/Foo.framework/Foo" }
1161 }})";
1163 Expected<TBDFile> Result =
1164 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1165 EXPECT_FALSE(!!Result);
1166 std::string ErrorMessage = toString(Result.takeError());
1167 EXPECT_EQ("invalid min_deployment section\n", ErrorMessage);
1170 TEST(TBDv5, SimSupport) {
1171 static const char TBDv5File[] = R"({
1172 "tapi_tbd_version": 5,
1173 "main_library": {
1174 "target_info": [
1176 "target": "arm64-macos",
1177 "min_deployment": "11.1"
1180 "install_names":[
1181 { "name":"/S/L/F/Foo.framework/Foo" }
1183 "flags":[
1184 { "attributes": ["sim_support"] }
1186 }})";
1188 Expected<TBDFile> Result =
1189 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1190 EXPECT_TRUE(!!Result);
1191 Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));
1192 TBDFile ReadFile = std::move(Result.get());
1193 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());
1194 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1195 ReadFile->getInstallName());
1196 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());
1197 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);
1198 EXPECT_TRUE(ReadFile->hasSimulatorSupport());
1201 TEST(TBDv5, NotForSharedCache) {
1202 static const char TBDv5File[] = R"({
1203 "tapi_tbd_version": 5,
1204 "main_library": {
1205 "target_info": [
1207 "target": "arm64-macos",
1208 "min_deployment": "11.1"
1211 "install_names":[
1212 { "name":"/S/L/F/Foo.framework/Foo" }
1214 "flags":[
1215 { "attributes": ["not_for_dyld_shared_cache"] }
1217 }})";
1219 Expected<TBDFile> Result =
1220 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1221 EXPECT_TRUE(!!Result);
1222 Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 1));
1223 TBDFile ReadFile = std::move(Result.get());
1224 EXPECT_EQ(FileType::TBD_V5, ReadFile->getFileType());
1225 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1226 ReadFile->getInstallName());
1227 EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end());
1228 EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget);
1229 EXPECT_FALSE(ReadFile->hasSimulatorSupport());
1230 EXPECT_TRUE(ReadFile->isOSLibNotForSharedCache());
1233 TEST(TBDv5, ObjCInterfaces) {
1234 static const char TBDv5File[] = R"({
1235 "tapi_tbd_version": 5,
1236 "main_library": {
1237 "target_info": [
1239 "target": "arm64-ios-simulator",
1240 "min_deployment": "14.0"
1243 "install_names":[
1244 { "name":"/S/L/F/Foo.framework/Foo" }
1246 "exported_symbols": [
1248 "data": {
1249 "global": [
1250 "_global",
1251 "_OBJC_METACLASS_$_Standalone",
1252 "_OBJC_CLASS_$_Standalone2"
1254 "weak": ["_OBJC_EHTYPE_$_NSObject"],
1255 "objc_class": [
1256 "ClassA",
1257 "ClassB"
1259 "objc_eh_type": ["ClassA"]
1262 }})";
1264 Expected<TBDFile> Result =
1265 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1266 EXPECT_TRUE(!!Result);
1267 TBDFile File = std::move(Result.get());
1268 EXPECT_EQ(FileType::TBD_V5, File->getFileType());
1269 Target ExpectedTarget =
1270 Target(AK_arm64, PLATFORM_IOSSIMULATOR, VersionTuple(14, 0));
1271 EXPECT_EQ(*File->targets().begin(), ExpectedTarget);
1273 // Check Symbols.
1274 ExportedSymbolSeq Exports;
1275 for (const auto *Sym : File->symbols()) {
1276 ExportedSymbol Temp =
1277 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
1278 Sym->isWeakDefined() || Sym->isWeakReferenced(),
1279 Sym->isThreadLocalValue(), Sym->isData()};
1280 Exports.emplace_back(std::move(Temp));
1282 llvm::sort(Exports);
1284 std::vector<ExportedSymbol> ExpectedExports = {
1285 {EncodeKind::GlobalSymbol, "_OBJC_CLASS_$_Standalone2", false, false,
1286 true},
1287 {EncodeKind::GlobalSymbol, "_OBJC_EHTYPE_$_NSObject", true, false, true},
1288 {EncodeKind::GlobalSymbol, "_OBJC_METACLASS_$_Standalone", false, false,
1289 true},
1290 {EncodeKind::GlobalSymbol, "_global", false, false, true},
1291 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true},
1292 {EncodeKind::ObjectiveCClass, "ClassB", false, false, true},
1293 {EncodeKind::ObjectiveCClassEHType, "ClassA", false, false, true}};
1295 EXPECT_EQ(ExpectedExports.size(), Exports.size());
1296 EXPECT_TRUE(
1297 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
1299 SmallString<4096> Buffer;
1300 raw_svector_ostream OS(Buffer);
1301 Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
1302 EXPECT_TRUE(!WriteResult);
1304 Expected<TBDFile> Output =
1305 TextAPIReader::get(MemoryBufferRef(Buffer, "Output.tbd"));
1306 EXPECT_TRUE(!!Output);
1307 TBDFile WriteResultFile = std::move(Output.get());
1308 EXPECT_EQ(*File, *WriteResultFile);
1311 TEST(TBDv5, MergeIF) {
1312 static const char TBDv5FileA[] = R"({
1313 "tapi_tbd_version": 5,
1314 "main_library": {
1315 "target_info": [
1317 "target": "x86_64-macos",
1318 "min_deployment": "10.14"
1321 "target": "arm64-macos",
1322 "min_deployment": "10.14"
1325 "target": "arm64-maccatalyst",
1326 "min_deployment": "12.1"
1329 "flags": [
1331 "targets": [
1332 "x86_64-macos"
1334 "attributes": [
1335 "flat_namespace"
1339 "install_names": [
1341 "name": "/S/L/F/Foo.framework/Foo"
1344 "current_versions": [
1346 "version": "1.2"
1349 "compatibility_versions": [
1350 { "version": "1.1" }
1352 "rpaths": [
1354 "targets": [
1355 "x86_64-macos"
1357 "paths": [
1358 "@executable_path/.../Frameworks"
1362 "parent_umbrellas": [
1364 "umbrella": "System"
1367 "allowable_clients": [
1369 "clients": [
1370 "ClientA",
1371 "ClientB"
1375 "reexported_libraries": [
1377 "names": [
1378 "/u/l/l/libfoo.dylib",
1379 "/u/l/l/libbar.dylib"
1383 "exported_symbols": [
1385 "targets": [
1386 "x86_64-macos",
1387 "arm64-macos"
1389 "data": {
1390 "global": [
1391 "_global"
1393 "objc_class": [
1394 "ClassA"
1396 "weak": [],
1397 "thread_local": []
1399 "text": {
1400 "global": [
1401 "_func"
1403 "weak": [],
1404 "thread_local": []
1408 "targets": [
1409 "x86_64-macos"
1411 "data": {
1412 "global": [
1413 "_globalVar"
1415 "objc_class": [
1416 "ClassA",
1417 "ClassB",
1418 "ClassData"
1420 "objc_eh_type": [
1421 "ClassA",
1422 "ClassB"
1424 "objc_ivar": [
1425 "ClassA.ivar1",
1426 "ClassA.ivar2",
1427 "ClassC.ivar1"
1430 "text": {
1431 "global": [
1432 "_funcFoo"
1437 "reexported_symbols": [
1439 "targets": [
1440 "x86_64-macos",
1441 "arm64-macos"
1443 "data": {
1444 "global": [
1445 "_globalRe"
1447 "objc_class": [
1448 "ClassRexport"
1451 "text": {
1452 "global": [
1453 "_funcA"
1458 "undefined_symbols": [
1460 "targets": [
1461 "x86_64-macos"
1463 "data": {
1464 "global": [
1465 "_globalBind"
1467 "weak": [
1468 "referenced_sym"
1474 "libraries": []
1475 })";
1477 static const char TBDv5FileB[] = R"({
1478 "tapi_tbd_version": 5,
1479 "main_library": {
1480 "target_info": [
1482 "target": "x86_64-macos",
1483 "min_deployment": "10.14"
1486 "target": "arm64-macos",
1487 "min_deployment": "10.14"
1490 "target": "arm64-maccatalyst",
1491 "min_deployment": "12.1"
1494 "flags": [
1496 "targets": [
1497 "x86_64-macos"
1499 "attributes": [
1500 "flat_namespace"
1504 "install_names": [
1506 "name": "/S/L/F/Foo.framework/Foo"
1509 "current_versions": [
1511 "version": "1.2"
1514 "compatibility_versions": [
1515 { "version": "1.1" }
1517 "exported_symbols": [
1519 "targets": [
1520 "x86_64-macos",
1521 "arm64-macos"
1523 "data": {
1524 "global": [
1525 "_globalZ"
1527 "objc_class": [
1528 "ClassZ"
1530 "weak": [],
1531 "thread_local": []
1533 "text": {
1534 "global": [
1535 "_funcZ"
1537 "weak": [],
1538 "thread_local": []
1542 "targets": [
1543 "x86_64-macos"
1545 "data": {
1546 "global": [
1547 "_globalVarZ"
1549 "objc_class": [
1550 "ClassZ",
1551 "ClassF"
1553 "objc_eh_type": [
1554 "ClassZ",
1555 "ClassF"
1557 "objc_ivar": [
1558 "ClassZ.ivar1",
1559 "ClassZ.ivar2",
1560 "ClassF.ivar1"
1563 "text": {
1564 "global": [
1565 "_funcFooZ"
1571 "libraries": []
1572 })";
1574 Expected<TBDFile> ResultA =
1575 TextAPIReader::get(MemoryBufferRef(TBDv5FileA, "Test.tbd"));
1576 EXPECT_TRUE(!!ResultA);
1577 TBDFile FileA = std::move(ResultA.get());
1579 Expected<TBDFile> ResultB =
1580 TextAPIReader::get(MemoryBufferRef(TBDv5FileB, "Test.tbd"));
1581 EXPECT_TRUE(!!ResultB);
1582 TBDFile FileB = std::move(ResultB.get());
1584 Expected<TBDFile> MergedResult = FileA->merge(FileB.get());
1585 EXPECT_TRUE(!!MergedResult);
1586 TBDFile MergedFile = std::move(MergedResult.get());
1588 EXPECT_EQ(FileType::TBD_V5, MergedFile->getFileType());
1589 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1590 MergedFile->getInstallName());
1591 TargetList AllTargets = {
1592 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
1593 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
1594 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
1596 EXPECT_EQ(mapToPlatformSet(AllTargets), MergedFile->getPlatforms());
1597 EXPECT_EQ(mapToArchitectureSet(AllTargets), MergedFile->getArchitectures());
1598 EXPECT_EQ(PackedVersion(1, 2, 0), MergedFile->getCurrentVersion());
1599 EXPECT_EQ(PackedVersion(1, 1, 0), MergedFile->getCompatibilityVersion());
1600 EXPECT_TRUE(MergedFile->isApplicationExtensionSafe());
1601 EXPECT_FALSE(MergedFile->isTwoLevelNamespace());
1602 EXPECT_EQ(0U, MergedFile->documents().size());
1603 InterfaceFileRef ClientA("ClientA", AllTargets);
1604 InterfaceFileRef ClientB("ClientB", AllTargets);
1605 EXPECT_EQ(2U, MergedFile->allowableClients().size());
1606 EXPECT_EQ(ClientA, MergedFile->allowableClients().at(0));
1607 EXPECT_EQ(ClientB, MergedFile->allowableClients().at(1));
1609 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
1610 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
1611 EXPECT_EQ(2U, MergedFile->reexportedLibraries().size());
1612 EXPECT_EQ(ReexportA, MergedFile->reexportedLibraries().at(0));
1613 EXPECT_EQ(ReexportB, MergedFile->reexportedLibraries().at(1));
1615 TargetToAttr RPaths = {
1616 {Target(AK_x86_64, PLATFORM_MACOS), "@executable_path/.../Frameworks"},
1618 EXPECT_EQ(RPaths, MergedFile->rpaths());
1620 TargetToAttr Umbrellas = {{Target(AK_x86_64, PLATFORM_MACOS), "System"},
1621 {Target(AK_arm64, PLATFORM_MACOS), "System"},
1622 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
1623 EXPECT_EQ(Umbrellas, MergedFile->umbrellas());
1625 ExportedSymbolSeq Exports, Reexports, Undefineds;
1626 for (const auto *Sym : MergedFile->symbols()) {
1627 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
1628 ExportedSymbol Temp =
1629 ExportedSymbol{Sym->getKind(),
1630 std::string(Sym->getName()),
1631 Sym->isWeakDefined() || Sym->isWeakReferenced(),
1632 Sym->isThreadLocalValue(),
1633 Sym->isData(),
1634 SymTargets};
1635 if (Sym->isUndefined())
1636 Undefineds.emplace_back(std::move(Temp));
1637 else
1638 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
1639 : Exports.emplace_back(std::move(Temp));
1641 llvm::sort(Exports);
1642 llvm::sort(Reexports);
1643 llvm::sort(Undefineds);
1645 TargetList MacOSTargets = {Target(AK_x86_64, PLATFORM_MACOS),
1646 Target(AK_arm64, PLATFORM_MACOS)};
1648 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
1649 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
1650 {EncodeKind::GlobalSymbol,
1651 "_funcFoo",
1652 false,
1653 false,
1654 false,
1655 {Target(AK_x86_64, PLATFORM_MACOS)}},
1656 {EncodeKind::GlobalSymbol,
1657 "_funcFooZ",
1658 false,
1659 false,
1660 false,
1661 {Target(AK_x86_64, PLATFORM_MACOS)}},
1662 {EncodeKind::GlobalSymbol, "_funcZ", false, false, false, MacOSTargets},
1663 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
1664 {EncodeKind::GlobalSymbol,
1665 "_globalVar",
1666 false,
1667 false,
1668 true,
1669 {Target(AK_x86_64, PLATFORM_MACOS)}},
1670 {EncodeKind::GlobalSymbol,
1671 "_globalVarZ",
1672 false,
1673 false,
1674 true,
1675 {Target(AK_x86_64, PLATFORM_MACOS)}},
1676 {EncodeKind::GlobalSymbol, "_globalZ", false, false, true, MacOSTargets},
1677 {EncodeKind::ObjectiveCClass,
1678 "ClassA",
1679 false,
1680 false,
1681 true,
1682 {Target(AK_x86_64, PLATFORM_MACOS)}},
1683 {EncodeKind::ObjectiveCClass,
1684 "ClassB",
1685 false,
1686 false,
1687 true,
1688 {Target(AK_x86_64, PLATFORM_MACOS)}},
1689 {EncodeKind::ObjectiveCClass,
1690 "ClassData",
1691 false,
1692 false,
1693 true,
1694 {Target(AK_x86_64, PLATFORM_MACOS)}},
1695 {EncodeKind::ObjectiveCClass,
1696 "ClassF",
1697 false,
1698 false,
1699 true,
1700 {Target(AK_x86_64, PLATFORM_MACOS)}},
1701 {EncodeKind::ObjectiveCClass,
1702 "ClassZ",
1703 false,
1704 false,
1705 true,
1706 {Target(AK_x86_64, PLATFORM_MACOS)}},
1707 {EncodeKind::ObjectiveCClassEHType,
1708 "ClassA",
1709 false,
1710 false,
1711 true,
1712 {Target(AK_x86_64, PLATFORM_MACOS)}},
1713 {EncodeKind::ObjectiveCClassEHType,
1714 "ClassB",
1715 false,
1716 false,
1717 true,
1718 {Target(AK_x86_64, PLATFORM_MACOS)}},
1719 {EncodeKind::ObjectiveCClassEHType,
1720 "ClassF",
1721 false,
1722 false,
1723 true,
1724 {Target(AK_x86_64, PLATFORM_MACOS)}},
1725 {EncodeKind::ObjectiveCClassEHType,
1726 "ClassZ",
1727 false,
1728 false,
1729 true,
1730 {Target(AK_x86_64, PLATFORM_MACOS)}},
1731 {EncodeKind::ObjectiveCInstanceVariable,
1732 "ClassA.ivar1",
1733 false,
1734 false,
1735 true,
1736 {Target(AK_x86_64, PLATFORM_MACOS)}},
1737 {EncodeKind::ObjectiveCInstanceVariable,
1738 "ClassA.ivar2",
1739 false,
1740 false,
1741 true,
1742 {Target(AK_x86_64, PLATFORM_MACOS)}},
1743 {EncodeKind::ObjectiveCInstanceVariable,
1744 "ClassC.ivar1",
1745 false,
1746 false,
1747 true,
1748 {Target(AK_x86_64, PLATFORM_MACOS)}},
1749 {EncodeKind::ObjectiveCInstanceVariable,
1750 "ClassF.ivar1",
1751 false,
1752 false,
1753 true,
1754 {Target(AK_x86_64, PLATFORM_MACOS)}},
1755 {EncodeKind::ObjectiveCInstanceVariable,
1756 "ClassZ.ivar1",
1757 false,
1758 false,
1759 true,
1760 {Target(AK_x86_64, PLATFORM_MACOS)}},
1761 {EncodeKind::ObjectiveCInstanceVariable,
1762 "ClassZ.ivar2",
1763 false,
1764 false,
1765 true,
1766 {Target(AK_x86_64, PLATFORM_MACOS)}},
1769 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
1770 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
1771 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
1772 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,
1773 MacOSTargets},
1776 std::vector<ExportedSymbol> ExpectedUndefinedSymbols = {
1777 {EncodeKind::GlobalSymbol,
1778 "_globalBind",
1779 false,
1780 false,
1781 true,
1782 {Target(AK_x86_64, PLATFORM_MACOS)}},
1783 {EncodeKind::GlobalSymbol,
1784 "referenced_sym",
1785 true,
1786 false,
1787 true,
1788 {Target(AK_x86_64, PLATFORM_MACOS)}},
1791 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
1792 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
1793 EXPECT_EQ(ExpectedUndefinedSymbols.size(), Undefineds.size());
1794 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
1795 std::begin(ExpectedExportedSymbols)));
1796 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
1797 std::begin(ExpectedReexportedSymbols)));
1798 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
1799 std::begin(ExpectedUndefinedSymbols)));
1802 TEST(TBDv5, ExtractIF) {
1803 static const char TBDv5File[] = R"({
1804 "tapi_tbd_version": 5,
1805 "main_library": {
1806 "target_info": [
1808 "target": "x86_64-macos",
1809 "min_deployment": "10.14"
1812 "target": "arm64-macos",
1813 "min_deployment": "10.14"
1816 "target": "arm64-maccatalyst",
1817 "min_deployment": "12.1"
1820 "flags": [
1822 "targets": [
1823 "x86_64-macos"
1825 "attributes": [
1826 "flat_namespace"
1830 "install_names": [
1832 "name": "/S/L/F/Foo.framework/Foo"
1835 "current_versions": [
1837 "version": "1.2"
1840 "compatibility_versions": [
1841 { "version": "1.1" }
1843 "rpaths": [
1845 "targets": [
1846 "x86_64-macos"
1848 "paths": [
1849 "@executable_path/.../Frameworks"
1853 "parent_umbrellas": [
1855 "umbrella": "System"
1858 "allowable_clients": [
1860 "clients": [
1861 "ClientA",
1862 "ClientB"
1866 "reexported_libraries": [
1868 "names": [
1869 "/u/l/l/libfoo.dylib",
1870 "/u/l/l/libbar.dylib"
1874 "exported_symbols": [
1876 "targets": [
1877 "x86_64-macos",
1878 "arm64-macos"
1880 "data": {
1881 "global": [
1882 "_global"
1884 "objc_class": [
1885 "ClassA"
1887 "weak": [],
1888 "thread_local": []
1890 "text": {
1891 "global": [
1892 "_func"
1894 "weak": [],
1895 "thread_local": []
1899 "targets": [
1900 "x86_64-macos"
1902 "data": {
1903 "global": [
1904 "_globalVar"
1906 "objc_class": [
1907 "ClassA",
1908 "ClassB",
1909 "ClassData"
1911 "objc_eh_type": [
1912 "ClassA",
1913 "ClassB"
1915 "objc_ivar": [
1916 "ClassA.ivar1",
1917 "ClassA.ivar2",
1918 "ClassC.ivar1"
1921 "text": {
1922 "global": [
1923 "_funcFoo"
1928 "reexported_symbols": [
1930 "targets": [
1931 "x86_64-macos",
1932 "arm64-macos"
1934 "data": {
1935 "global": [
1936 "_globalRe"
1938 "objc_class": [
1939 "ClassRexport"
1942 "text": {
1943 "global": [
1944 "_funcA"
1949 "undefined_symbols": [
1951 "targets": [
1952 "x86_64-macos"
1954 "data": {
1955 "global": [
1956 "_globalBind"
1958 "weak": [
1959 "referenced_sym"
1965 "libraries": []
1966 })";
1968 Expected<TBDFile> Result =
1969 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
1970 EXPECT_TRUE(!!Result);
1971 TBDFile File = std::move(Result.get());
1973 Expected<TBDFile> ExtractedResult = File->extract(AK_arm64);
1974 EXPECT_TRUE(!!ExtractedResult);
1975 TBDFile ExtractedFile = std::move(ExtractedResult.get());
1977 EXPECT_EQ(FileType::TBD_V5, ExtractedFile->getFileType());
1978 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
1979 ExtractedFile->getInstallName());
1981 TargetList AllTargets = {
1982 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
1983 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
1985 EXPECT_EQ(mapToPlatformSet(AllTargets), ExtractedFile->getPlatforms());
1986 EXPECT_EQ(mapToArchitectureSet(AllTargets),
1987 ExtractedFile->getArchitectures());
1989 EXPECT_EQ(PackedVersion(1, 2, 0), ExtractedFile->getCurrentVersion());
1990 EXPECT_EQ(PackedVersion(1, 1, 0), ExtractedFile->getCompatibilityVersion());
1991 EXPECT_TRUE(ExtractedFile->isApplicationExtensionSafe());
1992 EXPECT_FALSE(ExtractedFile->isTwoLevelNamespace());
1993 EXPECT_EQ(0U, ExtractedFile->documents().size());
1995 InterfaceFileRef ClientA("ClientA", AllTargets);
1996 InterfaceFileRef ClientB("ClientB", AllTargets);
1997 EXPECT_EQ(2U, ExtractedFile->allowableClients().size());
1998 EXPECT_EQ(ClientA, ExtractedFile->allowableClients().at(0));
1999 EXPECT_EQ(ClientB, ExtractedFile->allowableClients().at(1));
2001 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
2002 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
2003 EXPECT_EQ(2U, ExtractedFile->reexportedLibraries().size());
2004 EXPECT_EQ(ReexportA, ExtractedFile->reexportedLibraries().at(0));
2005 EXPECT_EQ(ReexportB, ExtractedFile->reexportedLibraries().at(1));
2007 EXPECT_EQ(0u, ExtractedFile->rpaths().size());
2009 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},
2010 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
2011 EXPECT_EQ(Umbrellas, ExtractedFile->umbrellas());
2013 ExportedSymbolSeq Exports, Reexports, Undefineds;
2014 for (const auto *Sym : ExtractedFile->symbols()) {
2015 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
2016 ExportedSymbol Temp =
2017 ExportedSymbol{Sym->getKind(),
2018 std::string(Sym->getName()),
2019 Sym->isWeakDefined() || Sym->isWeakReferenced(),
2020 Sym->isThreadLocalValue(),
2021 Sym->isData(),
2022 SymTargets};
2023 if (Sym->isUndefined())
2024 Undefineds.emplace_back(std::move(Temp));
2025 else
2026 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
2027 : Exports.emplace_back(std::move(Temp));
2029 llvm::sort(Exports);
2030 llvm::sort(Reexports);
2031 llvm::sort(Undefineds);
2033 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};
2035 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
2036 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
2037 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
2038 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},
2040 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
2041 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
2042 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
2043 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,
2044 MacOSTargets},
2047 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
2048 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
2049 EXPECT_EQ(0U, Undefineds.size());
2050 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
2051 std::begin(ExpectedExportedSymbols)));
2052 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
2053 std::begin(ExpectedReexportedSymbols)));
2056 TEST(TBDv5, RemoveIF) {
2057 static const char TBDv5File[] = R"({
2058 "tapi_tbd_version": 5,
2059 "main_library": {
2060 "target_info": [
2062 "target": "x86_64-macos",
2063 "min_deployment": "10.14"
2066 "target": "arm64-macos",
2067 "min_deployment": "10.14"
2070 "target": "arm64-maccatalyst",
2071 "min_deployment": "12.1"
2074 "flags": [
2076 "targets": [
2077 "x86_64-macos"
2079 "attributes": [
2080 "flat_namespace",
2081 "not_for_dyld_shared_cache"
2085 "install_names": [
2087 "name": "/S/L/F/Foo.framework/Foo"
2090 "current_versions": [
2092 "version": "1.2"
2095 "compatibility_versions": [
2096 { "version": "1.1" }
2098 "rpaths": [
2100 "targets": [
2101 "x86_64-macos"
2103 "paths": [
2104 "@executable_path/.../Frameworks"
2108 "parent_umbrellas": [
2110 "umbrella": "System"
2113 "allowable_clients": [
2115 "clients": [
2116 "ClientA",
2117 "ClientB"
2121 "reexported_libraries": [
2123 "names": [
2124 "/u/l/l/libfoo.dylib",
2125 "/u/l/l/libbar.dylib"
2129 "exported_symbols": [
2131 "targets": [
2132 "x86_64-macos",
2133 "arm64-macos"
2135 "data": {
2136 "global": [
2137 "_global"
2139 "objc_class": [
2140 "ClassA"
2142 "weak": [],
2143 "thread_local": []
2145 "text": {
2146 "global": [
2147 "_func"
2149 "weak": [],
2150 "thread_local": []
2154 "targets": [
2155 "x86_64-macos"
2157 "data": {
2158 "global": [
2159 "_globalVar"
2161 "objc_class": [
2162 "ClassA",
2163 "ClassB",
2164 "ClassData"
2166 "objc_eh_type": [
2167 "ClassA",
2168 "ClassB"
2170 "objc_ivar": [
2171 "ClassA.ivar1",
2172 "ClassA.ivar2",
2173 "ClassC.ivar1"
2176 "text": {
2177 "global": [
2178 "_funcFoo"
2183 "reexported_symbols": [
2185 "targets": [
2186 "x86_64-macos",
2187 "arm64-macos"
2189 "data": {
2190 "global": [
2191 "_globalRe"
2193 "objc_class": [
2194 "ClassRexport"
2197 "text": {
2198 "global": [
2199 "_funcA"
2204 "undefined_symbols": [
2206 "targets": [
2207 "x86_64-macos"
2209 "data": {
2210 "global": [
2211 "_globalBind"
2213 "weak": [
2214 "referenced_sym"
2220 "libraries": []
2221 })";
2223 Expected<TBDFile> Result =
2224 TextAPIReader::get(MemoryBufferRef(TBDv5File, "Test.tbd"));
2225 EXPECT_TRUE(!!Result);
2226 TBDFile File = std::move(Result.get());
2228 Expected<TBDFile> RemovedResult = File->remove(AK_x86_64);
2229 EXPECT_TRUE(!!RemovedResult);
2230 TBDFile RemovedFile = std::move(RemovedResult.get());
2232 EXPECT_EQ(FileType::TBD_V5, RemovedFile->getFileType());
2233 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
2234 RemovedFile->getInstallName());
2236 TargetList AllTargets = {
2237 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
2238 Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(14, 0)),
2240 EXPECT_EQ(mapToPlatformSet(AllTargets), RemovedFile->getPlatforms());
2241 EXPECT_EQ(mapToArchitectureSet(AllTargets), RemovedFile->getArchitectures());
2243 EXPECT_EQ(PackedVersion(1, 2, 0), RemovedFile->getCurrentVersion());
2244 EXPECT_EQ(PackedVersion(1, 1, 0), RemovedFile->getCompatibilityVersion());
2245 EXPECT_TRUE(RemovedFile->isApplicationExtensionSafe());
2246 EXPECT_TRUE(RemovedFile->isOSLibNotForSharedCache());
2247 EXPECT_FALSE(RemovedFile->isTwoLevelNamespace());
2248 EXPECT_EQ(0U, RemovedFile->documents().size());
2250 InterfaceFileRef ClientA("ClientA", AllTargets);
2251 InterfaceFileRef ClientB("ClientB", AllTargets);
2252 EXPECT_EQ(2U, RemovedFile->allowableClients().size());
2253 EXPECT_EQ(ClientA, RemovedFile->allowableClients().at(0));
2254 EXPECT_EQ(ClientB, RemovedFile->allowableClients().at(1));
2256 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
2257 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
2258 EXPECT_EQ(2U, RemovedFile->reexportedLibraries().size());
2259 EXPECT_EQ(ReexportA, RemovedFile->reexportedLibraries().at(0));
2260 EXPECT_EQ(ReexportB, RemovedFile->reexportedLibraries().at(1));
2262 EXPECT_EQ(0u, RemovedFile->rpaths().size());
2264 TargetToAttr Umbrellas = {{Target(AK_arm64, PLATFORM_MACOS), "System"},
2265 {Target(AK_arm64, PLATFORM_MACCATALYST), "System"}};
2266 EXPECT_EQ(Umbrellas, RemovedFile->umbrellas());
2268 ExportedSymbolSeq Exports, Reexports, Undefineds;
2269 for (const auto *Sym : RemovedFile->symbols()) {
2270 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
2271 ExportedSymbol Temp =
2272 ExportedSymbol{Sym->getKind(),
2273 std::string(Sym->getName()),
2274 Sym->isWeakDefined() || Sym->isWeakReferenced(),
2275 Sym->isThreadLocalValue(),
2276 Sym->isData(),
2277 SymTargets};
2278 if (Sym->isUndefined())
2279 Undefineds.emplace_back(std::move(Temp));
2280 else
2281 Sym->isReexported() ? Reexports.emplace_back(std::move(Temp))
2282 : Exports.emplace_back(std::move(Temp));
2284 llvm::sort(Exports);
2285 llvm::sort(Reexports);
2286 llvm::sort(Undefineds);
2288 TargetList MacOSTargets = {Target(AK_arm64, PLATFORM_MACOS)};
2290 std::vector<ExportedSymbol> ExpectedExportedSymbols = {
2291 {EncodeKind::GlobalSymbol, "_func", false, false, false, MacOSTargets},
2292 {EncodeKind::GlobalSymbol, "_global", false, false, true, MacOSTargets},
2293 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, MacOSTargets},
2295 std::vector<ExportedSymbol> ExpectedReexportedSymbols = {
2296 {EncodeKind::GlobalSymbol, "_funcA", false, false, false, MacOSTargets},
2297 {EncodeKind::GlobalSymbol, "_globalRe", false, false, true, MacOSTargets},
2298 {EncodeKind::ObjectiveCClass, "ClassRexport", false, false, true,
2299 MacOSTargets},
2302 EXPECT_EQ(ExpectedExportedSymbols.size(), Exports.size());
2303 EXPECT_EQ(ExpectedReexportedSymbols.size(), Reexports.size());
2304 EXPECT_EQ(0U, Undefineds.size());
2305 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
2306 std::begin(ExpectedExportedSymbols)));
2307 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
2308 std::begin(ExpectedReexportedSymbols)));
2311 TEST(TBDv5, InlineIF) {
2312 static const char UmbrellaFile[] = R"({
2313 "tapi_tbd_version": 5,
2314 "main_library": {
2315 "target_info": [
2317 "target": "x86_64-macos",
2318 "min_deployment": "10.14"
2321 "target": "arm64-macos",
2322 "min_deployment": "10.14"
2325 "install_names": [
2327 "name": "/S/L/F/Foo.framework/Foo"
2330 "current_versions": [
2332 "version": "1.2"
2335 "reexported_libraries": [
2337 "names": [
2338 "/u/l/l/libfoo.dylib",
2339 "/u/l/l/libbar.dylib"
2343 }})";
2345 static const char ReexportFile[] = R"({
2346 "tapi_tbd_version": 5,
2347 "main_library": {
2348 "target_info": [
2350 "target": "x86_64-macos",
2351 "min_deployment": "10.14"
2354 "target": "arm64-macos",
2355 "min_deployment": "10.14"
2358 "install_names": [
2360 "name" : "/u/l/l/libfoo.dylib"
2363 "current_versions": [
2365 "version": "1"
2368 "rpaths": [
2370 "targets": [
2371 "x86_64-macos"
2373 "paths": [
2374 "@executable_path/.../Frameworks"
2378 "exported_symbols": [
2380 "targets": [
2381 "x86_64-macos",
2382 "arm64-macos"
2384 "data": {
2385 "global": [
2386 "_global"
2388 "objc_class": [
2389 "ClassA"
2391 "weak": [],
2392 "thread_local": []
2395 ]}})";
2397 Expected<TBDFile> UmbrellaResult =
2398 TextAPIReader::get(MemoryBufferRef(UmbrellaFile, "Test.tbd"));
2399 EXPECT_TRUE(!!UmbrellaResult);
2400 TBDFile Umbrella = std::move(UmbrellaResult.get());
2402 Expected<TBDFile> ReexportResult =
2403 TextAPIReader::get(MemoryBufferRef(ReexportFile, "Test.tbd"));
2404 EXPECT_TRUE(!!ReexportResult);
2405 TBDReexportFile Reexport = std::move(ReexportResult.get());
2406 Umbrella->inlineLibrary(Reexport);
2408 EXPECT_EQ(FileType::TBD_V5, Umbrella->getFileType());
2409 EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo"),
2410 Umbrella->getInstallName());
2412 TargetList AllTargets = {
2413 Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
2414 Target(AK_arm64, PLATFORM_MACOS, VersionTuple(11, 0, 0)),
2416 EXPECT_EQ(mapToPlatformSet(AllTargets), Umbrella->getPlatforms());
2417 EXPECT_EQ(mapToArchitectureSet(AllTargets), Umbrella->getArchitectures());
2419 EXPECT_EQ(PackedVersion(1, 2, 0), Umbrella->getCurrentVersion());
2420 EXPECT_EQ(PackedVersion(1, 0, 0), Umbrella->getCompatibilityVersion());
2421 InterfaceFileRef ReexportA("/u/l/l/libbar.dylib", AllTargets);
2422 InterfaceFileRef ReexportB("/u/l/l/libfoo.dylib", AllTargets);
2423 EXPECT_EQ(2U, Umbrella->reexportedLibraries().size());
2424 EXPECT_EQ(ReexportA, Umbrella->reexportedLibraries().at(0));
2425 EXPECT_EQ(ReexportB, Umbrella->reexportedLibraries().at(1));
2426 EXPECT_EQ(1U, Umbrella->documents().size());
2428 TBDReexportFile Document = Umbrella->documents().front();
2429 EXPECT_EQ(std::string("/u/l/l/libfoo.dylib"), Document->getInstallName());
2430 EXPECT_EQ(0U, Document->getSwiftABIVersion());
2431 EXPECT_TRUE(Document->isTwoLevelNamespace());
2432 EXPECT_TRUE(Document->isApplicationExtensionSafe());
2433 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());
2434 EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());
2436 ExportedSymbolSeq Exports;
2437 for (const auto *Sym : Document->symbols()) {
2438 TargetList SymTargets{Sym->targets().begin(), Sym->targets().end()};
2439 Exports.emplace_back(
2440 ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
2441 Sym->isWeakDefined() || Sym->isWeakReferenced(),
2442 Sym->isThreadLocalValue(), Sym->isData(), SymTargets});
2444 llvm::sort(Exports);
2446 ExportedSymbolSeq ExpectedExports = {
2447 {EncodeKind::GlobalSymbol, "_global", false, false, true, AllTargets},
2448 {EncodeKind::ObjectiveCClass, "ClassA", false, false, true, AllTargets},
2450 EXPECT_EQ(ExpectedExports.size(), Exports.size());
2451 EXPECT_TRUE(
2452 std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
2454 } // end namespace TBDv5