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" 145f757f3fSDimitry Andric #include "llvm/TextAPI/TextAPIError.h" 15fe6060f1SDimitry Andric #include <iomanip> 16fe6060f1SDimitry Andric #include <sstream> 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric using namespace llvm; 19fe6060f1SDimitry Andric using namespace llvm::MachO; 20fe6060f1SDimitry Andric 21fe6060f1SDimitry Andric void InterfaceFileRef::addTarget(const Target &Target) { 22fe6060f1SDimitry Andric addEntry(Targets, Target); 23fe6060f1SDimitry Andric } 24fe6060f1SDimitry Andric 25fe6060f1SDimitry Andric void InterfaceFile::addAllowableClient(StringRef InstallName, 26fe6060f1SDimitry Andric const Target &Target) { 27*297eecfbSDimitry Andric if (InstallName.empty()) 28*297eecfbSDimitry Andric return; 29fe6060f1SDimitry Andric auto Client = addEntry(AllowableClients, InstallName); 30fe6060f1SDimitry Andric Client->addTarget(Target); 31fe6060f1SDimitry Andric } 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric void InterfaceFile::addReexportedLibrary(StringRef InstallName, 34fe6060f1SDimitry Andric const Target &Target) { 35*297eecfbSDimitry Andric if (InstallName.empty()) 36*297eecfbSDimitry Andric return; 37fe6060f1SDimitry Andric auto Lib = addEntry(ReexportedLibraries, InstallName); 38fe6060f1SDimitry Andric Lib->addTarget(Target); 39fe6060f1SDimitry Andric } 40fe6060f1SDimitry Andric 41fe6060f1SDimitry Andric void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 42*297eecfbSDimitry Andric if (Parent.empty()) 43*297eecfbSDimitry Andric return; 44fe6060f1SDimitry Andric auto Iter = lower_bound(ParentUmbrellas, Target_, 45fe6060f1SDimitry Andric [](const std::pair<Target, std::string> &LHS, 46fe6060f1SDimitry Andric Target RHS) { return LHS.first < RHS; }); 47fe6060f1SDimitry Andric 48fe6060f1SDimitry Andric if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 49fe6060f1SDimitry Andric Iter->second = std::string(Parent); 50fe6060f1SDimitry Andric return; 51fe6060f1SDimitry Andric } 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric ParentUmbrellas.emplace(Iter, Target_, std::string(Parent)); 54fe6060f1SDimitry Andric } 55fe6060f1SDimitry Andric 5606c3fb27SDimitry Andric void InterfaceFile::addRPath(const Target &InputTarget, StringRef RPath) { 57*297eecfbSDimitry Andric if (RPath.empty()) 58*297eecfbSDimitry Andric return; 595f757f3fSDimitry Andric using RPathEntryT = const std::pair<Target, std::string>; 605f757f3fSDimitry Andric RPathEntryT Entry(InputTarget, RPath); 615f757f3fSDimitry Andric auto Iter = 625f757f3fSDimitry Andric lower_bound(RPaths, Entry, 635f757f3fSDimitry Andric [](RPathEntryT &LHS, RPathEntryT &RHS) { return LHS < RHS; }); 64fe6060f1SDimitry Andric 655f757f3fSDimitry Andric if ((Iter != RPaths.end()) && (*Iter == Entry)) 66fe6060f1SDimitry Andric return; 67fe6060f1SDimitry Andric 685f757f3fSDimitry Andric RPaths.emplace(Iter, Entry); 69fe6060f1SDimitry Andric } 70fe6060f1SDimitry Andric 71fe6060f1SDimitry Andric void InterfaceFile::addTarget(const Target &Target) { 72fe6060f1SDimitry Andric addEntry(Targets, Target); 73fe6060f1SDimitry Andric } 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric InterfaceFile::const_filtered_target_range 76fe6060f1SDimitry Andric InterfaceFile::targets(ArchitectureSet Archs) const { 77fe6060f1SDimitry Andric std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 78fe6060f1SDimitry Andric return Archs.has(Target_.Arch); 79fe6060f1SDimitry Andric }; 80fe6060f1SDimitry Andric return make_filter_range(Targets, fn); 81fe6060f1SDimitry Andric } 82fe6060f1SDimitry Andric 83fe6060f1SDimitry Andric void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) { 84fe6060f1SDimitry Andric auto Pos = llvm::lower_bound(Documents, Document, 85fe6060f1SDimitry Andric [](const std::shared_ptr<InterfaceFile> &LHS, 86fe6060f1SDimitry Andric const std::shared_ptr<InterfaceFile> &RHS) { 87fe6060f1SDimitry Andric return LHS->InstallName < RHS->InstallName; 88fe6060f1SDimitry Andric }); 89fe6060f1SDimitry Andric Document->Parent = this; 90fe6060f1SDimitry Andric Documents.insert(Pos, Document); 91fe6060f1SDimitry Andric } 92fe6060f1SDimitry Andric 935f757f3fSDimitry Andric void InterfaceFile::inlineLibrary(std::shared_ptr<InterfaceFile> Library, 945f757f3fSDimitry Andric bool Overwrite) { 955f757f3fSDimitry Andric auto AddFwk = [&](std::shared_ptr<InterfaceFile> &&Reexport) { 965f757f3fSDimitry Andric auto It = lower_bound( 975f757f3fSDimitry Andric Documents, Reexport->getInstallName(), 985f757f3fSDimitry Andric [](std::shared_ptr<InterfaceFile> &Lhs, const StringRef Rhs) { 995f757f3fSDimitry Andric return Lhs->getInstallName() < Rhs; 1005f757f3fSDimitry Andric }); 1015f757f3fSDimitry Andric 1025f757f3fSDimitry Andric if (Overwrite && It != Documents.end() && 1035f757f3fSDimitry Andric Reexport->getInstallName() == (*It)->getInstallName()) { 1045f757f3fSDimitry Andric std::replace(Documents.begin(), Documents.end(), *It, 1055f757f3fSDimitry Andric std::move(Reexport)); 1065f757f3fSDimitry Andric return; 1075f757f3fSDimitry Andric } 1085f757f3fSDimitry Andric 1095f757f3fSDimitry Andric if ((It != Documents.end()) && 1105f757f3fSDimitry Andric !(Reexport->getInstallName() < (*It)->getInstallName())) 1115f757f3fSDimitry Andric return; 1125f757f3fSDimitry Andric 1135f757f3fSDimitry Andric Documents.emplace(It, std::move(Reexport)); 1145f757f3fSDimitry Andric }; 1155f757f3fSDimitry Andric for (auto Doc : Library->documents()) 1165f757f3fSDimitry Andric AddFwk(std::move(Doc)); 1175f757f3fSDimitry Andric 1185f757f3fSDimitry Andric Library->Documents.clear(); 1195f757f3fSDimitry Andric AddFwk(std::move(Library)); 1205f757f3fSDimitry Andric } 1215f757f3fSDimitry Andric 1225f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 1235f757f3fSDimitry Andric InterfaceFile::merge(const InterfaceFile *O) const { 1245f757f3fSDimitry Andric // Verify files can be merged. 1255f757f3fSDimitry Andric if (getInstallName() != O->getInstallName()) { 1265f757f3fSDimitry Andric return make_error<StringError>("install names do not match", 1275f757f3fSDimitry Andric inconvertibleErrorCode()); 1285f757f3fSDimitry Andric } 1295f757f3fSDimitry Andric 1305f757f3fSDimitry Andric if (getCurrentVersion() != O->getCurrentVersion()) { 1315f757f3fSDimitry Andric return make_error<StringError>("current versions do not match", 1325f757f3fSDimitry Andric inconvertibleErrorCode()); 1335f757f3fSDimitry Andric } 1345f757f3fSDimitry Andric 1355f757f3fSDimitry Andric if (getCompatibilityVersion() != O->getCompatibilityVersion()) { 1365f757f3fSDimitry Andric return make_error<StringError>("compatibility versions do not match", 1375f757f3fSDimitry Andric inconvertibleErrorCode()); 1385f757f3fSDimitry Andric } 1395f757f3fSDimitry Andric 1405f757f3fSDimitry Andric if ((getSwiftABIVersion() != 0) && (O->getSwiftABIVersion() != 0) && 1415f757f3fSDimitry Andric (getSwiftABIVersion() != O->getSwiftABIVersion())) { 1425f757f3fSDimitry Andric return make_error<StringError>("swift ABI versions do not match", 1435f757f3fSDimitry Andric inconvertibleErrorCode()); 1445f757f3fSDimitry Andric } 1455f757f3fSDimitry Andric 1465f757f3fSDimitry Andric if (isTwoLevelNamespace() != O->isTwoLevelNamespace()) { 1475f757f3fSDimitry Andric return make_error<StringError>("two level namespace flags do not match", 1485f757f3fSDimitry Andric inconvertibleErrorCode()); 1495f757f3fSDimitry Andric } 1505f757f3fSDimitry Andric 1515f757f3fSDimitry Andric if (isApplicationExtensionSafe() != O->isApplicationExtensionSafe()) { 1525f757f3fSDimitry Andric return make_error<StringError>( 1535f757f3fSDimitry Andric "application extension safe flags do not match", 1545f757f3fSDimitry Andric inconvertibleErrorCode()); 1555f757f3fSDimitry Andric } 1565f757f3fSDimitry Andric 1575f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 1585f757f3fSDimitry Andric IF->setFileType(std::max(getFileType(), O->getFileType())); 1595f757f3fSDimitry Andric IF->setPath(getPath()); 1605f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 1615f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 1625f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 1635f757f3fSDimitry Andric 1645f757f3fSDimitry Andric if (getSwiftABIVersion() == 0) 1655f757f3fSDimitry Andric IF->setSwiftABIVersion(O->getSwiftABIVersion()); 1665f757f3fSDimitry Andric else 1675f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 1685f757f3fSDimitry Andric 1695f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 1705f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 1715f757f3fSDimitry Andric 1725f757f3fSDimitry Andric for (const auto &It : umbrellas()) { 1735f757f3fSDimitry Andric if (!It.second.empty()) 1745f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 1755f757f3fSDimitry Andric } 1765f757f3fSDimitry Andric for (const auto &It : O->umbrellas()) { 1775f757f3fSDimitry Andric if (!It.second.empty()) 1785f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 1795f757f3fSDimitry Andric } 1805f757f3fSDimitry Andric IF->addTargets(targets()); 1815f757f3fSDimitry Andric IF->addTargets(O->targets()); 1825f757f3fSDimitry Andric 1835f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) 1845f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 1855f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 1865f757f3fSDimitry Andric 1875f757f3fSDimitry Andric for (const auto &Lib : O->allowableClients()) 1885f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 1895f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 1905f757f3fSDimitry Andric 1915f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) 1925f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 1935f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 1945f757f3fSDimitry Andric 1955f757f3fSDimitry Andric for (const auto &Lib : O->reexportedLibraries()) 1965f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 1975f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 1985f757f3fSDimitry Andric 1995f757f3fSDimitry Andric for (const auto &[Target, Path] : rpaths()) 2005f757f3fSDimitry Andric IF->addRPath(Target, Path); 2015f757f3fSDimitry Andric for (const auto &[Target, Path] : O->rpaths()) 2025f757f3fSDimitry Andric IF->addRPath(Target, Path); 2035f757f3fSDimitry Andric 2045f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 2055f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 2065f757f3fSDimitry Andric Sym->getFlags()); 2075f757f3fSDimitry Andric } 2085f757f3fSDimitry Andric 2095f757f3fSDimitry Andric for (const auto *Sym : O->symbols()) { 2105f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 2115f757f3fSDimitry Andric Sym->getFlags()); 2125f757f3fSDimitry Andric } 2135f757f3fSDimitry Andric 2145f757f3fSDimitry Andric return std::move(IF); 2155f757f3fSDimitry Andric } 2165f757f3fSDimitry Andric 2175f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 2185f757f3fSDimitry Andric InterfaceFile::remove(Architecture Arch) const { 2195f757f3fSDimitry Andric if (getArchitectures() == Arch) 2205f757f3fSDimitry Andric return make_error<StringError>("cannot remove last architecture slice '" + 2215f757f3fSDimitry Andric getArchitectureName(Arch) + "'", 2225f757f3fSDimitry Andric inconvertibleErrorCode()); 2235f757f3fSDimitry Andric 2245f757f3fSDimitry Andric if (!getArchitectures().has(Arch)) { 2255f757f3fSDimitry Andric bool Found = false; 2265f757f3fSDimitry Andric for (auto &Doc : Documents) { 2275f757f3fSDimitry Andric if (Doc->getArchitectures().has(Arch)) { 2285f757f3fSDimitry Andric Found = true; 2295f757f3fSDimitry Andric break; 2305f757f3fSDimitry Andric } 2315f757f3fSDimitry Andric } 2325f757f3fSDimitry Andric 2335f757f3fSDimitry Andric if (!Found) 2345f757f3fSDimitry Andric return make_error<TextAPIError>(TextAPIErrorCode::NoSuchArchitecture); 2355f757f3fSDimitry Andric } 2365f757f3fSDimitry Andric 2375f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 2385f757f3fSDimitry Andric IF->setFileType(getFileType()); 2395f757f3fSDimitry Andric IF->setPath(getPath()); 2405f757f3fSDimitry Andric IF->addTargets(targets(ArchitectureSet::All().clear(Arch))); 2415f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 2425f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 2435f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 2445f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 2455f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 2465f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 2475f757f3fSDimitry Andric for (const auto &It : umbrellas()) 2485f757f3fSDimitry Andric if (It.first.Arch != Arch) 2495f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 2505f757f3fSDimitry Andric 2515f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) { 2525f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 2535f757f3fSDimitry Andric if (Target.Arch != Arch) 2545f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 2555f757f3fSDimitry Andric } 2565f757f3fSDimitry Andric 2575f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) { 2585f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 2595f757f3fSDimitry Andric if (Target.Arch != Arch) 2605f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 2615f757f3fSDimitry Andric } 2625f757f3fSDimitry Andric 2635f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 2645f757f3fSDimitry Andric auto Archs = Sym->getArchitectures(); 2655f757f3fSDimitry Andric Archs.clear(Arch); 2665f757f3fSDimitry Andric if (Archs.empty()) 2675f757f3fSDimitry Andric continue; 2685f757f3fSDimitry Andric 2695f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Archs), 2705f757f3fSDimitry Andric Sym->getFlags()); 2715f757f3fSDimitry Andric } 2725f757f3fSDimitry Andric 2735f757f3fSDimitry Andric for (auto &Doc : Documents) { 2745f757f3fSDimitry Andric // Skip the inlined document if the to be removed architecture is the 2755f757f3fSDimitry Andric // only one left. 2765f757f3fSDimitry Andric if (Doc->getArchitectures() == Arch) 2775f757f3fSDimitry Andric continue; 2785f757f3fSDimitry Andric 2795f757f3fSDimitry Andric // If the document doesn't contain the arch, then no work is to be done 2805f757f3fSDimitry Andric // and it can be copied over. 2815f757f3fSDimitry Andric if (!Doc->getArchitectures().has(Arch)) { 2825f757f3fSDimitry Andric auto NewDoc = Doc; 2835f757f3fSDimitry Andric IF->addDocument(std::move(NewDoc)); 2845f757f3fSDimitry Andric continue; 2855f757f3fSDimitry Andric } 2865f757f3fSDimitry Andric 2875f757f3fSDimitry Andric auto Result = Doc->remove(Arch); 2885f757f3fSDimitry Andric if (!Result) 2895f757f3fSDimitry Andric return Result; 2905f757f3fSDimitry Andric 2915f757f3fSDimitry Andric IF->addDocument(std::move(Result.get())); 2925f757f3fSDimitry Andric } 2935f757f3fSDimitry Andric 2945f757f3fSDimitry Andric return std::move(IF); 2955f757f3fSDimitry Andric } 2965f757f3fSDimitry Andric 2975f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 2985f757f3fSDimitry Andric InterfaceFile::extract(Architecture Arch) const { 2995f757f3fSDimitry Andric if (!getArchitectures().has(Arch)) { 3005f757f3fSDimitry Andric return make_error<StringError>("file doesn't have architecture '" + 3015f757f3fSDimitry Andric getArchitectureName(Arch) + "'", 3025f757f3fSDimitry Andric inconvertibleErrorCode()); 3035f757f3fSDimitry Andric } 3045f757f3fSDimitry Andric 3055f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 3065f757f3fSDimitry Andric IF->setFileType(getFileType()); 3075f757f3fSDimitry Andric IF->setPath(getPath()); 3085f757f3fSDimitry Andric IF->addTargets(targets(Arch)); 3095f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 3105f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 3115f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 3125f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 3135f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 3145f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 3155f757f3fSDimitry Andric for (const auto &It : umbrellas()) 3165f757f3fSDimitry Andric if (It.first.Arch == Arch) 3175f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 3185f757f3fSDimitry Andric 3195f757f3fSDimitry Andric for (const auto &It : rpaths()) 3205f757f3fSDimitry Andric if (It.first.Arch == Arch) 3215f757f3fSDimitry Andric IF->addRPath(It.first, It.second); 3225f757f3fSDimitry Andric 3235f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) 3245f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 3255f757f3fSDimitry Andric if (Target.Arch == Arch) 3265f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 3275f757f3fSDimitry Andric 3285f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) 3295f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 3305f757f3fSDimitry Andric if (Target.Arch == Arch) 3315f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 3325f757f3fSDimitry Andric 3335f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 3345f757f3fSDimitry Andric if (Sym->hasArchitecture(Arch)) 3355f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Arch), 3365f757f3fSDimitry Andric Sym->getFlags()); 3375f757f3fSDimitry Andric } 3385f757f3fSDimitry Andric 3395f757f3fSDimitry Andric for (auto &Doc : Documents) { 3405f757f3fSDimitry Andric // Skip documents that don't have the requested architecture. 3415f757f3fSDimitry Andric if (!Doc->getArchitectures().has(Arch)) 3425f757f3fSDimitry Andric continue; 3435f757f3fSDimitry Andric 3445f757f3fSDimitry Andric auto Result = Doc->extract(Arch); 3455f757f3fSDimitry Andric if (!Result) 3465f757f3fSDimitry Andric return Result; 3475f757f3fSDimitry Andric 3485f757f3fSDimitry Andric IF->addDocument(std::move(Result.get())); 3495f757f3fSDimitry Andric } 3505f757f3fSDimitry Andric 3515f757f3fSDimitry Andric return std::move(IF); 3525f757f3fSDimitry Andric } 3535f757f3fSDimitry Andric 35406c3fb27SDimitry Andric static bool isYAMLTextStub(const FileType &Kind) { 35506c3fb27SDimitry Andric return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5); 35606c3fb27SDimitry Andric } 35706c3fb27SDimitry Andric 358fe6060f1SDimitry Andric bool InterfaceFile::operator==(const InterfaceFile &O) const { 359fe6060f1SDimitry Andric if (Targets != O.Targets) 360fe6060f1SDimitry Andric return false; 361fe6060f1SDimitry Andric if (InstallName != O.InstallName) 362fe6060f1SDimitry Andric return false; 363fe6060f1SDimitry Andric if ((CurrentVersion != O.CurrentVersion) || 364fe6060f1SDimitry Andric (CompatibilityVersion != O.CompatibilityVersion)) 365fe6060f1SDimitry Andric return false; 366fe6060f1SDimitry Andric if (SwiftABIVersion != O.SwiftABIVersion) 367fe6060f1SDimitry Andric return false; 368fe6060f1SDimitry Andric if (IsTwoLevelNamespace != O.IsTwoLevelNamespace) 369fe6060f1SDimitry Andric return false; 370fe6060f1SDimitry Andric if (IsAppExtensionSafe != O.IsAppExtensionSafe) 371fe6060f1SDimitry Andric return false; 3725f757f3fSDimitry Andric if (IsOSLibNotForSharedCache != O.IsOSLibNotForSharedCache) 3735f757f3fSDimitry Andric return false; 3745f757f3fSDimitry Andric if (HasSimSupport != O.HasSimSupport) 3755f757f3fSDimitry Andric return false; 376fe6060f1SDimitry Andric if (ParentUmbrellas != O.ParentUmbrellas) 377fe6060f1SDimitry Andric return false; 378fe6060f1SDimitry Andric if (AllowableClients != O.AllowableClients) 379fe6060f1SDimitry Andric return false; 380fe6060f1SDimitry Andric if (ReexportedLibraries != O.ReexportedLibraries) 381fe6060f1SDimitry Andric return false; 38206c3fb27SDimitry Andric if (*SymbolsSet != *O.SymbolsSet) 383fe6060f1SDimitry Andric return false; 38406c3fb27SDimitry Andric // Don't compare run search paths for older filetypes that cannot express 38506c3fb27SDimitry Andric // them. 38606c3fb27SDimitry Andric if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) { 38706c3fb27SDimitry Andric if (RPaths != O.RPaths) 38806c3fb27SDimitry Andric return false; 38906c3fb27SDimitry Andric if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets)) 39006c3fb27SDimitry Andric return false; 39106c3fb27SDimitry Andric } 39206c3fb27SDimitry Andric 393fe6060f1SDimitry Andric if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(), 394fe6060f1SDimitry Andric O.Documents.end(), 395fe6060f1SDimitry Andric [](const std::shared_ptr<InterfaceFile> LHS, 396fe6060f1SDimitry Andric const std::shared_ptr<InterfaceFile> RHS) { 397fe6060f1SDimitry Andric return *LHS == *RHS; 398fe6060f1SDimitry Andric })) 399fe6060f1SDimitry Andric return false; 400fe6060f1SDimitry Andric return true; 401fe6060f1SDimitry Andric } 402