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