InterfaceFile.cpp revision 360784
1//===- InterfaceFile.cpp --------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// Implements the Interface File. 10// 11//===----------------------------------------------------------------------===// 12 13#include "llvm/TextAPI/MachO/InterfaceFile.h" 14#include <iomanip> 15#include <sstream> 16 17namespace llvm { 18namespace MachO { 19namespace detail { 20template <typename C> 21typename C::iterator addEntry(C &Container, StringRef InstallName) { 22 auto I = partition_point(Container, [=](const InterfaceFileRef &O) { 23 return O.getInstallName() < InstallName; 24 }); 25 if (I != Container.end() && I->getInstallName() == InstallName) 26 return I; 27 28 return Container.emplace(I, InstallName); 29} 30 31template <typename C> 32typename C::iterator addEntry(C &Container, const Target &Target_) { 33 auto Iter = 34 lower_bound(Container, Target_, [](const Target &LHS, const Target &RHS) { 35 return LHS < RHS; 36 }); 37 if ((Iter != std::end(Container)) && !(Target_ < *Iter)) 38 return Iter; 39 40 return Container.insert(Iter, Target_); 41} 42} // end namespace detail. 43 44void InterfaceFileRef::addTarget(const Target &Target) { 45 detail::addEntry(Targets, Target); 46} 47 48void InterfaceFile::addAllowableClient(StringRef InstallName, 49 const Target &Target) { 50 auto Client = detail::addEntry(AllowableClients, InstallName); 51 Client->addTarget(Target); 52} 53 54void InterfaceFile::addReexportedLibrary(StringRef InstallName, 55 const Target &Target) { 56 auto Lib = detail::addEntry(ReexportedLibraries, InstallName); 57 Lib->addTarget(Target); 58} 59 60void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 61 auto Iter = lower_bound(ParentUmbrellas, Target_, 62 [](const std::pair<Target, std::string> &LHS, 63 Target RHS) { return LHS.first < RHS; }); 64 65 if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 66 Iter->second = Parent; 67 return; 68 } 69 70 ParentUmbrellas.emplace(Iter, Target_, Parent); 71 return; 72} 73 74void InterfaceFile::addUUID(const Target &Target_, StringRef UUID) { 75 auto Iter = lower_bound(UUIDs, Target_, 76 [](const std::pair<Target, std::string> &LHS, 77 Target RHS) { return LHS.first < RHS; }); 78 79 if ((Iter != UUIDs.end()) && !(Target_ < Iter->first)) { 80 Iter->second = UUID; 81 return; 82 } 83 84 UUIDs.emplace(Iter, Target_, UUID); 85 return; 86} 87 88void InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) { 89 std::stringstream Stream; 90 for (unsigned i = 0; i < 16; ++i) { 91 if (i == 4 || i == 6 || i == 8 || i == 10) 92 Stream << '-'; 93 Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex 94 << static_cast<int>(UUID[i]); 95 } 96 addUUID(Target, Stream.str()); 97} 98 99void InterfaceFile::addTarget(const Target &Target) { 100 detail::addEntry(Targets, Target); 101} 102 103InterfaceFile::const_filtered_target_range 104InterfaceFile::targets(ArchitectureSet Archs) const { 105 std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 106 return Archs.has(Target_.Arch); 107 }; 108 return make_filter_range(Targets, fn); 109} 110 111void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name, 112 const TargetList &Targets, SymbolFlags Flags) { 113 Name = copyString(Name); 114 auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr); 115 if (result.second) 116 result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags}; 117 else 118 for (const auto &Target : Targets) 119 result.first->second->addTarget(Target); 120} 121 122} // end namespace MachO. 123} // end namespace llvm. 124