xref: /freebsd-src/contrib/llvm-project/llvm/lib/TextAPI/InterfaceFile.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric //===- InterfaceFile.cpp --------------------------------------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // Implements the Interface File.
10fe6060f1SDimitry Andric //
11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
12fe6060f1SDimitry Andric 
13fe6060f1SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h"
14*0fca6ea1SDimitry Andric #include "llvm/TextAPI/RecordsSlice.h"
155f757f3fSDimitry Andric #include "llvm/TextAPI/TextAPIError.h"
16fe6060f1SDimitry Andric #include <iomanip>
17fe6060f1SDimitry Andric #include <sstream>
18fe6060f1SDimitry Andric 
19fe6060f1SDimitry Andric using namespace llvm;
20fe6060f1SDimitry Andric using namespace llvm::MachO;
21fe6060f1SDimitry Andric 
22fe6060f1SDimitry Andric void InterfaceFileRef::addTarget(const Target &Target) {
23fe6060f1SDimitry Andric   addEntry(Targets, Target);
24fe6060f1SDimitry Andric }
25fe6060f1SDimitry Andric 
26fe6060f1SDimitry Andric void InterfaceFile::addAllowableClient(StringRef InstallName,
27fe6060f1SDimitry Andric                                        const Target &Target) {
28297eecfbSDimitry Andric   if (InstallName.empty())
29297eecfbSDimitry Andric     return;
30fe6060f1SDimitry Andric   auto Client = addEntry(AllowableClients, InstallName);
31fe6060f1SDimitry Andric   Client->addTarget(Target);
32fe6060f1SDimitry Andric }
33fe6060f1SDimitry Andric 
34fe6060f1SDimitry Andric void InterfaceFile::addReexportedLibrary(StringRef InstallName,
35fe6060f1SDimitry Andric                                          const Target &Target) {
36297eecfbSDimitry Andric   if (InstallName.empty())
37297eecfbSDimitry Andric     return;
38fe6060f1SDimitry Andric   auto Lib = addEntry(ReexportedLibraries, InstallName);
39fe6060f1SDimitry Andric   Lib->addTarget(Target);
40fe6060f1SDimitry Andric }
41fe6060f1SDimitry Andric 
42fe6060f1SDimitry Andric void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) {
43297eecfbSDimitry Andric   if (Parent.empty())
44297eecfbSDimitry Andric     return;
45fe6060f1SDimitry Andric   auto Iter = lower_bound(ParentUmbrellas, Target_,
46fe6060f1SDimitry Andric                           [](const std::pair<Target, std::string> &LHS,
47fe6060f1SDimitry Andric                              Target RHS) { return LHS.first < RHS; });
48fe6060f1SDimitry Andric 
49fe6060f1SDimitry Andric   if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
50fe6060f1SDimitry Andric     Iter->second = std::string(Parent);
51fe6060f1SDimitry Andric     return;
52fe6060f1SDimitry Andric   }
53fe6060f1SDimitry Andric 
54fe6060f1SDimitry Andric   ParentUmbrellas.emplace(Iter, Target_, std::string(Parent));
55fe6060f1SDimitry Andric }
56fe6060f1SDimitry Andric 
57*0fca6ea1SDimitry Andric void InterfaceFile::addRPath(StringRef RPath, const Target &InputTarget) {
58297eecfbSDimitry Andric   if (RPath.empty())
59297eecfbSDimitry Andric     return;
605f757f3fSDimitry Andric   using RPathEntryT = const std::pair<Target, std::string>;
615f757f3fSDimitry Andric   RPathEntryT Entry(InputTarget, RPath);
625f757f3fSDimitry Andric   auto Iter =
635f757f3fSDimitry Andric       lower_bound(RPaths, Entry,
645f757f3fSDimitry Andric                   [](RPathEntryT &LHS, RPathEntryT &RHS) { return LHS < RHS; });
65fe6060f1SDimitry Andric 
665f757f3fSDimitry Andric   if ((Iter != RPaths.end()) && (*Iter == Entry))
67fe6060f1SDimitry Andric     return;
68fe6060f1SDimitry Andric 
695f757f3fSDimitry Andric   RPaths.emplace(Iter, Entry);
70fe6060f1SDimitry Andric }
71fe6060f1SDimitry Andric 
72fe6060f1SDimitry Andric void InterfaceFile::addTarget(const Target &Target) {
73fe6060f1SDimitry Andric   addEntry(Targets, Target);
74fe6060f1SDimitry Andric }
75fe6060f1SDimitry Andric 
76fe6060f1SDimitry Andric InterfaceFile::const_filtered_target_range
77fe6060f1SDimitry Andric InterfaceFile::targets(ArchitectureSet Archs) const {
78fe6060f1SDimitry Andric   std::function<bool(const Target &)> fn = [Archs](const Target &Target_) {
79fe6060f1SDimitry Andric     return Archs.has(Target_.Arch);
80fe6060f1SDimitry Andric   };
81fe6060f1SDimitry Andric   return make_filter_range(Targets, fn);
82fe6060f1SDimitry Andric }
83fe6060f1SDimitry Andric 
84fe6060f1SDimitry Andric void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) {
85fe6060f1SDimitry Andric   auto Pos = llvm::lower_bound(Documents, Document,
86fe6060f1SDimitry Andric                                [](const std::shared_ptr<InterfaceFile> &LHS,
87fe6060f1SDimitry Andric                                   const std::shared_ptr<InterfaceFile> &RHS) {
88fe6060f1SDimitry Andric                                  return LHS->InstallName < RHS->InstallName;
89fe6060f1SDimitry Andric                                });
90fe6060f1SDimitry Andric   Document->Parent = this;
91fe6060f1SDimitry Andric   Documents.insert(Pos, Document);
92fe6060f1SDimitry Andric }
93fe6060f1SDimitry Andric 
945f757f3fSDimitry Andric void InterfaceFile::inlineLibrary(std::shared_ptr<InterfaceFile> Library,
955f757f3fSDimitry Andric                                   bool Overwrite) {
965f757f3fSDimitry Andric   auto AddFwk = [&](std::shared_ptr<InterfaceFile> &&Reexport) {
975f757f3fSDimitry Andric     auto It = lower_bound(
985f757f3fSDimitry Andric         Documents, Reexport->getInstallName(),
995f757f3fSDimitry Andric         [](std::shared_ptr<InterfaceFile> &Lhs, const StringRef Rhs) {
1005f757f3fSDimitry Andric           return Lhs->getInstallName() < Rhs;
1015f757f3fSDimitry Andric         });
1025f757f3fSDimitry Andric 
1035f757f3fSDimitry Andric     if (Overwrite && It != Documents.end() &&
1045f757f3fSDimitry Andric         Reexport->getInstallName() == (*It)->getInstallName()) {
1055f757f3fSDimitry Andric       std::replace(Documents.begin(), Documents.end(), *It,
1065f757f3fSDimitry Andric                    std::move(Reexport));
1075f757f3fSDimitry Andric       return;
1085f757f3fSDimitry Andric     }
1095f757f3fSDimitry Andric 
1105f757f3fSDimitry Andric     if ((It != Documents.end()) &&
1115f757f3fSDimitry Andric         !(Reexport->getInstallName() < (*It)->getInstallName()))
1125f757f3fSDimitry Andric       return;
1135f757f3fSDimitry Andric 
1145f757f3fSDimitry Andric     Documents.emplace(It, std::move(Reexport));
1155f757f3fSDimitry Andric   };
1165f757f3fSDimitry Andric   for (auto Doc : Library->documents())
1175f757f3fSDimitry Andric     AddFwk(std::move(Doc));
1185f757f3fSDimitry Andric 
1195f757f3fSDimitry Andric   Library->Documents.clear();
1205f757f3fSDimitry Andric   AddFwk(std::move(Library));
1215f757f3fSDimitry Andric }
1225f757f3fSDimitry Andric 
1235f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
1245f757f3fSDimitry Andric InterfaceFile::merge(const InterfaceFile *O) const {
1255f757f3fSDimitry Andric   // Verify files can be merged.
1265f757f3fSDimitry Andric   if (getInstallName() != O->getInstallName()) {
1275f757f3fSDimitry Andric     return make_error<StringError>("install names do not match",
1285f757f3fSDimitry Andric                                    inconvertibleErrorCode());
1295f757f3fSDimitry Andric   }
1305f757f3fSDimitry Andric 
1315f757f3fSDimitry Andric   if (getCurrentVersion() != O->getCurrentVersion()) {
1325f757f3fSDimitry Andric     return make_error<StringError>("current versions do not match",
1335f757f3fSDimitry Andric                                    inconvertibleErrorCode());
1345f757f3fSDimitry Andric   }
1355f757f3fSDimitry Andric 
1365f757f3fSDimitry Andric   if (getCompatibilityVersion() != O->getCompatibilityVersion()) {
1375f757f3fSDimitry Andric     return make_error<StringError>("compatibility versions do not match",
1385f757f3fSDimitry Andric                                    inconvertibleErrorCode());
1395f757f3fSDimitry Andric   }
1405f757f3fSDimitry Andric 
1415f757f3fSDimitry Andric   if ((getSwiftABIVersion() != 0) && (O->getSwiftABIVersion() != 0) &&
1425f757f3fSDimitry Andric       (getSwiftABIVersion() != O->getSwiftABIVersion())) {
1435f757f3fSDimitry Andric     return make_error<StringError>("swift ABI versions do not match",
1445f757f3fSDimitry Andric                                    inconvertibleErrorCode());
1455f757f3fSDimitry Andric   }
1465f757f3fSDimitry Andric 
1475f757f3fSDimitry Andric   if (isTwoLevelNamespace() != O->isTwoLevelNamespace()) {
1485f757f3fSDimitry Andric     return make_error<StringError>("two level namespace flags do not match",
1495f757f3fSDimitry Andric                                    inconvertibleErrorCode());
1505f757f3fSDimitry Andric   }
1515f757f3fSDimitry Andric 
1525f757f3fSDimitry Andric   if (isApplicationExtensionSafe() != O->isApplicationExtensionSafe()) {
1535f757f3fSDimitry Andric     return make_error<StringError>(
1545f757f3fSDimitry Andric         "application extension safe flags do not match",
1555f757f3fSDimitry Andric         inconvertibleErrorCode());
1565f757f3fSDimitry Andric   }
1575f757f3fSDimitry Andric 
1585f757f3fSDimitry Andric   std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
1595f757f3fSDimitry Andric   IF->setFileType(std::max(getFileType(), O->getFileType()));
1605f757f3fSDimitry Andric   IF->setPath(getPath());
1615f757f3fSDimitry Andric   IF->setInstallName(getInstallName());
1625f757f3fSDimitry Andric   IF->setCurrentVersion(getCurrentVersion());
1635f757f3fSDimitry Andric   IF->setCompatibilityVersion(getCompatibilityVersion());
1645f757f3fSDimitry Andric 
1655f757f3fSDimitry Andric   if (getSwiftABIVersion() == 0)
1665f757f3fSDimitry Andric     IF->setSwiftABIVersion(O->getSwiftABIVersion());
1675f757f3fSDimitry Andric   else
1685f757f3fSDimitry Andric     IF->setSwiftABIVersion(getSwiftABIVersion());
1695f757f3fSDimitry Andric 
1705f757f3fSDimitry Andric   IF->setTwoLevelNamespace(isTwoLevelNamespace());
1715f757f3fSDimitry Andric   IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
1725f757f3fSDimitry Andric 
1735f757f3fSDimitry Andric   for (const auto &It : umbrellas()) {
1745f757f3fSDimitry Andric     if (!It.second.empty())
1755f757f3fSDimitry Andric       IF->addParentUmbrella(It.first, It.second);
1765f757f3fSDimitry Andric   }
1775f757f3fSDimitry Andric   for (const auto &It : O->umbrellas()) {
1785f757f3fSDimitry Andric     if (!It.second.empty())
1795f757f3fSDimitry Andric       IF->addParentUmbrella(It.first, It.second);
1805f757f3fSDimitry Andric   }
1815f757f3fSDimitry Andric   IF->addTargets(targets());
1825f757f3fSDimitry Andric   IF->addTargets(O->targets());
1835f757f3fSDimitry Andric 
1845f757f3fSDimitry Andric   for (const auto &Lib : allowableClients())
1855f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
1865f757f3fSDimitry Andric       IF->addAllowableClient(Lib.getInstallName(), Target);
1875f757f3fSDimitry Andric 
1885f757f3fSDimitry Andric   for (const auto &Lib : O->allowableClients())
1895f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
1905f757f3fSDimitry Andric       IF->addAllowableClient(Lib.getInstallName(), Target);
1915f757f3fSDimitry Andric 
1925f757f3fSDimitry Andric   for (const auto &Lib : reexportedLibraries())
1935f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
1945f757f3fSDimitry Andric       IF->addReexportedLibrary(Lib.getInstallName(), Target);
1955f757f3fSDimitry Andric 
1965f757f3fSDimitry Andric   for (const auto &Lib : O->reexportedLibraries())
1975f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
1985f757f3fSDimitry Andric       IF->addReexportedLibrary(Lib.getInstallName(), Target);
1995f757f3fSDimitry Andric 
2005f757f3fSDimitry Andric   for (const auto &[Target, Path] : rpaths())
201*0fca6ea1SDimitry Andric     IF->addRPath(Path, Target);
2025f757f3fSDimitry Andric   for (const auto &[Target, Path] : O->rpaths())
203*0fca6ea1SDimitry Andric     IF->addRPath(Path, Target);
2045f757f3fSDimitry Andric 
2055f757f3fSDimitry Andric   for (const auto *Sym : symbols()) {
2065f757f3fSDimitry Andric     IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(),
2075f757f3fSDimitry Andric                   Sym->getFlags());
2085f757f3fSDimitry Andric   }
2095f757f3fSDimitry Andric 
2105f757f3fSDimitry Andric   for (const auto *Sym : O->symbols()) {
2115f757f3fSDimitry Andric     IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(),
2125f757f3fSDimitry Andric                   Sym->getFlags());
2135f757f3fSDimitry Andric   }
2145f757f3fSDimitry Andric 
2155f757f3fSDimitry Andric   return std::move(IF);
2165f757f3fSDimitry Andric }
2175f757f3fSDimitry Andric 
2185f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
2195f757f3fSDimitry Andric InterfaceFile::remove(Architecture Arch) const {
2205f757f3fSDimitry Andric   if (getArchitectures() == Arch)
2215f757f3fSDimitry Andric     return make_error<StringError>("cannot remove last architecture slice '" +
2225f757f3fSDimitry Andric                                        getArchitectureName(Arch) + "'",
2235f757f3fSDimitry Andric                                    inconvertibleErrorCode());
2245f757f3fSDimitry Andric 
2255f757f3fSDimitry Andric   if (!getArchitectures().has(Arch)) {
2265f757f3fSDimitry Andric     bool Found = false;
2275f757f3fSDimitry Andric     for (auto &Doc : Documents) {
2285f757f3fSDimitry Andric       if (Doc->getArchitectures().has(Arch)) {
2295f757f3fSDimitry Andric         Found = true;
2305f757f3fSDimitry Andric         break;
2315f757f3fSDimitry Andric       }
2325f757f3fSDimitry Andric     }
2335f757f3fSDimitry Andric 
2345f757f3fSDimitry Andric     if (!Found)
2355f757f3fSDimitry Andric       return make_error<TextAPIError>(TextAPIErrorCode::NoSuchArchitecture);
2365f757f3fSDimitry Andric   }
2375f757f3fSDimitry Andric 
2385f757f3fSDimitry Andric   std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
2395f757f3fSDimitry Andric   IF->setFileType(getFileType());
2405f757f3fSDimitry Andric   IF->setPath(getPath());
2415f757f3fSDimitry Andric   IF->addTargets(targets(ArchitectureSet::All().clear(Arch)));
2425f757f3fSDimitry Andric   IF->setInstallName(getInstallName());
2435f757f3fSDimitry Andric   IF->setCurrentVersion(getCurrentVersion());
2445f757f3fSDimitry Andric   IF->setCompatibilityVersion(getCompatibilityVersion());
2455f757f3fSDimitry Andric   IF->setSwiftABIVersion(getSwiftABIVersion());
2465f757f3fSDimitry Andric   IF->setTwoLevelNamespace(isTwoLevelNamespace());
2475f757f3fSDimitry Andric   IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
2485f757f3fSDimitry Andric   for (const auto &It : umbrellas())
2495f757f3fSDimitry Andric     if (It.first.Arch != Arch)
2505f757f3fSDimitry Andric       IF->addParentUmbrella(It.first, It.second);
2515f757f3fSDimitry Andric 
2525f757f3fSDimitry Andric   for (const auto &Lib : allowableClients()) {
2535f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
2545f757f3fSDimitry Andric       if (Target.Arch != Arch)
2555f757f3fSDimitry Andric         IF->addAllowableClient(Lib.getInstallName(), Target);
2565f757f3fSDimitry Andric   }
2575f757f3fSDimitry Andric 
2585f757f3fSDimitry Andric   for (const auto &Lib : reexportedLibraries()) {
2595f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
2605f757f3fSDimitry Andric       if (Target.Arch != Arch)
2615f757f3fSDimitry Andric         IF->addReexportedLibrary(Lib.getInstallName(), Target);
2625f757f3fSDimitry Andric   }
2635f757f3fSDimitry Andric 
2645f757f3fSDimitry Andric   for (const auto *Sym : symbols()) {
2655f757f3fSDimitry Andric     auto Archs = Sym->getArchitectures();
2665f757f3fSDimitry Andric     Archs.clear(Arch);
2675f757f3fSDimitry Andric     if (Archs.empty())
2685f757f3fSDimitry Andric       continue;
2695f757f3fSDimitry Andric 
2705f757f3fSDimitry Andric     IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Archs),
2715f757f3fSDimitry Andric                   Sym->getFlags());
2725f757f3fSDimitry Andric   }
2735f757f3fSDimitry Andric 
2745f757f3fSDimitry Andric   for (auto &Doc : Documents) {
2755f757f3fSDimitry Andric     // Skip the inlined document if the to be removed architecture is the
2765f757f3fSDimitry Andric     // only one left.
2775f757f3fSDimitry Andric     if (Doc->getArchitectures() == Arch)
2785f757f3fSDimitry Andric       continue;
2795f757f3fSDimitry Andric 
2805f757f3fSDimitry Andric     // If the document doesn't contain the arch, then no work is to be done
2815f757f3fSDimitry Andric     // and it can be copied over.
2825f757f3fSDimitry Andric     if (!Doc->getArchitectures().has(Arch)) {
2835f757f3fSDimitry Andric       auto NewDoc = Doc;
2845f757f3fSDimitry Andric       IF->addDocument(std::move(NewDoc));
2855f757f3fSDimitry Andric       continue;
2865f757f3fSDimitry Andric     }
2875f757f3fSDimitry Andric 
2885f757f3fSDimitry Andric     auto Result = Doc->remove(Arch);
2895f757f3fSDimitry Andric     if (!Result)
2905f757f3fSDimitry Andric       return Result;
2915f757f3fSDimitry Andric 
2925f757f3fSDimitry Andric     IF->addDocument(std::move(Result.get()));
2935f757f3fSDimitry Andric   }
2945f757f3fSDimitry Andric 
2955f757f3fSDimitry Andric   return std::move(IF);
2965f757f3fSDimitry Andric }
2975f757f3fSDimitry Andric 
2985f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
2995f757f3fSDimitry Andric InterfaceFile::extract(Architecture Arch) const {
3005f757f3fSDimitry Andric   if (!getArchitectures().has(Arch)) {
3015f757f3fSDimitry Andric     return make_error<StringError>("file doesn't have architecture '" +
3025f757f3fSDimitry Andric                                        getArchitectureName(Arch) + "'",
3035f757f3fSDimitry Andric                                    inconvertibleErrorCode());
3045f757f3fSDimitry Andric   }
3055f757f3fSDimitry Andric 
3065f757f3fSDimitry Andric   std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
3075f757f3fSDimitry Andric   IF->setFileType(getFileType());
3085f757f3fSDimitry Andric   IF->setPath(getPath());
3095f757f3fSDimitry Andric   IF->addTargets(targets(Arch));
3105f757f3fSDimitry Andric   IF->setInstallName(getInstallName());
3115f757f3fSDimitry Andric   IF->setCurrentVersion(getCurrentVersion());
3125f757f3fSDimitry Andric   IF->setCompatibilityVersion(getCompatibilityVersion());
3135f757f3fSDimitry Andric   IF->setSwiftABIVersion(getSwiftABIVersion());
3145f757f3fSDimitry Andric   IF->setTwoLevelNamespace(isTwoLevelNamespace());
3155f757f3fSDimitry Andric   IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
3165f757f3fSDimitry Andric   for (const auto &It : umbrellas())
3175f757f3fSDimitry Andric     if (It.first.Arch == Arch)
3185f757f3fSDimitry Andric       IF->addParentUmbrella(It.first, It.second);
3195f757f3fSDimitry Andric 
3205f757f3fSDimitry Andric   for (const auto &It : rpaths())
3215f757f3fSDimitry Andric     if (It.first.Arch == Arch)
322*0fca6ea1SDimitry Andric       IF->addRPath(It.second, It.first);
3235f757f3fSDimitry Andric 
3245f757f3fSDimitry Andric   for (const auto &Lib : allowableClients())
3255f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
3265f757f3fSDimitry Andric       if (Target.Arch == Arch)
3275f757f3fSDimitry Andric         IF->addAllowableClient(Lib.getInstallName(), Target);
3285f757f3fSDimitry Andric 
3295f757f3fSDimitry Andric   for (const auto &Lib : reexportedLibraries())
3305f757f3fSDimitry Andric     for (const auto &Target : Lib.targets())
3315f757f3fSDimitry Andric       if (Target.Arch == Arch)
3325f757f3fSDimitry Andric         IF->addReexportedLibrary(Lib.getInstallName(), Target);
3335f757f3fSDimitry Andric 
3345f757f3fSDimitry Andric   for (const auto *Sym : symbols()) {
3355f757f3fSDimitry Andric     if (Sym->hasArchitecture(Arch))
3365f757f3fSDimitry Andric       IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Arch),
3375f757f3fSDimitry Andric                     Sym->getFlags());
3385f757f3fSDimitry Andric   }
3395f757f3fSDimitry Andric 
3405f757f3fSDimitry Andric   for (auto &Doc : Documents) {
3415f757f3fSDimitry Andric     // Skip documents that don't have the requested architecture.
3425f757f3fSDimitry Andric     if (!Doc->getArchitectures().has(Arch))
3435f757f3fSDimitry Andric       continue;
3445f757f3fSDimitry Andric 
3455f757f3fSDimitry Andric     auto Result = Doc->extract(Arch);
3465f757f3fSDimitry Andric     if (!Result)
3475f757f3fSDimitry Andric       return Result;
3485f757f3fSDimitry Andric 
3495f757f3fSDimitry Andric     IF->addDocument(std::move(Result.get()));
3505f757f3fSDimitry Andric   }
3515f757f3fSDimitry Andric 
3525f757f3fSDimitry Andric   return std::move(IF);
3535f757f3fSDimitry Andric }
3545f757f3fSDimitry Andric 
355*0fca6ea1SDimitry Andric void InterfaceFile::setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA,
356*0fca6ea1SDimitry Andric                                        const Target &Targ) {
357*0fca6ea1SDimitry Andric   if (getFileType() != BA.File)
358*0fca6ea1SDimitry Andric     setFileType(BA.File);
359*0fca6ea1SDimitry Andric   if (getInstallName().empty())
360*0fca6ea1SDimitry Andric     setInstallName(BA.InstallName);
361*0fca6ea1SDimitry Andric   if (BA.AppExtensionSafe && !isApplicationExtensionSafe())
362*0fca6ea1SDimitry Andric     setApplicationExtensionSafe();
363*0fca6ea1SDimitry Andric   if (BA.TwoLevelNamespace && !isTwoLevelNamespace())
364*0fca6ea1SDimitry Andric     setTwoLevelNamespace();
365*0fca6ea1SDimitry Andric   if (BA.OSLibNotForSharedCache && !isOSLibNotForSharedCache())
366*0fca6ea1SDimitry Andric     setOSLibNotForSharedCache();
367*0fca6ea1SDimitry Andric   if (getCurrentVersion().empty())
368*0fca6ea1SDimitry Andric     setCurrentVersion(BA.CurrentVersion);
369*0fca6ea1SDimitry Andric   if (getCompatibilityVersion().empty())
370*0fca6ea1SDimitry Andric     setCompatibilityVersion(BA.CompatVersion);
371*0fca6ea1SDimitry Andric   if (getSwiftABIVersion() == 0)
372*0fca6ea1SDimitry Andric     setSwiftABIVersion(BA.SwiftABI);
373*0fca6ea1SDimitry Andric   if (getPath().empty())
374*0fca6ea1SDimitry Andric     setPath(BA.Path);
375*0fca6ea1SDimitry Andric   if (!BA.ParentUmbrella.empty())
376*0fca6ea1SDimitry Andric     addParentUmbrella(Targ, BA.ParentUmbrella);
377*0fca6ea1SDimitry Andric   for (const auto &Client : BA.AllowableClients)
378*0fca6ea1SDimitry Andric     addAllowableClient(Client, Targ);
379*0fca6ea1SDimitry Andric   for (const auto &Lib : BA.RexportedLibraries)
380*0fca6ea1SDimitry Andric     addReexportedLibrary(Lib, Targ);
381*0fca6ea1SDimitry Andric }
382*0fca6ea1SDimitry Andric 
38306c3fb27SDimitry Andric static bool isYAMLTextStub(const FileType &Kind) {
38406c3fb27SDimitry Andric   return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5);
38506c3fb27SDimitry Andric }
38606c3fb27SDimitry Andric 
387fe6060f1SDimitry Andric bool InterfaceFile::operator==(const InterfaceFile &O) const {
388fe6060f1SDimitry Andric   if (Targets != O.Targets)
389fe6060f1SDimitry Andric     return false;
390fe6060f1SDimitry Andric   if (InstallName != O.InstallName)
391fe6060f1SDimitry Andric     return false;
392fe6060f1SDimitry Andric   if ((CurrentVersion != O.CurrentVersion) ||
393fe6060f1SDimitry Andric       (CompatibilityVersion != O.CompatibilityVersion))
394fe6060f1SDimitry Andric     return false;
395fe6060f1SDimitry Andric   if (SwiftABIVersion != O.SwiftABIVersion)
396fe6060f1SDimitry Andric     return false;
397fe6060f1SDimitry Andric   if (IsTwoLevelNamespace != O.IsTwoLevelNamespace)
398fe6060f1SDimitry Andric     return false;
399fe6060f1SDimitry Andric   if (IsAppExtensionSafe != O.IsAppExtensionSafe)
400fe6060f1SDimitry Andric     return false;
4015f757f3fSDimitry Andric   if (IsOSLibNotForSharedCache != O.IsOSLibNotForSharedCache)
4025f757f3fSDimitry Andric     return false;
4035f757f3fSDimitry Andric   if (HasSimSupport != O.HasSimSupport)
4045f757f3fSDimitry Andric     return false;
405fe6060f1SDimitry Andric   if (ParentUmbrellas != O.ParentUmbrellas)
406fe6060f1SDimitry Andric     return false;
407fe6060f1SDimitry Andric   if (AllowableClients != O.AllowableClients)
408fe6060f1SDimitry Andric     return false;
409fe6060f1SDimitry Andric   if (ReexportedLibraries != O.ReexportedLibraries)
410fe6060f1SDimitry Andric     return false;
41106c3fb27SDimitry Andric   if (*SymbolsSet != *O.SymbolsSet)
412fe6060f1SDimitry Andric     return false;
41306c3fb27SDimitry Andric   // Don't compare run search paths for older filetypes that cannot express
41406c3fb27SDimitry Andric   // them.
41506c3fb27SDimitry Andric   if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) {
41606c3fb27SDimitry Andric     if (RPaths != O.RPaths)
41706c3fb27SDimitry Andric       return false;
41806c3fb27SDimitry Andric     if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets))
41906c3fb27SDimitry Andric       return false;
42006c3fb27SDimitry Andric   }
42106c3fb27SDimitry Andric 
422fe6060f1SDimitry Andric   if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(),
423fe6060f1SDimitry Andric                   O.Documents.end(),
424fe6060f1SDimitry Andric                   [](const std::shared_ptr<InterfaceFile> LHS,
425fe6060f1SDimitry Andric                      const std::shared_ptr<InterfaceFile> RHS) {
426fe6060f1SDimitry Andric                     return *LHS == *RHS;
427fe6060f1SDimitry Andric                   }))
428fe6060f1SDimitry Andric     return false;
429fe6060f1SDimitry Andric   return true;
430fe6060f1SDimitry Andric }
431