LLVM 23.0.0git
SymbolLookupSet.h
Go to the documentation of this file.
1//===------ SymbolLookupSet.h - Symbol set for ORC lookups ------*- C++ -*-===//
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// SymbolLookupSet class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
14#define LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/STLExtras.h"
20#include "llvm/Support/Error.h"
21
22#include <initializer_list>
23#include <type_traits>
24#include <utility>
25#include <vector>
26
27namespace llvm::orc {
28
29/// Lookup flags that apply to each symbol in a lookup.
30///
31/// If RequiredSymbol is used (the default) for a given symbol then that symbol
32/// must be found during the lookup or the lookup will fail returning a
33/// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
34/// symbol is not found then the query will continue, and no result for the
35/// missing symbol will be present in the result (assuming the rest of the
36/// lookup succeeds).
38
39/// A set of symbols to look up, each associated with a SymbolLookupFlags
40/// value.
41///
42/// This class is backed by a vector and optimized for fast insertion,
43/// deletion and iteration. It does not guarantee a stable order between
44/// operations, and will not automatically detect duplicate elements (they
45/// can be manually checked by calling the validate method).
47public:
48 using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
49 using UnderlyingVector = std::vector<value_type>;
50 using iterator = UnderlyingVector::iterator;
51 using const_iterator = UnderlyingVector::const_iterator;
52
53 SymbolLookupSet() = default;
54
55 SymbolLookupSet(std::initializer_list<value_type> Elems) {
56 for (auto &E : Elems)
57 Symbols.push_back(std::move(E));
58 }
59
61 SymbolStringPtr Name,
63 add(std::move(Name), Flags);
64 }
65
66 /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
68 std::initializer_list<SymbolStringPtr> Names,
70 Symbols.reserve(Names.size());
71 for (const auto &Name : Names)
72 add(std::move(Name), Flags);
73 }
74
75 /// Construct a SymbolLookupSet from a SymbolNameSet with the given
76 /// Flags used for each value.
78 const SymbolNameSet &Names,
80 Symbols.reserve(Names.size());
81 for (const auto &Name : Names)
82 add(Name, Flags);
83 }
84
85 /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
86 /// used for each value.
87 /// If the ArrayRef contains duplicates it is up to the client to remove these
88 /// before using this instance for lookup.
92 Symbols.reserve(Names.size());
93 for (const auto &Name : Names)
94 add(Name, Flags);
95 }
96
97 /// Construct a SymbolLookupSet from DenseMap keys.
98 template <typename ValT>
99 static SymbolLookupSet
103 Result.Symbols.reserve(M.size());
104 for (const auto &[Name, Val] : M)
105 Result.add(Name, Flags);
106 return Result;
107 }
108
109 /// Add an element to the set. The client is responsible for checking that
110 /// duplicates are not added.
114 Symbols.push_back(std::make_pair(std::move(Name), Flags));
115 return *this;
116 }
117
118 /// Quickly append one lookup set to another.
120 Symbols.reserve(Symbols.size() + Other.size());
121 for (auto &KV : Other)
122 Symbols.push_back(std::move(KV));
123 return *this;
124 }
125
126 bool empty() const { return Symbols.empty(); }
127 UnderlyingVector::size_type size() const { return Symbols.size(); }
128 iterator begin() { return Symbols.begin(); }
129 iterator end() { return Symbols.end(); }
130 const_iterator begin() const { return Symbols.begin(); }
131 const_iterator end() const { return Symbols.end(); }
132
133 /// Removes the Ith element of the vector, replacing it with the last element.
134 void remove(UnderlyingVector::size_type I) {
135 std::swap(Symbols[I], Symbols.back());
136 Symbols.pop_back();
137 }
138
139 /// Removes the element pointed to by the given iterator. This iterator and
140 /// all subsequent ones (including end()) are invalidated.
141 void remove(iterator I) { remove(I - begin()); }
142
143 /// Removes all elements matching the given predicate, which must be callable
144 /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
145 template <typename PredFn> void remove_if(PredFn &&Pred) {
146 UnderlyingVector::size_type I = 0;
147 while (I != Symbols.size()) {
148 const auto &Name = Symbols[I].first;
149 auto Flags = Symbols[I].second;
150 if (Pred(Name, Flags))
151 remove(I);
152 else
153 ++I;
154 }
155 }
156
157 /// Loop over the elements of this SymbolLookupSet, applying the Body function
158 /// to each one. Body must be callable as
159 /// bool(const SymbolStringPtr &, SymbolLookupFlags).
160 /// If Body returns true then the element just passed in is removed from the
161 /// set. If Body returns false then the element is retained.
162 template <typename BodyFn>
163 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
164 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
165 std::declval<SymbolLookupFlags>())),
166 bool>::value> {
167 UnderlyingVector::size_type I = 0;
168 while (I != Symbols.size()) {
169 const auto &Name = Symbols[I].first;
170 auto Flags = Symbols[I].second;
171 if (Body(Name, Flags))
172 remove(I);
173 else
174 ++I;
175 }
176 }
177
178 /// Loop over the elements of this SymbolLookupSet, applying the Body function
179 /// to each one. Body must be callable as
180 /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
181 /// If Body returns a failure value, the loop exits immediately. If Body
182 /// returns true then the element just passed in is removed from the set. If
183 /// Body returns false then the element is retained.
184 template <typename BodyFn>
185 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
186 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
187 std::declval<SymbolLookupFlags>())),
188 Expected<bool>>::value,
189 Error> {
190 UnderlyingVector::size_type I = 0;
191 while (I != Symbols.size()) {
192 const auto &Name = Symbols[I].first;
193 auto Flags = Symbols[I].second;
194 auto Remove = Body(Name, Flags);
195 if (!Remove)
196 return Remove.takeError();
197 if (*Remove)
198 remove(I);
199 else
200 ++I;
201 }
202 return Error::success();
203 }
204
205 /// Construct a SymbolNameVector from this instance by dropping the Flags
206 /// values.
208 SymbolNameVector Names;
209 Names.reserve(Symbols.size());
210 for (const auto &KV : Symbols)
211 Names.push_back(KV.first);
212 return Names;
213 }
214
215 /// Sort the lookup set by pointer value. This sort is fast but sensitive to
216 /// allocation order and so should not be used where a consistent order is
217 /// required.
219
220 /// Sort the lookup set lexicographically. This sort is slow but the order
221 /// is unaffected by allocation order.
222 void sortByName() {
223 llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
224 return *LHS.first < *RHS.first;
225 });
226 }
227
228 /// Remove any duplicate elements. If a SymbolLookupSet is not duplicate-free
229 /// by construction, this method can be used to turn it into a proper set.
232 auto LastI = llvm::unique(Symbols);
233 Symbols.erase(LastI, Symbols.end());
234 }
235
236#ifndef NDEBUG
237 /// Returns true if this set contains any duplicates. This should only be used
238 /// in assertions.
240 if (Symbols.size() < 2)
241 return false;
243 for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
244 if (Symbols[I].first == Symbols[I - 1].first)
245 return true;
246 return false;
247 }
248#endif
249
250private:
251 UnderlyingVector Symbols;
252};
253
254} // namespace llvm::orc
255
256#endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some templates that are useful if you are working with the STL at all.
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
size_type size() const
Definition DenseSet.h:87
A set of symbols to look up, each associated with a SymbolLookupFlags value.
std::pair< SymbolStringPtr, SymbolLookupFlags > value_type
const_iterator begin() const
void removeDuplicates()
Remove any duplicate elements.
UnderlyingVector::const_iterator const_iterator
void sortByAddress()
Sort the lookup set by pointer value.
SymbolLookupSet(std::initializer_list< SymbolStringPtr > Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
UnderlyingVector::size_type size() const
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
static SymbolLookupSet fromMapKeys(const DenseMap< SymbolStringPtr, ValT > &M, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from DenseMap keys.
SymbolLookupSet & append(SymbolLookupSet Other)
Quickly append one lookup set to another.
SymbolLookupSet(ArrayRef< SymbolStringPtr > Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from a vector of symbols with the given Flags used for each value.
SymbolLookupSet(std::initializer_list< value_type > Elems)
void sortByName()
Sort the lookup set lexicographically.
void remove(iterator I)
Removes the element pointed to by the given iterator.
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< std::is_same< decltype(Body(std::declval< const SymbolStringPtr & >(), std::declval< SymbolLookupFlags >())), bool >::value >
Loop over the elements of this SymbolLookupSet, applying the Body function to each one.
bool containsDuplicates()
Returns true if this set contains any duplicates.
UnderlyingVector::iterator iterator
void remove_if(PredFn &&Pred)
Removes all elements matching the given predicate, which must be callable as bool(const SymbolStringP...
SymbolLookupSet(const SymbolNameSet &Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from a SymbolNameSet with the given Flags used for each value.
SymbolLookupSet(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
SymbolNameVector getSymbolNames() const
Construct a SymbolNameVector from this instance by dropping the Flags values.
const_iterator end() const
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< std::is_same< decltype(Body(std::declval< const SymbolStringPtr & >(), std::declval< SymbolLookupFlags >())), Expected< bool > >::value, Error >
Loop over the elements of this SymbolLookupSet, applying the Body function to each one.
void remove(UnderlyingVector::size_type I)
Removes the Ith element of the vector, replacing it with the last element.
std::vector< value_type > UnderlyingVector
Pointer to a pooled string representing a symbol name.
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2133
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1635
@ Other
Any other memory.
Definition ModRef.h:68
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:863
Function object to check whether the first component of a container supported by std::get (like std::...
Definition STLExtras.h:1438