1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
//===- llvm/TextAPI/SymbolSet.h - TAPI Symbol Set --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TEXTAPI_SYMBOLSET_H
#define LLVM_TEXTAPI_SYMBOLSET_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/TextAPI/Architecture.h"
#include "llvm/TextAPI/ArchitectureSet.h"
#include "llvm/TextAPI/Symbol.h"
#include <stddef.h>
namespace llvm {
struct SymbolsMapKey {
MachO::EncodeKind Kind;
StringRef Name;
SymbolsMapKey(MachO::EncodeKind Kind, StringRef Name)
: Kind(Kind), Name(Name) {}
};
template <> struct DenseMapInfo<SymbolsMapKey> {
static inline SymbolsMapKey getEmptyKey() {
return SymbolsMapKey(MachO::EncodeKind::GlobalSymbol, StringRef{});
}
static inline SymbolsMapKey getTombstoneKey() {
return SymbolsMapKey(MachO::EncodeKind::ObjectiveCInstanceVariable,
StringRef{});
}
static unsigned getHashValue(const SymbolsMapKey &Key) {
return hash_combine(hash_value(Key.Kind), hash_value(Key.Name));
}
static bool isEqual(const SymbolsMapKey &LHS, const SymbolsMapKey &RHS) {
return std::tie(LHS.Kind, LHS.Name) == std::tie(RHS.Kind, RHS.Name);
}
};
template <typename DerivedT, typename KeyInfoT, typename BucketT>
bool operator==(const DenseMapBase<DerivedT, SymbolsMapKey, MachO::Symbol *,
KeyInfoT, BucketT> &LHS,
const DenseMapBase<DerivedT, SymbolsMapKey, MachO::Symbol *,
KeyInfoT, BucketT> &RHS) {
if (LHS.size() != RHS.size())
return false;
for (const auto &KV : LHS) {
auto I = RHS.find(KV.first);
if (I == RHS.end() || *I->second != *KV.second)
return false;
}
return true;
}
template <typename DerivedT, typename KeyInfoT, typename BucketT>
bool operator!=(const DenseMapBase<DerivedT, SymbolsMapKey, MachO::Symbol *,
KeyInfoT, BucketT> &LHS,
const DenseMapBase<DerivedT, SymbolsMapKey, MachO::Symbol *,
KeyInfoT, BucketT> &RHS) {
return !(LHS == RHS);
}
namespace MachO {
class SymbolSet {
private:
llvm::BumpPtrAllocator Allocator;
StringRef copyString(StringRef String) {
if (String.empty())
return {};
void *Ptr = Allocator.Allocate(String.size(), 1);
memcpy(Ptr, String.data(), String.size());
return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
}
using SymbolsMapType = llvm::DenseMap<SymbolsMapKey, Symbol *>;
SymbolsMapType Symbols;
LLVM_ABI Symbol *addGlobalImpl(EncodeKind, StringRef Name, SymbolFlags Flags);
public:
SymbolSet() = default;
LLVM_ABI Symbol *addGlobal(EncodeKind Kind, StringRef Name, SymbolFlags Flags,
const Target &Targ);
size_t size() const { return Symbols.size(); }
template <typename RangeT, typename ElT = std::remove_reference_t<
decltype(*std::begin(std::declval<RangeT>()))>>
Symbol *addGlobal(EncodeKind Kind, StringRef Name, SymbolFlags Flags,
RangeT &&Targets) {
auto *Global = addGlobalImpl(Kind, Name, Flags);
for (const auto &Targ : Targets)
Global->addTarget(Targ);
if (Kind == EncodeKind::ObjectiveCClassEHType)
addGlobal(EncodeKind::ObjectiveCClass, Name, Flags, Targets);
return Global;
}
LLVM_ABI const Symbol *
findSymbol(EncodeKind Kind, StringRef Name,
ObjCIFSymbolKind ObjCIF = ObjCIFSymbolKind::None) const;
struct const_symbol_iterator
: public iterator_adaptor_base<
const_symbol_iterator, SymbolsMapType::const_iterator,
std::forward_iterator_tag, const Symbol *, ptrdiff_t,
const Symbol *, const Symbol *> {
const_symbol_iterator() = default;
template <typename U>
const_symbol_iterator(U &&u)
: iterator_adaptor_base(std::forward<U &&>(u)) {}
reference operator*() const { return I->second; }
pointer operator->() const { return I->second; }
};
using const_symbol_range = iterator_range<const_symbol_iterator>;
using const_filtered_symbol_iterator =
filter_iterator<const_symbol_iterator,
std::function<bool(const Symbol *)>>;
using const_filtered_symbol_range =
iterator_range<const_filtered_symbol_iterator>;
// Range that contains all symbols.
const_symbol_range symbols() const {
return {Symbols.begin(), Symbols.end()};
}
// Range that contains all defined and exported symbols.
const_filtered_symbol_range exports() const {
std::function<bool(const Symbol *)> fn = [](const Symbol *Symbol) {
return !Symbol->isUndefined() && !Symbol->isReexported();
};
return make_filter_range(
make_range<const_symbol_iterator>({Symbols.begin()}, {Symbols.end()}),
fn);
}
// Range that contains all reexported symbols.
const_filtered_symbol_range reexports() const {
std::function<bool(const Symbol *)> fn = [](const Symbol *Symbol) {
return Symbol->isReexported();
};
return make_filter_range(
make_range<const_symbol_iterator>({Symbols.begin()}, {Symbols.end()}),
fn);
}
// Range that contains all undefined and exported symbols.
const_filtered_symbol_range undefineds() const {
std::function<bool(const Symbol *)> fn = [](const Symbol *Symbol) {
return Symbol->isUndefined();
};
return make_filter_range(
make_range<const_symbol_iterator>({Symbols.begin()}, {Symbols.end()}),
fn);
}
LLVM_ABI bool operator==(const SymbolSet &O) const;
bool operator!=(const SymbolSet &O) const { return !(Symbols == O.Symbols); }
void *allocate(size_t Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
};
} // namespace MachO
} // namespace llvm
#endif // LLVM_TEXTAPI_SYMBOLSET_H
|