10116d04dSCyndy Ishida //===- InterfaceFile.cpp --------------------------------------------------===// 20116d04dSCyndy Ishida // 30116d04dSCyndy Ishida // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40116d04dSCyndy Ishida // See https://llvm.org/LICENSE.txt for license information. 50116d04dSCyndy Ishida // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60116d04dSCyndy Ishida // 70116d04dSCyndy Ishida //===----------------------------------------------------------------------===// 80116d04dSCyndy Ishida // 90116d04dSCyndy Ishida // Implements the Interface File. 100116d04dSCyndy Ishida // 110116d04dSCyndy Ishida //===----------------------------------------------------------------------===// 120116d04dSCyndy Ishida 130116d04dSCyndy Ishida #include "llvm/TextAPI/InterfaceFile.h" 143a080a01SCyndy Ishida #include "llvm/TextAPI/RecordsSlice.h" 1516c1f436SCyndy Ishida #include "llvm/TextAPI/TextAPIError.h" 160116d04dSCyndy Ishida #include <iomanip> 170116d04dSCyndy Ishida #include <sstream> 180116d04dSCyndy Ishida 190116d04dSCyndy Ishida using namespace llvm; 200116d04dSCyndy Ishida using namespace llvm::MachO; 210116d04dSCyndy Ishida 220116d04dSCyndy Ishida void InterfaceFileRef::addTarget(const Target &Target) { 230116d04dSCyndy Ishida addEntry(Targets, Target); 240116d04dSCyndy Ishida } 250116d04dSCyndy Ishida 260116d04dSCyndy Ishida void InterfaceFile::addAllowableClient(StringRef InstallName, 270116d04dSCyndy Ishida const Target &Target) { 288ca0364dSCyndy Ishida if (InstallName.empty()) 298ca0364dSCyndy Ishida return; 300116d04dSCyndy Ishida auto Client = addEntry(AllowableClients, InstallName); 310116d04dSCyndy Ishida Client->addTarget(Target); 320116d04dSCyndy Ishida } 330116d04dSCyndy Ishida 340116d04dSCyndy Ishida void InterfaceFile::addReexportedLibrary(StringRef InstallName, 350116d04dSCyndy Ishida const Target &Target) { 368ca0364dSCyndy Ishida if (InstallName.empty()) 378ca0364dSCyndy Ishida return; 380116d04dSCyndy Ishida auto Lib = addEntry(ReexportedLibraries, InstallName); 390116d04dSCyndy Ishida Lib->addTarget(Target); 400116d04dSCyndy Ishida } 410116d04dSCyndy Ishida 420116d04dSCyndy Ishida void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 438ca0364dSCyndy Ishida if (Parent.empty()) 448ca0364dSCyndy Ishida return; 450116d04dSCyndy Ishida auto Iter = lower_bound(ParentUmbrellas, Target_, 460116d04dSCyndy Ishida [](const std::pair<Target, std::string> &LHS, 470116d04dSCyndy Ishida Target RHS) { return LHS.first < RHS; }); 480116d04dSCyndy Ishida 490116d04dSCyndy Ishida if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 500116d04dSCyndy Ishida Iter->second = std::string(Parent); 510116d04dSCyndy Ishida return; 520116d04dSCyndy Ishida } 530116d04dSCyndy Ishida 540116d04dSCyndy Ishida ParentUmbrellas.emplace(Iter, Target_, std::string(Parent)); 550116d04dSCyndy Ishida } 560116d04dSCyndy Ishida 57515d3f7dSCyndy Ishida void InterfaceFile::addRPath(StringRef RPath, const Target &InputTarget) { 588ca0364dSCyndy Ishida if (RPath.empty()) 598ca0364dSCyndy Ishida return; 601a0d6992SCyndy Ishida using RPathEntryT = const std::pair<Target, std::string>; 611a0d6992SCyndy Ishida RPathEntryT Entry(InputTarget, RPath); 621a0d6992SCyndy Ishida auto Iter = 631a0d6992SCyndy Ishida lower_bound(RPaths, Entry, 641a0d6992SCyndy Ishida [](RPathEntryT &LHS, RPathEntryT &RHS) { return LHS < RHS; }); 65b70d87bcSCyndy Ishida 661a0d6992SCyndy Ishida if ((Iter != RPaths.end()) && (*Iter == Entry)) 67b70d87bcSCyndy Ishida return; 68b70d87bcSCyndy Ishida 691a0d6992SCyndy Ishida RPaths.emplace(Iter, Entry); 70b70d87bcSCyndy Ishida } 71b70d87bcSCyndy Ishida 720116d04dSCyndy Ishida void InterfaceFile::addTarget(const Target &Target) { 730116d04dSCyndy Ishida addEntry(Targets, Target); 740116d04dSCyndy Ishida } 750116d04dSCyndy Ishida 760116d04dSCyndy Ishida InterfaceFile::const_filtered_target_range 770116d04dSCyndy Ishida InterfaceFile::targets(ArchitectureSet Archs) const { 780116d04dSCyndy Ishida std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 790116d04dSCyndy Ishida return Archs.has(Target_.Arch); 800116d04dSCyndy Ishida }; 810116d04dSCyndy Ishida return make_filter_range(Targets, fn); 820116d04dSCyndy Ishida } 830116d04dSCyndy Ishida 840116d04dSCyndy Ishida void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) { 850116d04dSCyndy Ishida auto Pos = llvm::lower_bound(Documents, Document, 860116d04dSCyndy Ishida [](const std::shared_ptr<InterfaceFile> &LHS, 870116d04dSCyndy Ishida const std::shared_ptr<InterfaceFile> &RHS) { 880116d04dSCyndy Ishida return LHS->InstallName < RHS->InstallName; 890116d04dSCyndy Ishida }); 901569e0edSCyndy Ishida assert((Pos == Documents.end() || 911569e0edSCyndy Ishida (*Pos)->InstallName != Document->InstallName) && 921569e0edSCyndy Ishida "Unexpected duplicate document added"); 930116d04dSCyndy Ishida Document->Parent = this; 940116d04dSCyndy Ishida Documents.insert(Pos, Document); 950116d04dSCyndy Ishida } 960116d04dSCyndy Ishida 9716c1f436SCyndy Ishida void InterfaceFile::inlineLibrary(std::shared_ptr<InterfaceFile> Library, 9816c1f436SCyndy Ishida bool Overwrite) { 9916c1f436SCyndy Ishida auto AddFwk = [&](std::shared_ptr<InterfaceFile> &&Reexport) { 10016c1f436SCyndy Ishida auto It = lower_bound( 10116c1f436SCyndy Ishida Documents, Reexport->getInstallName(), 10216c1f436SCyndy Ishida [](std::shared_ptr<InterfaceFile> &Lhs, const StringRef Rhs) { 10316c1f436SCyndy Ishida return Lhs->getInstallName() < Rhs; 10416c1f436SCyndy Ishida }); 10516c1f436SCyndy Ishida 10616c1f436SCyndy Ishida if (Overwrite && It != Documents.end() && 10716c1f436SCyndy Ishida Reexport->getInstallName() == (*It)->getInstallName()) { 10816c1f436SCyndy Ishida std::replace(Documents.begin(), Documents.end(), *It, 10916c1f436SCyndy Ishida std::move(Reexport)); 11016c1f436SCyndy Ishida return; 11116c1f436SCyndy Ishida } 11216c1f436SCyndy Ishida 11316c1f436SCyndy Ishida if ((It != Documents.end()) && 11416c1f436SCyndy Ishida !(Reexport->getInstallName() < (*It)->getInstallName())) 11516c1f436SCyndy Ishida return; 11616c1f436SCyndy Ishida 11716c1f436SCyndy Ishida Documents.emplace(It, std::move(Reexport)); 11816c1f436SCyndy Ishida }; 11916c1f436SCyndy Ishida for (auto Doc : Library->documents()) 12016c1f436SCyndy Ishida AddFwk(std::move(Doc)); 12116c1f436SCyndy Ishida 12216c1f436SCyndy Ishida Library->Documents.clear(); 12316c1f436SCyndy Ishida AddFwk(std::move(Library)); 12416c1f436SCyndy Ishida } 12516c1f436SCyndy Ishida 12616c1f436SCyndy Ishida Expected<std::unique_ptr<InterfaceFile>> 12716c1f436SCyndy Ishida InterfaceFile::merge(const InterfaceFile *O) const { 12816c1f436SCyndy Ishida // Verify files can be merged. 12916c1f436SCyndy Ishida if (getInstallName() != O->getInstallName()) { 13016c1f436SCyndy Ishida return make_error<StringError>("install names do not match", 13116c1f436SCyndy Ishida inconvertibleErrorCode()); 13216c1f436SCyndy Ishida } 13316c1f436SCyndy Ishida 13416c1f436SCyndy Ishida if (getCurrentVersion() != O->getCurrentVersion()) { 13516c1f436SCyndy Ishida return make_error<StringError>("current versions do not match", 13616c1f436SCyndy Ishida inconvertibleErrorCode()); 13716c1f436SCyndy Ishida } 13816c1f436SCyndy Ishida 13916c1f436SCyndy Ishida if (getCompatibilityVersion() != O->getCompatibilityVersion()) { 14016c1f436SCyndy Ishida return make_error<StringError>("compatibility versions do not match", 14116c1f436SCyndy Ishida inconvertibleErrorCode()); 14216c1f436SCyndy Ishida } 14316c1f436SCyndy Ishida 14416c1f436SCyndy Ishida if ((getSwiftABIVersion() != 0) && (O->getSwiftABIVersion() != 0) && 14516c1f436SCyndy Ishida (getSwiftABIVersion() != O->getSwiftABIVersion())) { 14616c1f436SCyndy Ishida return make_error<StringError>("swift ABI versions do not match", 14716c1f436SCyndy Ishida inconvertibleErrorCode()); 14816c1f436SCyndy Ishida } 14916c1f436SCyndy Ishida 15016c1f436SCyndy Ishida if (isTwoLevelNamespace() != O->isTwoLevelNamespace()) { 15116c1f436SCyndy Ishida return make_error<StringError>("two level namespace flags do not match", 15216c1f436SCyndy Ishida inconvertibleErrorCode()); 15316c1f436SCyndy Ishida } 15416c1f436SCyndy Ishida 15516c1f436SCyndy Ishida if (isApplicationExtensionSafe() != O->isApplicationExtensionSafe()) { 15616c1f436SCyndy Ishida return make_error<StringError>( 15716c1f436SCyndy Ishida "application extension safe flags do not match", 15816c1f436SCyndy Ishida inconvertibleErrorCode()); 15916c1f436SCyndy Ishida } 16016c1f436SCyndy Ishida 16116c1f436SCyndy Ishida std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 16216c1f436SCyndy Ishida IF->setFileType(std::max(getFileType(), O->getFileType())); 16316c1f436SCyndy Ishida IF->setPath(getPath()); 16416c1f436SCyndy Ishida IF->setInstallName(getInstallName()); 16516c1f436SCyndy Ishida IF->setCurrentVersion(getCurrentVersion()); 16616c1f436SCyndy Ishida IF->setCompatibilityVersion(getCompatibilityVersion()); 16716c1f436SCyndy Ishida 16816c1f436SCyndy Ishida if (getSwiftABIVersion() == 0) 16916c1f436SCyndy Ishida IF->setSwiftABIVersion(O->getSwiftABIVersion()); 17016c1f436SCyndy Ishida else 17116c1f436SCyndy Ishida IF->setSwiftABIVersion(getSwiftABIVersion()); 17216c1f436SCyndy Ishida 17316c1f436SCyndy Ishida IF->setTwoLevelNamespace(isTwoLevelNamespace()); 17416c1f436SCyndy Ishida IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 175*03506bc0SCyndy Ishida IF->setOSLibNotForSharedCache(isOSLibNotForSharedCache()); 17616c1f436SCyndy Ishida 17716c1f436SCyndy Ishida for (const auto &It : umbrellas()) { 17816c1f436SCyndy Ishida if (!It.second.empty()) 17916c1f436SCyndy Ishida IF->addParentUmbrella(It.first, It.second); 18016c1f436SCyndy Ishida } 18116c1f436SCyndy Ishida for (const auto &It : O->umbrellas()) { 18216c1f436SCyndy Ishida if (!It.second.empty()) 18316c1f436SCyndy Ishida IF->addParentUmbrella(It.first, It.second); 18416c1f436SCyndy Ishida } 18516c1f436SCyndy Ishida IF->addTargets(targets()); 18616c1f436SCyndy Ishida IF->addTargets(O->targets()); 18716c1f436SCyndy Ishida 18816c1f436SCyndy Ishida for (const auto &Lib : allowableClients()) 18916c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 19016c1f436SCyndy Ishida IF->addAllowableClient(Lib.getInstallName(), Target); 19116c1f436SCyndy Ishida 19216c1f436SCyndy Ishida for (const auto &Lib : O->allowableClients()) 19316c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 19416c1f436SCyndy Ishida IF->addAllowableClient(Lib.getInstallName(), Target); 19516c1f436SCyndy Ishida 19616c1f436SCyndy Ishida for (const auto &Lib : reexportedLibraries()) 19716c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 19816c1f436SCyndy Ishida IF->addReexportedLibrary(Lib.getInstallName(), Target); 19916c1f436SCyndy Ishida 20016c1f436SCyndy Ishida for (const auto &Lib : O->reexportedLibraries()) 20116c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 20216c1f436SCyndy Ishida IF->addReexportedLibrary(Lib.getInstallName(), Target); 20316c1f436SCyndy Ishida 20416c1f436SCyndy Ishida for (const auto &[Target, Path] : rpaths()) 205515d3f7dSCyndy Ishida IF->addRPath(Path, Target); 20616c1f436SCyndy Ishida for (const auto &[Target, Path] : O->rpaths()) 207515d3f7dSCyndy Ishida IF->addRPath(Path, Target); 20816c1f436SCyndy Ishida 20916c1f436SCyndy Ishida for (const auto *Sym : symbols()) { 21016c1f436SCyndy Ishida IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 21116c1f436SCyndy Ishida Sym->getFlags()); 21216c1f436SCyndy Ishida } 21316c1f436SCyndy Ishida 21416c1f436SCyndy Ishida for (const auto *Sym : O->symbols()) { 21516c1f436SCyndy Ishida IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(), 21616c1f436SCyndy Ishida Sym->getFlags()); 21716c1f436SCyndy Ishida } 21816c1f436SCyndy Ishida 21916c1f436SCyndy Ishida return std::move(IF); 22016c1f436SCyndy Ishida } 22116c1f436SCyndy Ishida 22216c1f436SCyndy Ishida Expected<std::unique_ptr<InterfaceFile>> 22316c1f436SCyndy Ishida InterfaceFile::remove(Architecture Arch) const { 22416c1f436SCyndy Ishida if (getArchitectures() == Arch) 22516c1f436SCyndy Ishida return make_error<StringError>("cannot remove last architecture slice '" + 22616c1f436SCyndy Ishida getArchitectureName(Arch) + "'", 22716c1f436SCyndy Ishida inconvertibleErrorCode()); 22816c1f436SCyndy Ishida 22916c1f436SCyndy Ishida if (!getArchitectures().has(Arch)) { 23016c1f436SCyndy Ishida bool Found = false; 23116c1f436SCyndy Ishida for (auto &Doc : Documents) { 23216c1f436SCyndy Ishida if (Doc->getArchitectures().has(Arch)) { 23316c1f436SCyndy Ishida Found = true; 23416c1f436SCyndy Ishida break; 23516c1f436SCyndy Ishida } 23616c1f436SCyndy Ishida } 23716c1f436SCyndy Ishida 23816c1f436SCyndy Ishida if (!Found) 23916c1f436SCyndy Ishida return make_error<TextAPIError>(TextAPIErrorCode::NoSuchArchitecture); 24016c1f436SCyndy Ishida } 24116c1f436SCyndy Ishida 242*03506bc0SCyndy Ishida // FIXME: Figure out how to keep these attributes in sync when new ones are 243*03506bc0SCyndy Ishida // added. 24416c1f436SCyndy Ishida std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 24516c1f436SCyndy Ishida IF->setFileType(getFileType()); 24616c1f436SCyndy Ishida IF->setPath(getPath()); 24716c1f436SCyndy Ishida IF->addTargets(targets(ArchitectureSet::All().clear(Arch))); 24816c1f436SCyndy Ishida IF->setInstallName(getInstallName()); 24916c1f436SCyndy Ishida IF->setCurrentVersion(getCurrentVersion()); 25016c1f436SCyndy Ishida IF->setCompatibilityVersion(getCompatibilityVersion()); 25116c1f436SCyndy Ishida IF->setSwiftABIVersion(getSwiftABIVersion()); 25216c1f436SCyndy Ishida IF->setTwoLevelNamespace(isTwoLevelNamespace()); 25316c1f436SCyndy Ishida IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 254*03506bc0SCyndy Ishida IF->setOSLibNotForSharedCache(isOSLibNotForSharedCache()); 25516c1f436SCyndy Ishida for (const auto &It : umbrellas()) 25616c1f436SCyndy Ishida if (It.first.Arch != Arch) 25716c1f436SCyndy Ishida IF->addParentUmbrella(It.first, It.second); 25816c1f436SCyndy Ishida 25916c1f436SCyndy Ishida for (const auto &Lib : allowableClients()) { 26016c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 26116c1f436SCyndy Ishida if (Target.Arch != Arch) 26216c1f436SCyndy Ishida IF->addAllowableClient(Lib.getInstallName(), Target); 26316c1f436SCyndy Ishida } 26416c1f436SCyndy Ishida 26516c1f436SCyndy Ishida for (const auto &Lib : reexportedLibraries()) { 26616c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 26716c1f436SCyndy Ishida if (Target.Arch != Arch) 26816c1f436SCyndy Ishida IF->addReexportedLibrary(Lib.getInstallName(), Target); 26916c1f436SCyndy Ishida } 27016c1f436SCyndy Ishida 27116c1f436SCyndy Ishida for (const auto *Sym : symbols()) { 27216c1f436SCyndy Ishida auto Archs = Sym->getArchitectures(); 27316c1f436SCyndy Ishida Archs.clear(Arch); 27416c1f436SCyndy Ishida if (Archs.empty()) 27516c1f436SCyndy Ishida continue; 27616c1f436SCyndy Ishida 27716c1f436SCyndy Ishida IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Archs), 27816c1f436SCyndy Ishida Sym->getFlags()); 27916c1f436SCyndy Ishida } 28016c1f436SCyndy Ishida 28116c1f436SCyndy Ishida for (auto &Doc : Documents) { 28216c1f436SCyndy Ishida // Skip the inlined document if the to be removed architecture is the 28316c1f436SCyndy Ishida // only one left. 28416c1f436SCyndy Ishida if (Doc->getArchitectures() == Arch) 28516c1f436SCyndy Ishida continue; 28616c1f436SCyndy Ishida 28716c1f436SCyndy Ishida // If the document doesn't contain the arch, then no work is to be done 28816c1f436SCyndy Ishida // and it can be copied over. 28916c1f436SCyndy Ishida if (!Doc->getArchitectures().has(Arch)) { 29016c1f436SCyndy Ishida auto NewDoc = Doc; 29116c1f436SCyndy Ishida IF->addDocument(std::move(NewDoc)); 29216c1f436SCyndy Ishida continue; 29316c1f436SCyndy Ishida } 29416c1f436SCyndy Ishida 29516c1f436SCyndy Ishida auto Result = Doc->remove(Arch); 29616c1f436SCyndy Ishida if (!Result) 29716c1f436SCyndy Ishida return Result; 29816c1f436SCyndy Ishida 29916c1f436SCyndy Ishida IF->addDocument(std::move(Result.get())); 30016c1f436SCyndy Ishida } 30116c1f436SCyndy Ishida 30216c1f436SCyndy Ishida return std::move(IF); 30316c1f436SCyndy Ishida } 30416c1f436SCyndy Ishida 30516c1f436SCyndy Ishida Expected<std::unique_ptr<InterfaceFile>> 30616c1f436SCyndy Ishida InterfaceFile::extract(Architecture Arch) const { 30716c1f436SCyndy Ishida if (!getArchitectures().has(Arch)) { 30816c1f436SCyndy Ishida return make_error<StringError>("file doesn't have architecture '" + 30916c1f436SCyndy Ishida getArchitectureName(Arch) + "'", 31016c1f436SCyndy Ishida inconvertibleErrorCode()); 31116c1f436SCyndy Ishida } 31216c1f436SCyndy Ishida 31316c1f436SCyndy Ishida std::unique_ptr<InterfaceFile> IF(new InterfaceFile()); 31416c1f436SCyndy Ishida IF->setFileType(getFileType()); 31516c1f436SCyndy Ishida IF->setPath(getPath()); 31616c1f436SCyndy Ishida IF->addTargets(targets(Arch)); 31716c1f436SCyndy Ishida IF->setInstallName(getInstallName()); 31816c1f436SCyndy Ishida IF->setCurrentVersion(getCurrentVersion()); 31916c1f436SCyndy Ishida IF->setCompatibilityVersion(getCompatibilityVersion()); 32016c1f436SCyndy Ishida IF->setSwiftABIVersion(getSwiftABIVersion()); 32116c1f436SCyndy Ishida IF->setTwoLevelNamespace(isTwoLevelNamespace()); 32216c1f436SCyndy Ishida IF->setApplicationExtensionSafe(isApplicationExtensionSafe()); 323*03506bc0SCyndy Ishida IF->setOSLibNotForSharedCache(isOSLibNotForSharedCache()); 32416c1f436SCyndy Ishida for (const auto &It : umbrellas()) 32516c1f436SCyndy Ishida if (It.first.Arch == Arch) 32616c1f436SCyndy Ishida IF->addParentUmbrella(It.first, It.second); 32716c1f436SCyndy Ishida 32816c1f436SCyndy Ishida for (const auto &It : rpaths()) 32916c1f436SCyndy Ishida if (It.first.Arch == Arch) 330515d3f7dSCyndy Ishida IF->addRPath(It.second, It.first); 33116c1f436SCyndy Ishida 33216c1f436SCyndy Ishida for (const auto &Lib : allowableClients()) 33316c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 33416c1f436SCyndy Ishida if (Target.Arch == Arch) 33516c1f436SCyndy Ishida IF->addAllowableClient(Lib.getInstallName(), Target); 33616c1f436SCyndy Ishida 33716c1f436SCyndy Ishida for (const auto &Lib : reexportedLibraries()) 33816c1f436SCyndy Ishida for (const auto &Target : Lib.targets()) 33916c1f436SCyndy Ishida if (Target.Arch == Arch) 34016c1f436SCyndy Ishida IF->addReexportedLibrary(Lib.getInstallName(), Target); 34116c1f436SCyndy Ishida 34216c1f436SCyndy Ishida for (const auto *Sym : symbols()) { 34316c1f436SCyndy Ishida if (Sym->hasArchitecture(Arch)) 34416c1f436SCyndy Ishida IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Arch), 34516c1f436SCyndy Ishida Sym->getFlags()); 34616c1f436SCyndy Ishida } 34716c1f436SCyndy Ishida 34816c1f436SCyndy Ishida for (auto &Doc : Documents) { 34916c1f436SCyndy Ishida // Skip documents that don't have the requested architecture. 35016c1f436SCyndy Ishida if (!Doc->getArchitectures().has(Arch)) 35116c1f436SCyndy Ishida continue; 35216c1f436SCyndy Ishida 35316c1f436SCyndy Ishida auto Result = Doc->extract(Arch); 35416c1f436SCyndy Ishida if (!Result) 35516c1f436SCyndy Ishida return Result; 35616c1f436SCyndy Ishida 35716c1f436SCyndy Ishida IF->addDocument(std::move(Result.get())); 35816c1f436SCyndy Ishida } 35916c1f436SCyndy Ishida 36016c1f436SCyndy Ishida return std::move(IF); 36116c1f436SCyndy Ishida } 36216c1f436SCyndy Ishida 3633a080a01SCyndy Ishida void InterfaceFile::setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA, 3643a080a01SCyndy Ishida const Target &Targ) { 3653a080a01SCyndy Ishida if (getFileType() != BA.File) 3663a080a01SCyndy Ishida setFileType(BA.File); 3673a080a01SCyndy Ishida if (getInstallName().empty()) 3683a080a01SCyndy Ishida setInstallName(BA.InstallName); 3693a080a01SCyndy Ishida if (BA.AppExtensionSafe && !isApplicationExtensionSafe()) 3703a080a01SCyndy Ishida setApplicationExtensionSafe(); 3713a080a01SCyndy Ishida if (BA.TwoLevelNamespace && !isTwoLevelNamespace()) 3723a080a01SCyndy Ishida setTwoLevelNamespace(); 3733a080a01SCyndy Ishida if (BA.OSLibNotForSharedCache && !isOSLibNotForSharedCache()) 3743a080a01SCyndy Ishida setOSLibNotForSharedCache(); 3753a080a01SCyndy Ishida if (getCurrentVersion().empty()) 3763a080a01SCyndy Ishida setCurrentVersion(BA.CurrentVersion); 3773a080a01SCyndy Ishida if (getCompatibilityVersion().empty()) 3783a080a01SCyndy Ishida setCompatibilityVersion(BA.CompatVersion); 3793a080a01SCyndy Ishida if (getSwiftABIVersion() == 0) 3803a080a01SCyndy Ishida setSwiftABIVersion(BA.SwiftABI); 3813a080a01SCyndy Ishida if (getPath().empty()) 3823a080a01SCyndy Ishida setPath(BA.Path); 3833a080a01SCyndy Ishida if (!BA.ParentUmbrella.empty()) 3843a080a01SCyndy Ishida addParentUmbrella(Targ, BA.ParentUmbrella); 3853a080a01SCyndy Ishida for (const auto &Client : BA.AllowableClients) 3863a080a01SCyndy Ishida addAllowableClient(Client, Targ); 3873a080a01SCyndy Ishida for (const auto &Lib : BA.RexportedLibraries) 3883a080a01SCyndy Ishida addReexportedLibrary(Lib, Targ); 3893a080a01SCyndy Ishida } 3903a080a01SCyndy Ishida 391bc85cf16SCyndy Ishida static bool isYAMLTextStub(const FileType &Kind) { 392bc85cf16SCyndy Ishida return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5); 393bc85cf16SCyndy Ishida } 394bc85cf16SCyndy Ishida 3950116d04dSCyndy Ishida bool InterfaceFile::operator==(const InterfaceFile &O) const { 3960116d04dSCyndy Ishida if (Targets != O.Targets) 3970116d04dSCyndy Ishida return false; 3980116d04dSCyndy Ishida if (InstallName != O.InstallName) 3990116d04dSCyndy Ishida return false; 4000116d04dSCyndy Ishida if ((CurrentVersion != O.CurrentVersion) || 4010116d04dSCyndy Ishida (CompatibilityVersion != O.CompatibilityVersion)) 4020116d04dSCyndy Ishida return false; 4030116d04dSCyndy Ishida if (SwiftABIVersion != O.SwiftABIVersion) 4040116d04dSCyndy Ishida return false; 4050116d04dSCyndy Ishida if (IsTwoLevelNamespace != O.IsTwoLevelNamespace) 4060116d04dSCyndy Ishida return false; 4070116d04dSCyndy Ishida if (IsAppExtensionSafe != O.IsAppExtensionSafe) 4080116d04dSCyndy Ishida return false; 409e17efa60SCyndy Ishida if (IsOSLibNotForSharedCache != O.IsOSLibNotForSharedCache) 410e17efa60SCyndy Ishida return false; 411913f21aeSCyndy Ishida if (HasSimSupport != O.HasSimSupport) 412913f21aeSCyndy Ishida return false; 4130116d04dSCyndy Ishida if (ParentUmbrellas != O.ParentUmbrellas) 4140116d04dSCyndy Ishida return false; 4150116d04dSCyndy Ishida if (AllowableClients != O.AllowableClients) 4160116d04dSCyndy Ishida return false; 4170116d04dSCyndy Ishida if (ReexportedLibraries != O.ReexportedLibraries) 4180116d04dSCyndy Ishida return false; 4190882c70dSCyndy Ishida if (*SymbolsSet != *O.SymbolsSet) 4200116d04dSCyndy Ishida return false; 421bc85cf16SCyndy Ishida // Don't compare run search paths for older filetypes that cannot express 422bc85cf16SCyndy Ishida // them. 423bc85cf16SCyndy Ishida if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) { 424bc85cf16SCyndy Ishida if (RPaths != O.RPaths) 425bc85cf16SCyndy Ishida return false; 4267de8cd61SCyndy Ishida if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets)) 4277de8cd61SCyndy Ishida return false; 428bc85cf16SCyndy Ishida } 429bc85cf16SCyndy Ishida 4300116d04dSCyndy Ishida if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(), 4310116d04dSCyndy Ishida O.Documents.end(), 4320116d04dSCyndy Ishida [](const std::shared_ptr<InterfaceFile> LHS, 4330116d04dSCyndy Ishida const std::shared_ptr<InterfaceFile> RHS) { 4340116d04dSCyndy Ishida return *LHS == *RHS; 4350116d04dSCyndy Ishida })) 4360116d04dSCyndy Ishida return false; 4370116d04dSCyndy Ishida return true; 4380116d04dSCyndy Ishida } 439