blob: 9f084560d5fe41d88153aa680fbfdec926bf32d2 [file] [log] [blame]
Juergen Ributzka32cb5942019-03-22 22:46:52 +00001//===- 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
Juergen Ributzka32cb5942019-03-22 22:46:52 +000017namespace llvm {
18namespace MachO {
19namespace detail {
20template <typename C>
21typename C::iterator addEntry(C &Container, StringRef InstallName) {
Fangrui Song78ee2fb2019-06-30 11:19:56 +000022 auto I = partition_point(Container, [=](const InterfaceFileRef &O) {
23 return O.getInstallName() < InstallName;
Fangrui Songdc8de602019-06-21 05:40:31 +000024 });
Fangrui Song78ee2fb2019-06-30 11:19:56 +000025 if (I != Container.end() && I->getInstallName() == InstallName)
Juergen Ributzka32cb5942019-03-22 22:46:52 +000026 return I;
27
28 return Container.emplace(I, InstallName);
29}
Cyndy Ishida81669d52019-09-20 14:32:34 +000030
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}
Juergen Ributzka32cb5942019-03-22 22:46:52 +000042} // end namespace detail.
43
Cyndy Ishida81669d52019-09-20 14:32:34 +000044void 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);
Juergen Ributzka32cb5942019-03-22 22:46:52 +000052}
53
54void InterfaceFile::addReexportedLibrary(StringRef InstallName,
Cyndy Ishida81669d52019-09-20 14:32:34 +000055 const Target &Target) {
Juergen Ributzka32cb5942019-03-22 22:46:52 +000056 auto Lib = detail::addEntry(ReexportedLibraries, InstallName);
Cyndy Ishida81669d52019-09-20 14:32:34 +000057 Lib->addTarget(Target);
Juergen Ributzka32cb5942019-03-22 22:46:52 +000058}
59
Cyndy Ishida81669d52019-09-20 14:32:34 +000060void 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; });
Juergen Ributzka32cb5942019-03-22 22:46:52 +000064
Cyndy Ishida81669d52019-09-20 14:32:34 +000065 if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
Benjamin Krameradcd0262020-01-28 20:23:46 +010066 Iter->second = std::string(Parent);
Juergen Ributzka32cb5942019-03-22 22:46:52 +000067 return;
68 }
69
Cyndy Ishida81669d52019-09-20 14:32:34 +000070 ParentUmbrellas.emplace(Iter, Target_, Parent);
Juergen Ributzka32cb5942019-03-22 22:46:52 +000071 return;
72}
73
Cyndy Ishida81669d52019-09-20 14:32:34 +000074void 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)) {
Benjamin Krameradcd0262020-01-28 20:23:46 +010080 Iter->second = std::string(UUID);
Cyndy Ishida81669d52019-09-20 14:32:34 +000081 return;
82 }
83
84 UUIDs.emplace(Iter, Target_, UUID);
85 return;
86}
87
88void InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) {
Juergen Ributzka32cb5942019-03-22 22:46:52 +000089 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 }
Cyndy Ishida81669d52019-09-20 14:32:34 +000096 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);
Juergen Ributzka32cb5942019-03-22 22:46:52 +0000109}
110
111void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name,
Cyndy Ishida81669d52019-09-20 14:32:34 +0000112 const TargetList &Targets, SymbolFlags Flags) {
Juergen Ributzka32cb5942019-03-22 22:46:52 +0000113 Name = copyString(Name);
114 auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr);
115 if (result.second)
Cyndy Ishida81669d52019-09-20 14:32:34 +0000116 result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags};
Juergen Ributzka32cb5942019-03-22 22:46:52 +0000117 else
Cyndy Ishida81669d52019-09-20 14:32:34 +0000118 for (const auto &Target : Targets)
119 result.first->second->addTarget(Target);
Juergen Ributzka32cb5942019-03-22 22:46:52 +0000120}
121
122} // end namespace MachO.
123} // end namespace llvm.