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*5f757f3fSDimitry 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) { 27fe6060f1SDimitry Andric auto Client = addEntry(AllowableClients, InstallName); 28fe6060f1SDimitry Andric Client->addTarget(Target); 29fe6060f1SDimitry Andric } 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric void InterfaceFile::addReexportedLibrary(StringRef InstallName, 32fe6060f1SDimitry Andric const Target &Target) { 33fe6060f1SDimitry Andric auto Lib = addEntry(ReexportedLibraries, InstallName); 34fe6060f1SDimitry Andric Lib->addTarget(Target); 35fe6060f1SDimitry Andric } 36fe6060f1SDimitry Andric 37fe6060f1SDimitry Andric void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 38fe6060f1SDimitry Andric auto Iter = lower_bound(ParentUmbrellas, Target_, 39fe6060f1SDimitry Andric [](const std::pair<Target, std::string> &LHS, 40fe6060f1SDimitry Andric Target RHS) { return LHS.first < RHS; }); 41fe6060f1SDimitry Andric 42fe6060f1SDimitry Andric if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 43fe6060f1SDimitry Andric Iter->second = std::string(Parent); 44fe6060f1SDimitry Andric return; 45fe6060f1SDimitry Andric } 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric ParentUmbrellas.emplace(Iter, Target_, std::string(Parent)); 48fe6060f1SDimitry Andric } 49fe6060f1SDimitry Andric 5006c3fb27SDimitry Andric void InterfaceFile::addRPath(const Target &InputTarget, StringRef RPath) { 51*5f757f3fSDimitry Andric using RPathEntryT = const std::pair<Target, std::string>; 52*5f757f3fSDimitry Andric RPathEntryT Entry(InputTarget, RPath); 53*5f757f3fSDimitry Andric auto Iter = 54*5f757f3fSDimitry Andric lower_bound(RPaths, Entry, 55*5f757f3fSDimitry Andric [](RPathEntryT &LHS, RPathEntryT &RHS) { return LHS < RHS; }); 56fe6060f1SDimitry Andric 57*5f757f3fSDimitry Andric if ((Iter != RPaths.end()) && (*Iter == Entry)) 58fe6060f1SDimitry Andric return; 59fe6060f1SDimitry Andric 60*5f757f3fSDimitry Andric RPaths.emplace(Iter, Entry); 61fe6060f1SDimitry Andric } 62fe6060f1SDimitry Andric 63fe6060f1SDimitry Andric void InterfaceFile::addTarget(const Target &Target) { 64fe6060f1SDimitry Andric addEntry(Targets, Target); 65fe6060f1SDimitry Andric } 66fe6060f1SDimitry Andric 67fe6060f1SDimitry Andric InterfaceFile::const_filtered_target_range 68fe6060f1SDimitry Andric InterfaceFile::targets(ArchitectureSet Archs) const { 69fe6060f1SDimitry Andric std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 70fe6060f1SDimitry Andric return Archs.has(Target_.Arch); 71fe6060f1SDimitry Andric }; 72fe6060f1SDimitry Andric return make_filter_range(Targets, fn); 73fe6060f1SDimitry Andric } 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) { 76fe6060f1SDimitry Andric auto Pos = llvm::lower_bound(Documents, Document, 77fe6060f1SDimitry Andric [](const std::shared_ptr<InterfaceFile> &LHS, 78fe6060f1SDimitry Andric const std::shared_ptr<InterfaceFile> &RHS) { 79fe6060f1SDimitry Andric return LHS->InstallName < RHS->InstallName; 80fe6060f1SDimitry Andric }); 81fe6060f1SDimitry Andric Document->Parent = this; 82fe6060f1SDimitry Andric Documents.insert(Pos, Document); 83fe6060f1SDimitry Andric } 84fe6060f1SDimitry Andric 85*5f757f3fSDimitry Andric void InterfaceFile::inlineLibrary(std::shared_ptr<InterfaceFile> Library, 86*5f757f3fSDimitry Andric bool Overwrite) { 87*5f757f3fSDimitry Andric auto AddFwk = [&](std::shared_ptr<InterfaceFile> &&Reexport) { 88*5f757f3fSDimitry Andric auto It = lower_bound( 89*5f757f3fSDimitry Andric Documents, Reexport->getInstallName(), 90*5f757f3fSDimitry Andric [](std::shared_ptr<InterfaceFile> &Lhs, const StringRef Rhs) { 91*5f757f3fSDimitry Andric return Lhs->getInstallName() < Rhs; 92*5f757f3fSDimitry Andric }); 93*5f757f3fSDimitry Andric 94*5f757f3fSDimitry Andric if (Overwrite && It != Documents.end() && 95*5f757f3fSDimitry Andric Reexport->getInstallName() == (*It)->getInstallName()) { 96*5f757f3fSDimitry Andric std::replace(Documents.begin(), Documents.end(), *It, 97*5f757f3fSDimitry Andric std::move(Reexport)); 98*5f757f3fSDimitry Andric return; 99*5f757f3fSDimitry Andric } 100*5f757f3fSDimitry Andric 101*5f757f3fSDimitry Andric if ((It != Documents.end()) && 102*5f757f3fSDimitry Andric !(Reexport->getInstallName() < (*It)->getInstallName())) 103*5f757f3fSDimitry Andric return; 104*5f757f3fSDimitry Andric 105*5f757f3fSDimitry Andric Documents.emplace(It, std::move(Reexport)); 106*5f757f3fSDimitry Andric }; 107*5f757f3fSDimitry Andric for (auto Doc : Library->documents()) 108*5f757f3fSDimitry Andric AddFwk(std::move(Doc)); 109*5f757f3fSDimitry Andric 110*5f757f3fSDimitry Andric Library->Documents.clear(); 111*5f757f3fSDimitry Andric AddFwk(std::move(Library)); 112*5f757f3fSDimitry Andric } 113*5f757f3fSDimitry Andric 114*5f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 115*5f757f3fSDimitry Andric InterfaceFile::merge(const InterfaceFile *O) const { 116*5f757f3fSDimitry Andric // Verify files can be merged. 117*5f757f3fSDimitry Andric if (getInstallName() != O->getInstallName()) { 118*5f757f3fSDimitry Andric return make_error<StringError>("install names do not match", 119*5f757f3fSDimitry Andric inconvertibleErrorCode()); 120*5f757f3fSDimitry Andric } 121*5f757f3fSDimitry Andric 122*5f757f3fSDimitry Andric if (getCurrentVersion() != O->getCurrentVersion()) { 123*5f757f3fSDimitry Andric return make_error<StringError>("current versions do not match", 124*5f757f3fSDimitry Andric inconvertibleErrorCode()); 125*5f757f3fSDimitry Andric } 126*5f757f3fSDimitry Andric 127*5f757f3fSDimitry Andric if (getCompatibilityVersion() != O->getCompatibilityVersion()) { 128*5f757f3fSDimitry Andric return make_error<StringError>("compatibility versions do not match", 129*5f757f3fSDimitry Andric inconvertibleErrorCode()); 130*5f757f3fSDimitry Andric } 131*5f757f3fSDimitry Andric 132*5f757f3fSDimitry Andric if ((getSwiftABIVersion() != 0) && (O->getSwiftABIVersion() != 0) && 133*5f757f3fSDimitry Andric (getSwiftABIVersion() != O->getSwiftABIVersion())) { 134*5f757f3fSDimitry Andric return make_error<StringError>("swift ABI versions do not match", 135*5f757f3fSDimitry Andric inconvertibleErrorCode()); 136*5f757f3fSDimitry Andric } 137*5f757f3fSDimitry Andric 138*5f757f3fSDimitry Andric if (isTwoLevelNamespace() != O->isTwoLevelNamespace()) { 139*5f757f3fSDimitry Andric return make_error<StringError>("two level namespace flags do not match", 140*5f757f3fSDimitry Andric inconvertibleErrorCode()); 141*5f757f3fSDimitry Andric } 142*5f757f3fSDimitry Andric 143*5f757f3fSDimitry Andric if (isApplicationExtensionSafe() != O->isApplicationExtensionSafe()) { 144*5f757f3fSDimitry Andric return make_error<StringError>( 145*5f757f3fSDimitry Andric "application extension safe flags do not match", 146*5f757f3fSDimitry Andric inconvertibleErrorCode()); 147*5f757f3fSDimitry Andric } 148*5f757f3fSDimitry Andric 149*5f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 150*5f757f3fSDimitry Andric IF->setFileType(std::max(getFileType(), O->getFileType())); 151*5f757f3fSDimitry Andric IF->setPath(getPath()); 152*5f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 153*5f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 154*5f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 155*5f757f3fSDimitry Andric 156*5f757f3fSDimitry Andric if (getSwiftABIVersion() == 0) 157*5f757f3fSDimitry Andric IF->setSwiftABIVersion(O->getSwiftABIVersion()); 158*5f757f3fSDimitry Andric else 159*5f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 160*5f757f3fSDimitry Andric 161*5f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 162*5f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 163*5f757f3fSDimitry Andric 164*5f757f3fSDimitry Andric for (const auto &It : umbrellas()) { 165*5f757f3fSDimitry Andric if (!It.second.empty()) 166*5f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 167*5f757f3fSDimitry Andric } 168*5f757f3fSDimitry Andric for (const auto &It : O->umbrellas()) { 169*5f757f3fSDimitry Andric if (!It.second.empty()) 170*5f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 171*5f757f3fSDimitry Andric } 172*5f757f3fSDimitry Andric IF->addTargets(targets()); 173*5f757f3fSDimitry Andric IF->addTargets(O->targets()); 174*5f757f3fSDimitry Andric 175*5f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) 176*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 177*5f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 178*5f757f3fSDimitry Andric 179*5f757f3fSDimitry Andric for (const auto &Lib : O->allowableClients()) 180*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 181*5f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 182*5f757f3fSDimitry Andric 183*5f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) 184*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 185*5f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 186*5f757f3fSDimitry Andric 187*5f757f3fSDimitry Andric for (const auto &Lib : O->reexportedLibraries()) 188*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 189*5f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 190*5f757f3fSDimitry Andric 191*5f757f3fSDimitry Andric for (const auto &[Target, Path] : rpaths()) 192*5f757f3fSDimitry Andric IF->addRPath(Target, Path); 193*5f757f3fSDimitry Andric for (const auto &[Target, Path] : O->rpaths()) 194*5f757f3fSDimitry Andric IF->addRPath(Target, Path); 195*5f757f3fSDimitry Andric 196*5f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 197*5f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 198*5f757f3fSDimitry Andric Sym->getFlags()); 199*5f757f3fSDimitry Andric } 200*5f757f3fSDimitry Andric 201*5f757f3fSDimitry Andric for (const auto *Sym : O->symbols()) { 202*5f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 203*5f757f3fSDimitry Andric Sym->getFlags()); 204*5f757f3fSDimitry Andric } 205*5f757f3fSDimitry Andric 206*5f757f3fSDimitry Andric return std::move(IF); 207*5f757f3fSDimitry Andric } 208*5f757f3fSDimitry Andric 209*5f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 210*5f757f3fSDimitry Andric InterfaceFile::remove(Architecture Arch) const { 211*5f757f3fSDimitry Andric if (getArchitectures() == Arch) 212*5f757f3fSDimitry Andric return make_error<StringError>("cannot remove last architecture slice '" + 213*5f757f3fSDimitry Andric getArchitectureName(Arch) + "'", 214*5f757f3fSDimitry Andric inconvertibleErrorCode()); 215*5f757f3fSDimitry Andric 216*5f757f3fSDimitry Andric if (!getArchitectures().has(Arch)) { 217*5f757f3fSDimitry Andric bool Found = false; 218*5f757f3fSDimitry Andric for (auto &Doc : Documents) { 219*5f757f3fSDimitry Andric if (Doc->getArchitectures().has(Arch)) { 220*5f757f3fSDimitry Andric Found = true; 221*5f757f3fSDimitry Andric break; 222*5f757f3fSDimitry Andric } 223*5f757f3fSDimitry Andric } 224*5f757f3fSDimitry Andric 225*5f757f3fSDimitry Andric if (!Found) 226*5f757f3fSDimitry Andric return make_error<TextAPIError>(TextAPIErrorCode::NoSuchArchitecture); 227*5f757f3fSDimitry Andric } 228*5f757f3fSDimitry Andric 229*5f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 230*5f757f3fSDimitry Andric IF->setFileType(getFileType()); 231*5f757f3fSDimitry Andric IF->setPath(getPath()); 232*5f757f3fSDimitry Andric IF->addTargets(targets(ArchitectureSet::All().clear(Arch))); 233*5f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 234*5f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 235*5f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 236*5f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 237*5f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 238*5f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 239*5f757f3fSDimitry Andric for (const auto &It : umbrellas()) 240*5f757f3fSDimitry Andric if (It.first.Arch != Arch) 241*5f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 242*5f757f3fSDimitry Andric 243*5f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) { 244*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 245*5f757f3fSDimitry Andric if (Target.Arch != Arch) 246*5f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 247*5f757f3fSDimitry Andric } 248*5f757f3fSDimitry Andric 249*5f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) { 250*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 251*5f757f3fSDimitry Andric if (Target.Arch != Arch) 252*5f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 253*5f757f3fSDimitry Andric } 254*5f757f3fSDimitry Andric 255*5f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 256*5f757f3fSDimitry Andric auto Archs = Sym->getArchitectures(); 257*5f757f3fSDimitry Andric Archs.clear(Arch); 258*5f757f3fSDimitry Andric if (Archs.empty()) 259*5f757f3fSDimitry Andric continue; 260*5f757f3fSDimitry Andric 261*5f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Archs), 262*5f757f3fSDimitry Andric Sym->getFlags()); 263*5f757f3fSDimitry Andric } 264*5f757f3fSDimitry Andric 265*5f757f3fSDimitry Andric for (auto &Doc : Documents) { 266*5f757f3fSDimitry Andric // Skip the inlined document if the to be removed architecture is the 267*5f757f3fSDimitry Andric // only one left. 268*5f757f3fSDimitry Andric if (Doc->getArchitectures() == Arch) 269*5f757f3fSDimitry Andric continue; 270*5f757f3fSDimitry Andric 271*5f757f3fSDimitry Andric // If the document doesn't contain the arch, then no work is to be done 272*5f757f3fSDimitry Andric // and it can be copied over. 273*5f757f3fSDimitry Andric if (!Doc->getArchitectures().has(Arch)) { 274*5f757f3fSDimitry Andric auto NewDoc = Doc; 275*5f757f3fSDimitry Andric IF->addDocument(std::move(NewDoc)); 276*5f757f3fSDimitry Andric continue; 277*5f757f3fSDimitry Andric } 278*5f757f3fSDimitry Andric 279*5f757f3fSDimitry Andric auto Result = Doc->remove(Arch); 280*5f757f3fSDimitry Andric if (!Result) 281*5f757f3fSDimitry Andric return Result; 282*5f757f3fSDimitry Andric 283*5f757f3fSDimitry Andric IF->addDocument(std::move(Result.get())); 284*5f757f3fSDimitry Andric } 285*5f757f3fSDimitry Andric 286*5f757f3fSDimitry Andric return std::move(IF); 287*5f757f3fSDimitry Andric } 288*5f757f3fSDimitry Andric 289*5f757f3fSDimitry Andric Expected<std::unique_ptr<InterfaceFile>> 290*5f757f3fSDimitry Andric InterfaceFile::extract(Architecture Arch) const { 291*5f757f3fSDimitry Andric if (!getArchitectures().has(Arch)) { 292*5f757f3fSDimitry Andric return make_error<StringError>("file doesn't have architecture '" + 293*5f757f3fSDimitry Andric getArchitectureName(Arch) + "'", 294*5f757f3fSDimitry Andric inconvertibleErrorCode()); 295*5f757f3fSDimitry Andric } 296*5f757f3fSDimitry Andric 297*5f757f3fSDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 298*5f757f3fSDimitry Andric IF->setFileType(getFileType()); 299*5f757f3fSDimitry Andric IF->setPath(getPath()); 300*5f757f3fSDimitry Andric IF->addTargets(targets(Arch)); 301*5f757f3fSDimitry Andric IF->setInstallName(getInstallName()); 302*5f757f3fSDimitry Andric IF->setCurrentVersion(getCurrentVersion()); 303*5f757f3fSDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion()); 304*5f757f3fSDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion()); 305*5f757f3fSDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace()); 306*5f757f3fSDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 307*5f757f3fSDimitry Andric for (const auto &It : umbrellas()) 308*5f757f3fSDimitry Andric if (It.first.Arch == Arch) 309*5f757f3fSDimitry Andric IF->addParentUmbrella(It.first, It.second); 310*5f757f3fSDimitry Andric 311*5f757f3fSDimitry Andric for (const auto &It : rpaths()) 312*5f757f3fSDimitry Andric if (It.first.Arch == Arch) 313*5f757f3fSDimitry Andric IF->addRPath(It.first, It.second); 314*5f757f3fSDimitry Andric 315*5f757f3fSDimitry Andric for (const auto &Lib : allowableClients()) 316*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 317*5f757f3fSDimitry Andric if (Target.Arch == Arch) 318*5f757f3fSDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target); 319*5f757f3fSDimitry Andric 320*5f757f3fSDimitry Andric for (const auto &Lib : reexportedLibraries()) 321*5f757f3fSDimitry Andric for (const auto &Target : Lib.targets()) 322*5f757f3fSDimitry Andric if (Target.Arch == Arch) 323*5f757f3fSDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target); 324*5f757f3fSDimitry Andric 325*5f757f3fSDimitry Andric for (const auto *Sym : symbols()) { 326*5f757f3fSDimitry Andric if (Sym->hasArchitecture(Arch)) 327*5f757f3fSDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Arch), 328*5f757f3fSDimitry Andric Sym->getFlags()); 329*5f757f3fSDimitry Andric } 330*5f757f3fSDimitry Andric 331*5f757f3fSDimitry Andric for (auto &Doc : Documents) { 332*5f757f3fSDimitry Andric // Skip documents that don't have the requested architecture. 333*5f757f3fSDimitry Andric if (!Doc->getArchitectures().has(Arch)) 334*5f757f3fSDimitry Andric continue; 335*5f757f3fSDimitry Andric 336*5f757f3fSDimitry Andric auto Result = Doc->extract(Arch); 337*5f757f3fSDimitry Andric if (!Result) 338*5f757f3fSDimitry Andric return Result; 339*5f757f3fSDimitry Andric 340*5f757f3fSDimitry Andric IF->addDocument(std::move(Result.get())); 341*5f757f3fSDimitry Andric } 342*5f757f3fSDimitry Andric 343*5f757f3fSDimitry Andric return std::move(IF); 344*5f757f3fSDimitry Andric } 345*5f757f3fSDimitry Andric 34606c3fb27SDimitry Andric static bool isYAMLTextStub(const FileType &Kind) { 34706c3fb27SDimitry Andric return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5); 34806c3fb27SDimitry Andric } 34906c3fb27SDimitry Andric 350fe6060f1SDimitry Andric bool InterfaceFile::operator==(const InterfaceFile &O) const { 351fe6060f1SDimitry Andric if (Targets != O.Targets) 352fe6060f1SDimitry Andric return false; 353fe6060f1SDimitry Andric if (InstallName != O.InstallName) 354fe6060f1SDimitry Andric return false; 355fe6060f1SDimitry Andric if ((CurrentVersion != O.CurrentVersion) || 356fe6060f1SDimitry Andric (CompatibilityVersion != O.CompatibilityVersion)) 357fe6060f1SDimitry Andric return false; 358fe6060f1SDimitry Andric if (SwiftABIVersion != O.SwiftABIVersion) 359fe6060f1SDimitry Andric return false; 360fe6060f1SDimitry Andric if (IsTwoLevelNamespace != O.IsTwoLevelNamespace) 361fe6060f1SDimitry Andric return false; 362fe6060f1SDimitry Andric if (IsAppExtensionSafe != O.IsAppExtensionSafe) 363fe6060f1SDimitry Andric return false; 364*5f757f3fSDimitry Andric if (IsOSLibNotForSharedCache != O.IsOSLibNotForSharedCache) 365*5f757f3fSDimitry Andric return false; 366*5f757f3fSDimitry Andric if (HasSimSupport != O.HasSimSupport) 367*5f757f3fSDimitry Andric return false; 368fe6060f1SDimitry Andric if (ParentUmbrellas != O.ParentUmbrellas) 369fe6060f1SDimitry Andric return false; 370fe6060f1SDimitry Andric if (AllowableClients != O.AllowableClients) 371fe6060f1SDimitry Andric return false; 372fe6060f1SDimitry Andric if (ReexportedLibraries != O.ReexportedLibraries) 373fe6060f1SDimitry Andric return false; 37406c3fb27SDimitry Andric if (*SymbolsSet != *O.SymbolsSet) 375fe6060f1SDimitry Andric return false; 37606c3fb27SDimitry Andric // Don't compare run search paths for older filetypes that cannot express 37706c3fb27SDimitry Andric // them. 37806c3fb27SDimitry Andric if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) { 37906c3fb27SDimitry Andric if (RPaths != O.RPaths) 38006c3fb27SDimitry Andric return false; 38106c3fb27SDimitry Andric if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets)) 38206c3fb27SDimitry Andric return false; 38306c3fb27SDimitry Andric } 38406c3fb27SDimitry Andric 385fe6060f1SDimitry Andric if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(), 386fe6060f1SDimitry Andric O.Documents.end(), 387fe6060f1SDimitry Andric [](const std::shared_ptr<InterfaceFile> LHS, 388fe6060f1SDimitry Andric const std::shared_ptr<InterfaceFile> RHS) { 389fe6060f1SDimitry Andric return *LHS == *RHS; 390fe6060f1SDimitry Andric })) 391fe6060f1SDimitry Andric return false; 392fe6060f1SDimitry Andric return true; 393fe6060f1SDimitry Andric } 394