1351278Sdim//===- InterfaceFile.cpp --------------------------------------------------===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim// 9351278Sdim// Implements the Interface File. 10351278Sdim// 11351278Sdim//===----------------------------------------------------------------------===// 12351278Sdim 13351278Sdim#include "llvm/TextAPI/MachO/InterfaceFile.h" 14351278Sdim#include <iomanip> 15351278Sdim#include <sstream> 16351278Sdim 17351278Sdimnamespace llvm { 18351278Sdimnamespace MachO { 19351278Sdimnamespace detail { 20351278Sdimtemplate <typename C> 21351278Sdimtypename C::iterator addEntry(C &Container, StringRef InstallName) { 22351278Sdim auto I = partition_point(Container, [=](const InterfaceFileRef &O) { 23351278Sdim return O.getInstallName() < InstallName; 24351278Sdim }); 25351278Sdim if (I != Container.end() && I->getInstallName() == InstallName) 26351278Sdim return I; 27351278Sdim 28351278Sdim return Container.emplace(I, InstallName); 29351278Sdim} 30360784Sdim 31360784Sdimtemplate <typename C> 32360784Sdimtypename C::iterator addEntry(C &Container, const Target &Target_) { 33360784Sdim auto Iter = 34360784Sdim lower_bound(Container, Target_, [](const Target &LHS, const Target &RHS) { 35360784Sdim return LHS < RHS; 36360784Sdim }); 37360784Sdim if ((Iter != std::end(Container)) && !(Target_ < *Iter)) 38360784Sdim return Iter; 39360784Sdim 40360784Sdim return Container.insert(Iter, Target_); 41360784Sdim} 42351278Sdim} // end namespace detail. 43351278Sdim 44360784Sdimvoid InterfaceFileRef::addTarget(const Target &Target) { 45360784Sdim detail::addEntry(Targets, Target); 46351278Sdim} 47351278Sdim 48360784Sdimvoid InterfaceFile::addAllowableClient(StringRef InstallName, 49360784Sdim const Target &Target) { 50360784Sdim auto Client = detail::addEntry(AllowableClients, InstallName); 51360784Sdim Client->addTarget(Target); 52360784Sdim} 53360784Sdim 54351278Sdimvoid InterfaceFile::addReexportedLibrary(StringRef InstallName, 55360784Sdim const Target &Target) { 56351278Sdim auto Lib = detail::addEntry(ReexportedLibraries, InstallName); 57360784Sdim Lib->addTarget(Target); 58351278Sdim} 59351278Sdim 60360784Sdimvoid InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 61360784Sdim auto Iter = lower_bound(ParentUmbrellas, Target_, 62360784Sdim [](const std::pair<Target, std::string> &LHS, 63360784Sdim Target RHS) { return LHS.first < RHS; }); 64351278Sdim 65360784Sdim if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 66360784Sdim Iter->second = Parent; 67351278Sdim return; 68351278Sdim } 69351278Sdim 70360784Sdim ParentUmbrellas.emplace(Iter, Target_, Parent); 71351278Sdim return; 72351278Sdim} 73351278Sdim 74360784Sdimvoid InterfaceFile::addUUID(const Target &Target_, StringRef UUID) { 75360784Sdim auto Iter = lower_bound(UUIDs, Target_, 76360784Sdim [](const std::pair<Target, std::string> &LHS, 77360784Sdim Target RHS) { return LHS.first < RHS; }); 78360784Sdim 79360784Sdim if ((Iter != UUIDs.end()) && !(Target_ < Iter->first)) { 80360784Sdim Iter->second = UUID; 81360784Sdim return; 82360784Sdim } 83360784Sdim 84360784Sdim UUIDs.emplace(Iter, Target_, UUID); 85360784Sdim return; 86360784Sdim} 87360784Sdim 88360784Sdimvoid InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) { 89351278Sdim std::stringstream Stream; 90351278Sdim for (unsigned i = 0; i < 16; ++i) { 91351278Sdim if (i == 4 || i == 6 || i == 8 || i == 10) 92351278Sdim Stream << '-'; 93351278Sdim Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex 94351278Sdim << static_cast<int>(UUID[i]); 95351278Sdim } 96360784Sdim addUUID(Target, Stream.str()); 97351278Sdim} 98351278Sdim 99360784Sdimvoid InterfaceFile::addTarget(const Target &Target) { 100360784Sdim detail::addEntry(Targets, Target); 101360784Sdim} 102360784Sdim 103360784SdimInterfaceFile::const_filtered_target_range 104360784SdimInterfaceFile::targets(ArchitectureSet Archs) const { 105360784Sdim std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 106360784Sdim return Archs.has(Target_.Arch); 107360784Sdim }; 108360784Sdim return make_filter_range(Targets, fn); 109360784Sdim} 110360784Sdim 111351278Sdimvoid InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name, 112360784Sdim const TargetList &Targets, SymbolFlags Flags) { 113351278Sdim Name = copyString(Name); 114351278Sdim auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr); 115351278Sdim if (result.second) 116360784Sdim result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags}; 117351278Sdim else 118360784Sdim for (const auto &Target : Targets) 119360784Sdim result.first->second->addTarget(Target); 120351278Sdim} 121351278Sdim 122351278Sdim} // end namespace MachO. 123351278Sdim} // end namespace llvm. 124