204 using namespace llvm;
209 struct ExportSection {
210 std::vector<Architecture> Architectures;
211 std::vector<FlowStringRef> AllowableClients;
212 std::vector<FlowStringRef> ReexportedLibraries;
213 std::vector<FlowStringRef> Symbols;
214 std::vector<FlowStringRef> Classes;
215 std::vector<FlowStringRef> ClassEHs;
216 std::vector<FlowStringRef> IVars;
217 std::vector<FlowStringRef> WeakDefSymbols;
218 std::vector<FlowStringRef> TLVSymbols;
221 struct UndefinedSection {
222 std::vector<Architecture> Architectures;
223 std::vector<FlowStringRef> Symbols;
224 std::vector<FlowStringRef> Classes;
225 std::vector<FlowStringRef> ClassEHs;
226 std::vector<FlowStringRef> IVars;
227 std::vector<FlowStringRef> WeakRefSymbols;
231 struct SymbolSection {
233 std::vector<FlowStringRef> Symbols;
234 std::vector<FlowStringRef> Classes;
235 std::vector<FlowStringRef> ClassEHs;
236 std::vector<FlowStringRef> Ivars;
237 std::vector<FlowStringRef> WeakSymbols;
238 std::vector<FlowStringRef> TlvSymbols;
241 struct MetadataSection {
242 enum Option { Clients, Libraries };
243 std::vector<Target> Targets;
244 std::vector<FlowStringRef> Values;
247 struct UmbrellaSection {
248 std::vector<Target> Targets;
249 std::string Umbrella;
258 UUIDv4(
const Target &TargetID,
const std::string &
Value)
263 enum TBDFlags :
unsigned {
265 FlatNamespace = 1U << 0,
266 NotApplicationExtensionSafe = 1U << 1,
267 InstallAPI = 1U << 2,
287 static void mapping(IO &IO, ExportSection &Section) {
288 const auto *Ctx =
reinterpret_cast<TextAPIContext *
>(IO.getContext());
290 "File type is not set in YAML context");
292 IO.mapRequired(
"archs", Section.Architectures);
294 IO.mapOptional(
"allowed-clients", Section.AllowableClients);
296 IO.mapOptional(
"allowable-clients", Section.AllowableClients);
297 IO.mapOptional(
"re-exports", Section.ReexportedLibraries);
298 IO.mapOptional(
"symbols", Section.Symbols);
299 IO.mapOptional(
"objc-classes", Section.Classes);
301 IO.mapOptional(
"objc-eh-types", Section.ClassEHs);
302 IO.mapOptional(
"objc-ivars", Section.IVars);
303 IO.mapOptional(
"weak-def-symbols", Section.WeakDefSymbols);
304 IO.mapOptional(
"thread-local-symbols", Section.TLVSymbols);
309 static void mapping(IO &IO, UndefinedSection &Section) {
310 const auto *Ctx =
reinterpret_cast<TextAPIContext *
>(IO.getContext());
312 "File type is not set in YAML context");
314 IO.mapRequired(
"archs", Section.Architectures);
315 IO.mapOptional(
"symbols", Section.Symbols);
316 IO.mapOptional(
"objc-classes", Section.Classes);
318 IO.mapOptional(
"objc-eh-types", Section.ClassEHs);
319 IO.mapOptional(
"objc-ivars", Section.IVars);
320 IO.mapOptional(
"weak-ref-symbols", Section.WeakRefSymbols);
325 static void mapping(IO &IO, SymbolSection &Section) {
326 IO.mapRequired(
"targets", Section.Targets);
327 IO.mapOptional(
"symbols", Section.Symbols);
328 IO.mapOptional(
"objc-classes", Section.Classes);
329 IO.mapOptional(
"objc-eh-types", Section.ClassEHs);
330 IO.mapOptional(
"objc-ivars", Section.Ivars);
331 IO.mapOptional(
"weak-symbols", Section.WeakSymbols);
332 IO.mapOptional(
"thread-local-symbols", Section.TlvSymbols);
337 static void mapping(IO &IO, UmbrellaSection &Section) {
338 IO.mapRequired(
"targets", Section.Targets);
339 IO.mapRequired(
"umbrella", Section.Umbrella);
345 IO.mapRequired(
"target",
UUID.TargetID);
346 IO.mapRequired(
"value",
UUID.Value);
351 struct MappingContextTraits<MetadataSection, MetadataSection::
Option> {
352 static void mapping(IO &IO, MetadataSection &Section,
353 MetadataSection::Option &OptionKind) {
354 IO.mapRequired(
"targets", Section.Targets);
355 switch (OptionKind) {
356 case MetadataSection::Option::Clients:
357 IO.mapRequired(
"clients", Section.Values);
359 case MetadataSection::Option::Libraries:
360 IO.mapRequired(
"libraries", Section.Values);
367 template <>
struct ScalarBitSetTraits<TBDFlags> {
368 static void bitset(IO &IO, TBDFlags &Flags) {
369 IO.bitSetCase(Flags,
"flat_namespace", TBDFlags::FlatNamespace);
370 IO.bitSetCase(Flags,
"not_app_extension_safe",
371 TBDFlags::NotApplicationExtensionSafe);
372 IO.bitSetCase(Flags,
"installapi", TBDFlags::InstallAPI);
376 template <>
struct ScalarTraits<
Target> {
378 OS <<
Value.Arch <<
"-";
379 switch (
Value.Platform) {
402 OS <<
"ios-simulator";
405 OS <<
"tvos-simulator";
408 OS <<
"watchos-simulator";
417 auto Result = Target::create(Scalar);
420 return "unparsable target";
425 return "unknown architecture";
427 return "unknown platform";
436 struct NormalizedTBD {
439 Architectures = File->getArchitectures();
440 UUIDs = File->uuids();
441 Platforms = File->getPlatforms();
442 InstallName = File->getInstallName();
444 CompatibilityVersion =
PackedVersion(File->getCompatibilityVersion());
445 SwiftABIVersion = File->getSwiftABIVersion();
446 ObjCConstraint = File->getObjCConstraint();
449 if (!File->isApplicationExtensionSafe())
450 Flags |= TBDFlags::NotApplicationExtensionSafe;
452 if (!File->isTwoLevelNamespace())
453 Flags |= TBDFlags::FlatNamespace;
455 if (File->isInstallAPI())
456 Flags |= TBDFlags::InstallAPI;
458 if (!File->umbrellas().empty())
459 ParentUmbrella = File->umbrellas().begin()->second;
461 std::set<ArchitectureSet> ArchSet;
462 for (
const auto &
Library : File->allowableClients())
463 ArchSet.insert(
Library.getArchitectures());
465 for (
const auto &
Library : File->reexportedLibraries())
466 ArchSet.insert(
Library.getArchitectures());
468 std::map<const Symbol *, ArchitectureSet> SymbolToArchSet;
469 for (
const auto *
Symbol : File->exports()) {
471 SymbolToArchSet[
Symbol] = Architectures;
472 ArchSet.insert(Architectures);
475 for (
auto Architectures : ArchSet) {
476 ExportSection Section;
477 Section.Architectures = Architectures;
479 for (
const auto &
Library : File->allowableClients())
480 if (
Library.getArchitectures() == Architectures)
481 Section.AllowableClients.emplace_back(
Library.getInstallName());
483 for (
const auto &
Library : File->reexportedLibraries())
484 if (
Library.getArchitectures() == Architectures)
485 Section.ReexportedLibraries.emplace_back(
Library.getInstallName());
487 for (
const auto &SymArch : SymbolToArchSet) {
488 if (SymArch.second != Architectures)
491 const auto *
Symbol = SymArch.first;
493 case SymbolKind::GlobalSymbol:
501 case SymbolKind::ObjectiveCClass:
503 Section.Classes.emplace_back(
508 case SymbolKind::ObjectiveCClassEHType:
510 Section.Symbols.emplace_back(
515 case SymbolKind::ObjectiveCInstanceVariable:
517 Section.IVars.emplace_back(
530 Exports.emplace_back(
std::move(Section));
534 SymbolToArchSet.clear();
536 for (
const auto *
Symbol : File->undefineds()) {
538 SymbolToArchSet[
Symbol] = Architectures;
539 ArchSet.insert(Architectures);
542 for (
auto Architectures : ArchSet) {
543 UndefinedSection Section;
544 Section.Architectures = Architectures;
546 for (
const auto &SymArch : SymbolToArchSet) {
547 if (SymArch.second != Architectures)
550 const auto *
Symbol = SymArch.first;
552 case SymbolKind::GlobalSymbol:
558 case SymbolKind::ObjectiveCClass:
560 Section.Classes.emplace_back(
565 case SymbolKind::ObjectiveCClassEHType:
567 Section.Symbols.emplace_back(
572 case SymbolKind::ObjectiveCInstanceVariable:
574 Section.IVars.emplace_back(
586 Undefineds.emplace_back(
std::move(Section));
599 for (
auto Platform : Platforms) {
617 File->setPath(Ctx->Path);
618 File->setFileType(Ctx->FileKind);
619 File->addTargets(synthesizeTargets(Architectures, Platforms));
620 for (
auto &
ID : UUIDs)
621 File->addUUID(
ID.first,
ID.second);
622 File->setInstallName(InstallName);
624 File->setCompatibilityVersion(CompatibilityVersion);
625 File->setSwiftABIVersion(SwiftABIVersion);
626 File->setObjCConstraint(ObjCConstraint);
627 for (
const auto &
Target : File->targets())
628 File->addParentUmbrella(
Target, ParentUmbrella);
631 File->setTwoLevelNamespace();
632 File->setApplicationExtensionSafe();
634 File->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
635 File->setApplicationExtensionSafe(
636 !(Flags & TBDFlags::NotApplicationExtensionSafe));
637 File->setInstallAPI(Flags & TBDFlags::InstallAPI);
640 for (
const auto &Section : Exports) {
642 synthesizeTargets(Section.Architectures, Platforms);
644 for (
const auto &
Lib : Section.AllowableClients)
645 for (
const auto &
Target : Targets)
648 for (
const auto &
Lib : Section.ReexportedLibraries)
649 for (
const auto &
Target : Targets)
652 for (
const auto &
Symbol : Section.Symbols) {
654 Symbol.value.startswith(
"_OBJC_EHTYPE_$_"))
655 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
656 Symbol.value.drop_front(15), Targets);
658 File->addSymbol(SymbolKind::GlobalSymbol,
Symbol, Targets);
660 for (
auto &
Symbol : Section.Classes) {
663 Name = Name.drop_front();
664 File->addSymbol(SymbolKind::ObjectiveCClass, Name, Targets);
666 for (
auto &
Symbol : Section.ClassEHs)
667 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
Symbol, Targets);
668 for (
auto &
Symbol : Section.IVars) {
671 Name = Name.drop_front();
672 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
675 for (
auto &
Symbol : Section.WeakDefSymbols)
676 File->addSymbol(SymbolKind::GlobalSymbol,
Symbol, Targets,
677 SymbolFlags::WeakDefined);
678 for (
auto &
Symbol : Section.TLVSymbols)
679 File->addSymbol(SymbolKind::GlobalSymbol,
Symbol, Targets,
680 SymbolFlags::ThreadLocalValue);
683 for (
const auto &Section : Undefineds) {
685 synthesizeTargets(Section.Architectures, Platforms);
686 for (
auto &
Symbol : Section.Symbols) {
688 Symbol.value.startswith(
"_OBJC_EHTYPE_$_"))
689 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
690 Symbol.value.drop_front(15), Targets,
691 SymbolFlags::Undefined);
693 File->addSymbol(SymbolKind::GlobalSymbol,
Symbol, Targets,
694 SymbolFlags::Undefined);
696 for (
auto &
Symbol : Section.Classes) {
699 Name = Name.drop_front();
700 File->addSymbol(SymbolKind::ObjectiveCClass, Name, Targets,
701 SymbolFlags::Undefined);
703 for (
auto &
Symbol : Section.ClassEHs)
704 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
Symbol, Targets,
705 SymbolFlags::Undefined);
706 for (
auto &
Symbol : Section.IVars) {
709 Name = Name.drop_front();
710 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name, Targets,
711 SymbolFlags::Undefined);
713 for (
auto &
Symbol : Section.WeakRefSymbols)
714 File->addSymbol(SymbolKind::GlobalSymbol,
Symbol, Targets,
715 SymbolFlags::Undefined | SymbolFlags::WeakReferenced);
727 memcpy(
Ptr, String.data(), String.size());
728 return StringRef(
reinterpret_cast<const char *
>(
Ptr), String.size());
737 SwiftVersion SwiftABIVersion{0};
746 if (IO.mapTag(
"!tapi-tbd",
false))
748 else if (IO.mapTag(
"!tapi-tbd-v3",
false))
750 else if (IO.mapTag(
"!tapi-tbd-v2",
false))
752 else if (IO.mapTag(
"!tapi-tbd-v1",
false) ||
753 IO.mapTag(
"tag:yaml.org,2002:map",
false))
763 assert((!Ctx || !IO.outputting() ||
765 "File type is not set in YAML context");
767 if (!IO.outputting()) {
768 setFileTypeForInput(Ctx, IO);
769 switch (Ctx->FileKind) {
773 mapKeysToValuesV4(IO, File);
776 IO.setError(
"unsupported file type");
781 switch (Ctx->FileKind) {
785 mapKeysToValuesV4(IO, File);
788 IO.mapTag(
"!tapi-tbd-v3",
true);
791 IO.mapTag(
"!tapi-tbd-v2",
true);
798 mapKeysToValues(Ctx->FileKind, IO, File);
802 struct NormalizedTBD_V4 {
807 TBDVersion = Ctx->FileKind >> 1;
808 Targets.insert(Targets.begin(), File->targets().begin(),
809 File->targets().end());
810 for (
const auto &
IT : File->uuids())
811 UUIDs.emplace_back(
IT.first,
IT.second);
812 InstallName = File->getInstallName();
814 CompatibilityVersion = File->getCompatibilityVersion();
815 SwiftABIVersion = File->getSwiftABIVersion();
818 if (!File->isApplicationExtensionSafe())
819 Flags |= TBDFlags::NotApplicationExtensionSafe;
821 if (!File->isTwoLevelNamespace())
822 Flags |= TBDFlags::FlatNamespace;
824 if (File->isInstallAPI())
825 Flags |= TBDFlags::InstallAPI;
828 std::map<std::string, TargetList> valueToTargetList;
829 for (
const auto &
it : File->umbrellas())
830 valueToTargetList[
it.second].emplace_back(
it.first);
832 for (
const auto &
it : valueToTargetList) {
833 UmbrellaSection CurrentSection;
834 CurrentSection.Targets.insert(CurrentSection.Targets.begin(),
835 it.second.begin(),
it.second.end());
836 CurrentSection.Umbrella =
it.first;
837 ParentUmbrellas.emplace_back(
std::move(CurrentSection));
841 assignTargetsToLibrary(File->allowableClients(), AllowableClients);
842 assignTargetsToLibrary(File->reexportedLibraries(), ReexportedLibraries);
848 std::set<TargetList> TargetSet;
849 std::map<const Symbol *, TargetList> SymbolToTargetList;
850 for (
const auto *
Symbol : Symbols) {
854 SymbolToTargetList[
Symbol] = Targets;
857 for (
const auto &TargetIDs : TargetSet) {
858 SymbolSection CurrentSection;
859 CurrentSection.Targets.insert(CurrentSection.Targets.begin(),
860 TargetIDs.begin(), TargetIDs.end());
862 for (
const auto &
IT : SymbolToTargetList) {
863 if (
IT.second != TargetIDs)
868 case SymbolKind::GlobalSymbol:
876 case SymbolKind::ObjectiveCClass:
879 case SymbolKind::ObjectiveCClassEHType:
882 case SymbolKind::ObjectiveCInstanceVariable:
887 sort(CurrentSection.Symbols);
888 sort(CurrentSection.Classes);
889 sort(CurrentSection.ClassEHs);
890 sort(CurrentSection.Ivars);
891 sort(CurrentSection.WeakSymbols);
892 sort(CurrentSection.TlvSymbols);
893 CurrentSections.emplace_back(
std::move(CurrentSection));
897 handleSymbols(Exports, File->exports(), [](
const Symbol *
Symbol) {
898 return !Symbol->isReexported();
900 handleSymbols(Reexports, File->exports(), [](
const Symbol *
Symbol) {
901 return Symbol->isReexported();
903 handleSymbols(Undefineds, File->undefineds(),
912 File->setPath(Ctx->Path);
913 File->setFileType(Ctx->FileKind);
914 for (
auto &
id : UUIDs)
915 File->addUUID(
id.TargetID,
id.
Value);
916 File->addTargets(Targets);
917 File->setInstallName(InstallName);
919 File->setCompatibilityVersion(CompatibilityVersion);
920 File->setSwiftABIVersion(SwiftABIVersion);
921 for (
const auto &CurrentSection : ParentUmbrellas)
922 for (
const auto &target : CurrentSection.Targets)
923 File->addParentUmbrella(target, CurrentSection.Umbrella);
924 File->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
925 File->setApplicationExtensionSafe(
926 !(Flags & TBDFlags::NotApplicationExtensionSafe));
927 File->setInstallAPI(Flags & TBDFlags::InstallAPI);
929 for (
const auto &CurrentSection : AllowableClients) {
930 for (
const auto &lib : CurrentSection.Values)
931 for (
const auto &
Target : CurrentSection.Targets)
932 File->addAllowableClient(lib,
Target);
935 for (
const auto &CurrentSection : ReexportedLibraries) {
936 for (
const auto &
Lib : CurrentSection.Values)
937 for (
const auto &
Target : CurrentSection.Targets)
941 auto handleSymbols = [File](
const SectionList &CurrentSections,
943 for (
const auto &CurrentSection : CurrentSections) {
944 for (
auto &sym : CurrentSection.Symbols)
945 File->addSymbol(SymbolKind::GlobalSymbol, sym,
946 CurrentSection.Targets,
Flag);
948 for (
auto &sym : CurrentSection.Classes)
949 File->addSymbol(SymbolKind::ObjectiveCClass, sym,
950 CurrentSection.Targets);
952 for (
auto &sym : CurrentSection.ClassEHs)
953 File->addSymbol(SymbolKind::ObjectiveCClassEHType, sym,
954 CurrentSection.Targets);
956 for (
auto &sym : CurrentSection.Ivars)
957 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, sym,
958 CurrentSection.Targets);
960 for (
auto &sym : CurrentSection.WeakSymbols)
961 File->addSymbol(SymbolKind::GlobalSymbol, sym,
962 CurrentSection.Targets, SymbolFlags::WeakDefined);
964 for (
auto &sym : CurrentSection.TlvSymbols)
965 File->addSymbol(SymbolKind::GlobalSymbol, sym,
966 CurrentSection.Targets,
967 SymbolFlags::ThreadLocalValue);
971 handleSymbols(Exports);
972 handleSymbols(Reexports, SymbolFlags::Rexported);
973 handleSymbols(Undefineds, SymbolFlags::Undefined);
984 SwiftVersion SwiftABIVersion{0};
994 void assignTargetsToLibrary(
const std::vector<InterfaceFileRef> &Libraries,
995 std::vector<MetadataSection> &Section) {
996 std::set<TargetList> targetSet;
997 std::map<const InterfaceFileRef *, TargetList> valueToTargetList;
998 for (
const auto &
library : Libraries) {
1004 for (
const auto &
targets : targetSet) {
1005 MetadataSection CurrentSection;
1006 CurrentSection.Targets.insert(CurrentSection.Targets.begin(),
1009 for (
const auto &
it : valueToTargetList) {
1013 CurrentSection.Values.emplace_back(
it.first->getInstallName());
1016 Section.emplace_back(
std::move(CurrentSection));
1023 MappingNormalization<NormalizedTBD, const InterfaceFile *> Keys(IO, File);
1024 IO.mapRequired(
"archs", Keys->Architectures);
1026 IO.mapOptional(
"uuids", Keys->UUIDs);
1027 IO.mapRequired(
"platform", Keys->Platforms);
1030 IO.mapRequired(
"install-name", Keys->InstallName);
1031 IO.mapOptional(
"current-version", Keys->CurrentVersion,
1033 IO.mapOptional(
"compatibility-version", Keys->CompatibilityVersion,
1036 IO.mapOptional(
"swift-version", Keys->SwiftABIVersion, SwiftVersion(0));
1038 IO.mapOptional(
"swift-abi-version", Keys->SwiftABIVersion,
1040 IO.mapOptional(
"objc-constraint", Keys->ObjCConstraint,
1043 : ObjCConstraintType::Retain_Release);
1045 IO.mapOptional(
"parent-umbrella", Keys->ParentUmbrella,
StringRef());
1046 IO.mapOptional(
"exports", Keys->Exports);
1048 IO.mapOptional(
"undefineds", Keys->Undefineds);
1052 MappingNormalization<NormalizedTBD_V4, const InterfaceFile *> Keys(IO,
1054 IO.mapTag(
"!tapi-tbd",
true);
1055 IO.mapRequired(
"tbd-version", Keys->TBDVersion);
1056 IO.mapRequired(
"targets", Keys->Targets);
1057 IO.mapOptional(
"uuids", Keys->UUIDs);
1059 IO.mapRequired(
"install-name", Keys->InstallName);
1060 IO.mapOptional(
"current-version", Keys->CurrentVersion,
1062 IO.mapOptional(
"compatibility-version", Keys->CompatibilityVersion,
1064 IO.mapOptional(
"swift-abi-version", Keys->SwiftABIVersion, SwiftVersion(0));
1065 IO.mapOptional(
"parent-umbrella", Keys->ParentUmbrellas);
1066 auto OptionKind = MetadataSection::Option::Clients;
1067 IO.mapOptionalWithContext(
"allowable-clients", Keys->AllowableClients,
1069 OptionKind = MetadataSection::Option::Libraries;
1070 IO.mapOptionalWithContext(
"reexported-libraries", Keys->ReexportedLibraries,
1072 IO.mapOptional(
"exports", Keys->Exports);
1073 IO.mapOptional(
"reexports", Keys->Reexports);
1074 IO.mapOptional(
"undefineds", Keys->Undefineds);
1079 struct DocumentListTraits<
std::vector<const MachO::InterfaceFile *>> {
1080 static size_t size(IO &IO, std::vector<const MachO::InterfaceFile *> &Seq) {
1085 if (
Index >= Seq.size())
1086 Seq.resize(
Index + 1);
1104 NewDiag.
print(
nullptr,
S);
1105 File->ErrorMessage = (
"malformed file\n" + Message).str();
1115 std::vector<const InterfaceFile *> Files;
1120 auto File = std::unique_ptr<InterfaceFile>(
1125 std::shared_ptr<InterfaceFile>(
const_cast<InterfaceFile *
>(FI)));
1128 return make_error<StringError>(Ctx.
ErrorMessage, YAMLIn.error());
1135 Ctx.
Path = std::string(File.getPath());
1137 llvm::yaml::Output YAMLOut(OS, &Ctx, 80);
1139 std::vector<const InterfaceFile *> Files;
1140 Files.emplace_back(&File);
1142 for (
auto Document : File.documents())
1143 Files.emplace_back(
Document.get());