LLVM: lib/TextAPI/TextStubV5.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
15#include
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71using namespace llvm;
74
75namespace {
76struct JSONSymbol {
78 std::string Name;
80};
81
82using AttrToTargets = std::map<std::string, TargetList>;
83using TargetsToSymbols =
85
86
87
88
89class InOrderAttrToTargets {
90 using EntryT = std::pair<std::string, TargetList>;
91
92public:
93 void insert(EntryT &&Entry) {
94 auto &Element = get(Entry.first);
95 Element.second = Entry.second;
96 }
97
98 const EntryT *begin() { return Container.begin(); }
99 const EntryT *end() { return Container.end(); }
100
101private:
102 EntryT &get(std::string &Key) {
103 auto *It = find_if(Container,
104 [&Key](EntryT &Input) { return Input.first == Key; });
105 if (It != Container.end())
106 return *It;
107 Container.push_back(EntryT(Key, {}));
108 return Container.back();
109 }
111};
112
113enum TBDKey : size_t {
114 TBDVersion = 0U,
115 MainLibrary,
116 Documents,
117 TargetInfo,
118 Targets,
120 Deployment,
121 Flags,
122 Attributes,
123 InstallName,
125 CompatibilityVersion,
126 Version,
127 SwiftABI,
128 ABI,
129 ParentUmbrella,
130 Umbrella,
131 AllowableClients,
132 Clients,
133 ReexportLibs,
134 Names,
136 Exports,
137 Reexports,
138 Undefineds,
142 ThreadLocal,
143 Globals,
144 ObjCClass,
145 ObjCEHType,
146 ObjCIvar,
148 Paths,
149};
150
151std::array<StringRef, 64> Keys = {
152 "tapi_tbd_version",
153 "main_library",
154 "libraries",
155 "target_info",
156 "targets",
157 "target",
158 "min_deployment",
159 "flags",
160 "attributes",
161 "install_names",
162 "current_versions",
163 "compatibility_versions",
164 "version",
165 "swift_abi",
166 "abi",
167 "parent_umbrellas",
168 "umbrella",
169 "allowable_clients",
170 "clients",
171 "reexported_libraries",
172 "names",
173 "name",
174 "exported_symbols",
175 "reexported_symbols",
176 "undefined_symbols",
177 "data",
178 "text",
179 "weak",
180 "thread_local",
181 "global",
182 "objc_class",
183 "objc_eh_type",
184 "objc_ivar",
185 "rpaths",
186 "paths",
187};
188
190 return {"invalid ", Keys[Key], " section"};
191}
192
194 return {"missing ", Keys[Key], " information"};
195}
196
197class JSONStubError : public llvm::ErrorInfollvm::json::ParseError {
198public:
199 JSONStubError(Twine ErrMsg) : Message(ErrMsg.str()) {}
200
201 void log(llvm::raw_ostream &OS) const override { OS << Message << "\n"; }
202 std::error_code convertToErrorCode() const override {
204 }
205
206private:
207 std::string Message;
208};
209
210template <typename JsonT, typename StubT = JsonT>
213 std::function<std::optional(const Object *, StringRef)> GetValue,
214 std::function<std::optional(JsonT)> Validate = nullptr) {
215 std::optional Val = GetValue(Obj, Keys[Key]);
216 if (!Val)
218
219 if (Validate == nullptr)
220 return static_cast<StubT>(*Val);
221
222 std::optional Result = Validate(*Val);
223 if (.has_value())
225 return Result.value();
226}
227
228template <typename JsonT, typename StubT = JsonT>
231 std::function<std::optional(const Object *, StringRef)> const
232 GetValue,
233 StubT DefaultValue, function_ref<std::optional(JsonT)> Validate) {
234 std::optional Val = GetValue(Obj, Keys[Key]);
235 if (!Val)
236 return DefaultValue;
237
238 std::optional Result;
239 Result = Validate(*Val);
240 if (.has_value())
242 return Result.value();
243}
244
247 bool IsRequired = false) {
248 const auto *Values = Obj->getArray(Keys[Key]);
249 if (!Values) {
250 if (IsRequired)
253 }
254
255 for (const Value &Val : *Values) {
256 auto ValStr = Val.getAsString();
257 if (!ValStr.has_value())
259 Append(ValStr.value());
260 }
261
263}
264
266
268 auto VersionOrErr = getRequiredValue<int64_t, FileType>(
270 [](int64_t Val) -> std::optional {
271 unsigned Result = Val;
272 if (Result != 5)
273 return std::nullopt;
275 });
276
277 if (!VersionOrErr)
279 return *VersionOrErr;
280}
281
283 const auto *Targets = Section->getArray(Keys[TBDKey::Targets]);
284 if (!Targets)
286
288 for (const Value &JSONTarget : *Targets) {
289 auto TargetStr = JSONTarget.getAsString();
290 if (!TargetStr.has_value())
292 auto TargetOrErr = Target::create(TargetStr.value());
293 if (!TargetOrErr)
295 IFTargets.push_back(*TargetOrErr);
296 }
297 return std::move(IFTargets);
298}
299
301 const Array *Targets = Section->getArray(Keys[TBDKey::TargetInfo]);
302 if (!Targets)
304
306 for (const Value &JSONTarget : *Targets) {
307 const auto *Obj = JSONTarget.getAsObject();
308 if (!Obj)
310 auto TargetStr =
311 getRequiredValue(TBDKey::Target, Obj, &Object::getString);
312 if (!TargetStr)
315 if (!TargetOrErr)
317
318 auto VersionStr = Obj->getString(Keys[TBDKey::Deployment]);
320 if (VersionStr && Version.tryParse(*VersionStr))
322 TargetOrErr->MinDeployment = Version;
323
324
325
328 }
329 return std::move(IFTargets);
330}
331
332Error collectSymbolsFromSegment(const Object *Segment, TargetsToSymbols &Result,
334 auto Err = collectFromArray(
335 TBDKey::Globals, Segment, [&Result, &SectionFlag](StringRef Name) {
337 Result.back().second.emplace_back(Sym);
338 });
339 if (Err)
340 return Err;
341
342 Err = collectFromArray(
343 TBDKey::ObjCClass, Segment, [&Result, &SectionFlag](StringRef Name) {
345 Result.back().second.emplace_back(Sym);
346 });
347 if (Err)
348 return Err;
349
350 Err = collectFromArray(TBDKey::ObjCEHType, Segment,
351 [&Result, &SectionFlag](StringRef Name) {
353 Name.str(), SectionFlag};
354 Result.back().second.emplace_back(Sym);
355 });
356 if (Err)
357 return Err;
358
359 Err = collectFromArray(
360 TBDKey::ObjCIvar, Segment, [&Result, &SectionFlag](StringRef Name) {
362 SectionFlag};
363 Result.back().second.emplace_back(Sym);
364 });
365 if (Err)
366 return Err;
367
369 SectionFlag |
373 Err = collectFromArray(
374 TBDKey::Weak, Segment, [&Result, WeakFlag](StringRef Name) {
376 Result.back().second.emplace_back(Sym);
377 });
378 if (Err)
379 return Err;
380
381 Err = collectFromArray(
382 TBDKey::ThreadLocal, Segment, [&Result, SectionFlag](StringRef Name) {
385 Result.back().second.emplace_back(Sym);
386 });
387 if (Err)
388 return Err;
389
391}
392
394 const Array *Section = File->getArray(Keys[TBDKey::InstallName]);
395 if (!Section)
397
398 assert(!Section->empty() && "unexpected missing install name");
399
400 const auto *Obj = Section->front().getAsObject();
401 if (!Obj)
403
404 return getRequiredValue(TBDKey::Name, Obj, &Object::getString);
405}
406
409
410 const Array *Section = File->getArray(Keys[Key]);
411 if (!Section)
412 return TargetsToSymbols();
413
415 switch (Key) {
416 case TBDKey::Reexports:
418 break;
419 case TBDKey::Undefineds:
421 break;
422 default:
424 break;
425 };
426
427 TargetsToSymbols Result;
429 for (auto Val : *Section) {
430 auto *Obj = Val.getAsObject();
431 if (!Obj)
432 continue;
433
434 auto TargetsOrErr = getTargets(Obj);
435 if (!TargetsOrErr) {
436 MappedTargets = Targets;
438 } else {
439 MappedTargets = *TargetsOrErr;
440 }
441 Result.emplace_back(
442 std::make_pair(std::move(MappedTargets), std::vector()));
443
444 auto *DataSection = Obj->getObject(Keys[TBDKey::Data]);
445 auto *TextSection = Obj->getObject(Keys[TBDKey::Text]);
446
447 if (!DataSection && !TextSection)
449
450 if (DataSection) {
451 auto Err = collectSymbolsFromSegment(DataSection, Result,
453 if (Err)
454 return std::move(Err);
455 }
456 if (TextSection) {
457 auto Err = collectSymbolsFromSegment(TextSection, Result,
459 if (Err)
460 return std::move(Err);
461 }
462 }
463
464 return std::move(Result);
465}
466
467template
470 auto *Section = File->getArray(Keys[Key]);
471 if (!Section)
472 return ReturnT();
473
474 ReturnT Result;
476 for (auto Val : *Section) {
477 auto *Obj = Val.getAsObject();
478 if (!Obj)
479 continue;
480
481 auto TargetsOrErr = getTargets(Obj);
482 if (!TargetsOrErr) {
483 MappedTargets = Targets;
485 } else {
486 MappedTargets = *TargetsOrErr;
487 }
488 auto Err =
489 collectFromArray(SubKey, Obj, [&Result, &MappedTargets](StringRef Key) {
490 Result.insert({Key.str(), MappedTargets});
491 });
492 if (Err)
493 return std::move(Err);
494 }
495
496 return std::move(Result);
497}
498
501 const auto *Umbrella = File->getArray(Keys[TBDKey::ParentUmbrella]);
502 if (!Umbrella)
503 return AttrToTargets();
504
505 AttrToTargets Result;
507 for (auto Val : *Umbrella) {
508 auto *Obj = Val.getAsObject();
509 if (!Obj)
511 getParseErrorMsg(TBDKey::ParentUmbrella));
512
513
514 auto TargetsOrErr = getTargets(Obj);
515 if (!TargetsOrErr) {
516 MappedTargets = Targets;
518 } else {
519 MappedTargets = *TargetsOrErr;
520 }
521
522 auto UmbrellaOrErr =
523 getRequiredValue(TBDKey::Umbrella, Obj, &Object::getString);
524 if (!UmbrellaOrErr)
525 return UmbrellaOrErr.takeError();
526 Result[UmbrellaOrErr->str()] = Targets;
527 }
528 return std::move(Result);
529}
530
532 const Array *Versions = File->getArray(Keys[TBDKey::SwiftABI]);
533 if (!Versions)
534 return 0;
535
536 for (const auto &Val : *Versions) {
537 const auto *Obj = Val.getAsObject();
538 if (!Obj)
540
541
542 return getRequiredValue<int64_t, uint8_t>(TBDKey::ABI, Obj,
544 }
545
546 return 0;
547}
548
550 const Array *Versions = File->getArray(Keys[Key]);
551 if (!Versions)
553
554 for (const auto &Val : *Versions) {
555 const auto *Obj = Val.getAsObject();
556 if (!Obj)
558
559 auto ValidatePV = [](StringRef Version) -> std::optional {
563 return std::nullopt;
564 return PV;
565 };
566
567 return getRequiredValue<StringRef, PackedVersion>(
569 ValidatePV);
570 }
571
573}
574
577 const Array *Section = File->getArray(Keys[TBDKey::Flags]);
578 if (!Section || Section->empty())
579 return Flags;
580
581 for (auto &Val : *Section) {
582
583 const auto *Obj = Val.getAsObject();
584 if (!Obj)
586
587 auto FlagsOrErr =
588 collectFromArray(TBDKey::Attributes, Obj, [&Flags](StringRef Flag) {
589 TBDFlags TBDFlag =
592 .Case("not_app_extension_safe",
595 .Case("not_for_dyld_shared_cache",
598 Flags |= TBDFlag;
599 });
600
601 if (FlagsOrErr)
602 return std::move(FlagsOrErr);
603
604 return Flags;
605 }
606
607 return Flags;
608}
609
610using IFPtr = std::unique_ptr;
612 auto TargetsOrErr = getTargetsSection(File);
613 if (!TargetsOrErr)
614 return TargetsOrErr.takeError();
616
617 auto NameOrErr = getNameSection(File);
618 if (!NameOrErr)
619 return NameOrErr.takeError();
621
622 auto CurrVersionOrErr = getPackedVersion(File, TBDKey::CurrentVersion);
623 if (!CurrVersionOrErr)
624 return CurrVersionOrErr.takeError();
626
627 auto CompVersionOrErr = getPackedVersion(File, TBDKey::CompatibilityVersion);
628 if (!CompVersionOrErr)
629 return CompVersionOrErr.takeError();
631
632 auto SwiftABIOrErr = getSwiftVersion(File);
633 if (!SwiftABIOrErr)
634 return SwiftABIOrErr.takeError();
635 uint8_t SwiftABI = *SwiftABIOrErr;
636
637 auto FlagsOrErr = getFlags(File);
638 if (!FlagsOrErr)
639 return FlagsOrErr.takeError();
640 TBDFlags Flags = *FlagsOrErr;
641
642 auto UmbrellasOrErr = getUmbrellaSection(File, Targets);
643 if (!UmbrellasOrErr)
644 return UmbrellasOrErr.takeError();
645 AttrToTargets Umbrellas = *UmbrellasOrErr;
646
647 auto ClientsOrErr =
648 getLibSection(File, TBDKey::AllowableClients, TBDKey::Clients, Targets);
649 if (!ClientsOrErr)
650 return ClientsOrErr.takeError();
651 AttrToTargets Clients = *ClientsOrErr;
652
653 auto RLOrErr =
654 getLibSection(File, TBDKey::ReexportLibs, TBDKey::Names, Targets);
655 if (!RLOrErr)
656 return RLOrErr.takeError();
657 AttrToTargets ReexportLibs = std::move(*RLOrErr);
658
659 auto RPathsOrErr = getLibSection(
660 File, TBDKey::RPath, TBDKey::Paths, Targets);
661 if (!RPathsOrErr)
662 return RPathsOrErr.takeError();
663 InOrderAttrToTargets RPaths = std::move(*RPathsOrErr);
664
665 auto ExportsOrErr = getSymbolSection(File, TBDKey::Exports, Targets);
666 if (!ExportsOrErr)
667 return ExportsOrErr.takeError();
668 TargetsToSymbols Exports = std::move(*ExportsOrErr);
669
670 auto ReexportsOrErr = getSymbolSection(File, TBDKey::Reexports, Targets);
671 if (!ReexportsOrErr)
672 return ReexportsOrErr.takeError();
673 TargetsToSymbols Reexports = std::move(*ReexportsOrErr);
674
675 auto UndefinedsOrErr = getSymbolSection(File, TBDKey::Undefineds, Targets);
676 if (!UndefinedsOrErr)
677 return UndefinedsOrErr.takeError();
678 TargetsToSymbols Undefineds = std::move(*UndefinedsOrErr);
679
681 F->setInstallName(Name);
682 F->setCurrentVersion(CurrVersion);
683 F->setCompatibilityVersion(CompVersion);
684 F->setSwiftABIVersion(SwiftABI);
686 F->setApplicationExtensionSafe(
690 for (auto &T : Targets)
691 F->addTarget(T);
692 for (auto &[Lib, Targets] : Clients)
693 for (auto Target : Targets)
695 for (auto &[Lib, Targets] : ReexportLibs)
696 for (auto Target : Targets)
697 F->addReexportedLibrary(Lib, Target);
698 for (auto &[Lib, Targets] : Umbrellas)
699 for (auto Target : Targets)
701 for (auto &[Path, Targets] : RPaths)
702 for (auto Target : Targets)
704 for (auto &[Targets, Symbols] : Exports)
705 for (auto &Sym : Symbols)
706 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);
707 for (auto &[Targets, Symbols] : Reexports)
708 for (auto &Sym : Symbols)
709 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);
710 for (auto &[Targets, Symbols] : Undefineds)
711 for (auto &Sym : Symbols)
712 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);
713
714 return std::move(F);
715}
716
718 std::vector IFs;
719 const Array *Files = File->getArray(Keys[TBDKey::Documents]);
720 if (!Files)
721 return std::move(IFs);
722
723 for (auto Lib : *Files) {
724 auto IFOrErr = parseToInterfaceFile(Lib.getAsObject());
725 if (!IFOrErr)
726 return IFOrErr.takeError();
727 auto IF = std::move(*IFOrErr);
728 IFs.emplace_back(std::move(IF));
729 }
730 return std::move(IFs);
731}
732
733}
734}
735
738 auto ValOrErr = parse(JSON);
739 if (!ValOrErr)
740 return ValOrErr.takeError();
741
742 auto *Root = ValOrErr->getAsObject();
743 auto VersionOrErr = StubParser::getVersion(Root);
744 if (!VersionOrErr)
745 return VersionOrErr.takeError();
747
748 Object *MainLib = Root->getObject(Keys[TBDKey::MainLibrary]);
749 auto IFOrErr = StubParser::parseToInterfaceFile(MainLib);
750 if (!IFOrErr)
751 return IFOrErr.takeError();
752 (*IFOrErr)->setFileType(Version);
753 std::unique_ptr IF(std::move(*IFOrErr));
754
755 auto IFsOrErr = StubParser::getInlinedLibs(Root);
756 if (!IFsOrErr)
757 return IFsOrErr.takeError();
758 for (auto &File : *IFsOrErr) {
759 File->setFileType(Version);
760 IF->addDocument(std::shared_ptr(std::move(File)));
761 }
762 return std::move(IF);
763}
764
765namespace {
766
767template
768bool insertNonEmptyValues(Object &Obj, TBDKey Key, ContainerT &&Contents) {
769 if (Contents.empty())
770 return false;
771 Obj[Keys[Key]] = std::move(Contents);
772 return true;
773}
774
775std::string getFormattedStr(const MachO::Target &Targ) {
776 std::string PlatformStr = Targ.Platform == PLATFORM_MACCATALYST
777 ? "maccatalyst"
780}
781
782template
783std::vectorstd::string serializeTargets(const AggregateT Targets,
785 std::vectorstd::string TargetsStr;
786 if (Targets.size() == ActiveTargets.size())
787 return TargetsStr;
788
790 TargetsStr.emplace_back(getFormattedStr(Target));
791
792 return TargetsStr;
793}
794
795Array serializeTargetInfo(const TargetList &ActiveTargets) {
797 for (const auto Targ : ActiveTargets) {
801 TargetInfo[Keys[TBDKey::Target]] = getFormattedStr(Targ);
803 }
804 return Targets;
805}
806
807template <typename ValueT, typename EntryT = ValueT>
810 return {};
813
814 Container.emplace_back(std::move(ScalarObj));
815 return Container;
816}
817
818using TargetsToValuesMap =
819 std::map<std::vectorstd::string, std::vectorstd::string>;
820
821template
822Array serializeAttrToTargets(AggregateT &Entries, TBDKey Key) {
824 for (const auto &[Targets, Values] : Entries) {
826 insertNonEmptyValues(Obj, TBDKey::Targets, std::move(Targets));
829 }
830 return Container;
831}
832
833
834
835template <typename ValueT = std::string,
836 typename AggregateT = std::vector<std::pair<MachO::Target, ValueT>>>
837Array serializeField(TBDKey Key, const AggregateT &Values,
838 const TargetList &ActiveTargets, bool IsArray = true) {
839 std::map<ValueT, std::setMachO::Target> Entries;
840 for (const auto &[Target, Val] : Values)
842
843 if (!IsArray) {
844 std::map<std::vectorstd::string, std::string> FinalEntries;
845 for (const auto &[Val, Targets] : Entries)
846 FinalEntries[serializeTargets(Targets, ActiveTargets)] = Val;
847 return serializeAttrToTargets(FinalEntries, Key);
848 }
849
850 TargetsToValuesMap FinalEntries;
851 for (const auto &[Val, Targets] : Entries)
852 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(Val);
853 return serializeAttrToTargets(FinalEntries, Key);
854}
855
856Array serializeField(TBDKey Key, const std::vector &Values,
858 TargetsToValuesMap FinalEntries;
859 for (const auto &Ref : Values) {
860 TargetList Targets{Ref.targets().begin(), Ref.targets().end()};
861 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(
862 Ref.getInstallName());
863 }
864 return serializeAttrToTargets(FinalEntries, Key);
865}
866
867template <
868 typename AggregateT = std::vector<std::pair<MachO::Target, std::string>>>
869Array serializeFieldInInsertionOrder(TBDKey Key, const AggregateT &Values,
872 for (const auto &[Target, Val] : Values)
874
875 TargetsToValuesMap FinalEntries;
876 for (const auto &[Val, Targets] : Entries)
877 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(
878 Val.str());
879 return serializeAttrToTargets(FinalEntries, Key);
880}
881
882struct SymbolFields {
883 struct SymbolTypes {
884 std::vector Weaks;
885 std::vector Globals;
886 std::vector TLV;
887 std::vector ObjCClasses;
888 std::vector IVars;
889 std::vector EHTypes;
890
891 bool empty() const {
892 return Weaks.empty() && Globals.empty() && TLV.empty() &&
893 ObjCClasses.empty() && IVars.empty() && EHTypes.empty();
894 }
895 };
896 SymbolTypes Data;
897 SymbolTypes Text;
898};
899
902 auto AssignForSymbolType = [](SymbolFields::SymbolTypes &Assignment,
904 switch (Sym->getKind()) {
906 Assignment.ObjCClasses.emplace_back(Sym->getName());
907 return;
909 Assignment.EHTypes.emplace_back(Sym->getName());
910 return;
912 Assignment.IVars.emplace_back(Sym->getName());
913 return;
915 if (Sym->isWeakReferenced() || Sym->isWeakDefined())
916 Assignment.Weaks.emplace_back(Sym->getName());
917 else if (Sym->isThreadLocalValue())
918 Assignment.TLV.emplace_back(Sym->getName());
919 else
920 Assignment.Globals.emplace_back(Sym->getName());
921 return;
922 }
923 }
924 };
925
926 std::map<std::vectorstd::string, SymbolFields> Entries;
927 for (const auto *Sym : Symbols) {
928 std::setMachO::Target Targets{Sym->targets().begin(),
929 Sym->targets().end()};
930 auto JSONTargets = serializeTargets(Targets, ActiveTargets);
931 if (Sym->isData())
932 AssignForSymbolType(Entries[std::move(JSONTargets)].Data, Sym);
933 else if (Sym->isText())
934 AssignForSymbolType(Entries[std::move(JSONTargets)].Text, Sym);
935 else
937 }
938
939 auto InsertSymbolsToJSON = [](Object &SymSection, TBDKey SegmentKey,
940 SymbolFields::SymbolTypes &SymField) {
941 if (SymField.empty())
942 return;
950 insertNonEmptyValues(Segment, TBDKey::Globals, std::move(SymField.Globals));
951 insertNonEmptyValues(Segment, TBDKey::ThreadLocal, std::move(SymField.TLV));
952 insertNonEmptyValues(Segment, TBDKey::Weak, std::move(SymField.Weaks));
953 insertNonEmptyValues(Segment, TBDKey::ObjCClass,
954 std::move(SymField.ObjCClasses));
955 insertNonEmptyValues(Segment, TBDKey::ObjCEHType,
956 std::move(SymField.EHTypes));
957 insertNonEmptyValues(Segment, TBDKey::ObjCIvar, std::move(SymField.IVars));
958 insertNonEmptyValues(SymSection, SegmentKey, std::move(Segment));
959 };
960
961 Array SymbolSection;
962 for (auto &[Targets, Fields] : Entries) {
964 insertNonEmptyValues(AllSyms, TBDKey::Targets, std::move(Targets));
965 InsertSymbolsToJSON(AllSyms, TBDKey::Data, Fields.Data);
966 InsertSymbolsToJSON(AllSyms, TBDKey::Text, Fields.Text);
967 SymbolSection.emplace_back(std::move(AllSyms));
968 }
969
970 return SymbolSection;
971}
972
974
976 if (->isTwoLevelNamespace())
978 if (->isApplicationExtensionSafe())
979 Flags.emplace_back("not_app_extension_safe");
980 if (File->hasSimulatorSupport())
981 Flags.emplace_back("sim_support");
982 if (File->isOSLibNotForSharedCache())
983 Flags.emplace_back("not_for_dyld_shared_cache");
984 return serializeScalar(TBDKey::Attributes, std::move(Flags));
985}
986
989
990
991 TargetList ActiveTargets{File->targets().begin(), File->targets().end()};
992 if (!insertNonEmptyValues(Library, TBDKey::TargetInfo,
993 serializeTargetInfo(ActiveTargets)))
995
996 Array Name = serializeScalar(TBDKey::Name, File->getInstallName());
997 if (!insertNonEmptyValues(Library, TBDKey::InstallName, std::move(Name)))
999
1000
1001 Array Flags = serializeFlags(File);
1002 insertNonEmptyValues(Library, TBDKey::Flags, std::move(Flags));
1003
1004 Array CurrentV = serializeScalar<PackedVersion, std::string>(
1005 TBDKey::Version, File->getCurrentVersion(), PackedVersion(1, 0, 0));
1006 insertNonEmptyValues(Library, TBDKey::CurrentVersion, std::move(CurrentV));
1007
1008 Array CompatV = serializeScalar<PackedVersion, std::string>(
1009 TBDKey::Version, File->getCompatibilityVersion(), PackedVersion(1, 0, 0));
1010 insertNonEmptyValues(Library, TBDKey::CompatibilityVersion,
1011 std::move(CompatV));
1012
1013 Array SwiftABI = serializeScalar<uint8_t, int64_t>(
1014 TBDKey::ABI, File->getSwiftABIVersion(), 0u);
1015 insertNonEmptyValues(Library, TBDKey::SwiftABI, std::move(SwiftABI));
1016
1017 Array RPaths = serializeFieldInInsertionOrder(TBDKey::Paths, File->rpaths(),
1018 ActiveTargets);
1019 insertNonEmptyValues(Library, TBDKey::RPath, std::move(RPaths));
1020
1021 Array Umbrellas = serializeField(TBDKey::Umbrella, File->umbrellas(),
1022 ActiveTargets, false);
1023 insertNonEmptyValues(Library, TBDKey::ParentUmbrella, std::move(Umbrellas));
1024
1026 serializeField(TBDKey::Clients, File->allowableClients(), ActiveTargets);
1027 insertNonEmptyValues(Library, TBDKey::AllowableClients, std::move(Clients));
1028
1029 Array ReexportLibs =
1030 serializeField(TBDKey::Names, File->reexportedLibraries(), ActiveTargets);
1031 insertNonEmptyValues(Library, TBDKey::ReexportLibs, std::move(ReexportLibs));
1032
1033
1034 Array Exports = serializeSymbols(File->exports(), ActiveTargets);
1035 insertNonEmptyValues(Library, TBDKey::Exports, std::move(Exports));
1036
1037 Array Reexports = serializeSymbols(File->reexports(), ActiveTargets);
1038 insertNonEmptyValues(Library, TBDKey::Reexports, std::move(Reexports));
1039
1040 if (->isTwoLevelNamespace()) {
1041 Array Undefineds = serializeSymbols(File->undefineds(), ActiveTargets);
1042 insertNonEmptyValues(Library, TBDKey::Undefineds, std::move(Undefineds));
1043 }
1044
1045 return std::move(Library);
1046}
1047
1051
1052 auto MainLibOrErr = serializeIF(File);
1053 if (!MainLibOrErr)
1054 return MainLibOrErr;
1055 Root[Keys[TBDKey::MainLibrary]] = std::move(*MainLibOrErr);
1056 Array Documents;
1057 for (const auto &Doc : File->documents()) {
1058 auto LibOrErr = serializeIF(Doc.get());
1059 if (!LibOrErr)
1060 return LibOrErr;
1061 Documents.emplace_back(std::move(*LibOrErr));
1062 }
1063
1064 Root[Keys[TBDKey::TBDVersion]] = 5;
1065 insertNonEmptyValues(Root, TBDKey::Documents, std::move(Documents));
1066 return std::move(Root);
1067}
1068
1069}
1070
1074 bool Compact) {
1075 auto TextFile = getJSON(&File, FileKind);
1076 if (!TextFile)
1077 return TextFile.takeError();
1078 if (Compact)
1079 OS << formatv("{0}", Value(std::move(*TextFile))) << "\n";
1080 else
1081 OS << formatv("{0:2}", Value(std::move(*TextFile))) << "\n";
1083}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file supports working with JSON data.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static uint32_t getFlags(const Symbol *Sym)
@ NotApplicationExtensionSafe
Base class for user error types.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
Defines the interface file.
SymbolSet::const_filtered_symbol_range const_filtered_symbol_range
LLVM_ABI std::pair< bool, bool > parse64(StringRef Str)
static LLVM_ABI llvm::Expected< Target > create(StringRef Target)
VersionTuple MinDeployment
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
LLVM Value Representation.
Represents a version number in the form major[.minor[.subminor[.build]]].
LLVM_ABI std::string getAsString() const
Retrieve a string representation of the version number.
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
An efficient, type-erasing, non-owning reference to a callable.
An Array is a JSON array, which contains heterogeneous JSON values.
void emplace_back(Args &&...A)
iterator insert(const_iterator P, const Value &E)
An Object is a JSON object, which maps strings to heterogenous JSON values.
LLVM_ABI const json::Object * getObject(StringRef K) const
LLVM_ABI std::optional< llvm::StringRef > getString(StringRef K) const
LLVM_ABI std::optional< int64_t > getInteger(StringRef K) const
A "cursor" marking a position within a Value.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition TextStubV5.cpp:265
LLVM_ABI std::string getTargetTripleName(const Target &Targ)
FileType
Defines the file type TextAPI files can represent.
@ TBD_V5
Text-based stub file (.tbd) version 5.0.
LLVM_ABI StringRef getArchitectureName(Architecture Arch)
Convert an architecture slice to a string.
LLVM_ABI std::string getOSAndEnvironmentName(PlatformType Platform, std::string Version="")
Error serializeInterfaceFileToJSON(raw_ostream &OS, const InterfaceFile &File, const FileType FileKind, bool Compact)
Definition TextStubV5.cpp:1071
Expected< std::unique_ptr< InterfaceFile > > getInterfaceFileFromJSON(StringRef JSON)
Definition TextStubV5.cpp:737
EncodeKind
Mapping of entry types in TextStubs.
@ ObjectiveCInstanceVariable
@ ThreadLocalValue
Thread-local value symbol.
@ WeakReferenced
Weak referenced symbol.
@ WeakDefined
Weak defined symbol.
SmallVector< Target, 5 > TargetList
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
@ Ref
The access may reference the value stored in memory.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
LogicalResult success(bool IsSuccess=true)
Utility function to generate a LogicalResult.
void consumeError(Error Err)
Consume a Error without doing anything.