aboutsummaryrefslogtreecommitdiff
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/ADT/IndexedMap.h36
-rw-r--r--llvm/include/llvm/ADT/RadixTree.h351
-rw-r--r--llvm/include/llvm/ADT/STLForwardCompat.h2
-rw-r--r--llvm/include/llvm/ADT/SparseMultiSet.h2
-rw-r--r--llvm/include/llvm/ADT/SparseSet.h20
-rw-r--r--llvm/include/llvm/CodeGen/Passes.h8
-rw-r--r--llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h2
-rw-r--r--llvm/include/llvm/DebugInfo/GSYM/GsymContext.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h6
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h4
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h28
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h12
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h2
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h2
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Core.h2
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h2
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h173
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h514
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h474
-rw-r--r--llvm/include/llvm/Support/SpecialCaseList.h7
28 files changed, 425 insertions, 1240 deletions
diff --git a/llvm/include/llvm/ADT/IndexedMap.h b/llvm/include/llvm/ADT/IndexedMap.h
index 55935a7..02193c7 100644
--- a/llvm/include/llvm/ADT/IndexedMap.h
+++ b/llvm/include/llvm/ADT/IndexedMap.h
@@ -43,40 +43,40 @@ class IndexedMap {
// is trivially copyable.
using StorageT = SmallVector<T, 0>;
- StorageT storage_;
- T nullVal_ = T();
- ToIndexT toIndex_;
+ StorageT Storage;
+ T NullVal = T();
+ ToIndexT ToIndex;
public:
IndexedMap() = default;
- explicit IndexedMap(const T &val) : nullVal_(val) {}
+ explicit IndexedMap(const T &Val) : NullVal(Val) {}
- typename StorageT::reference operator[](IndexT n) {
- assert(toIndex_(n) < storage_.size() && "index out of bounds!");
- return storage_[toIndex_(n)];
+ typename StorageT::reference operator[](IndexT N) {
+ assert(ToIndex(N) < Storage.size() && "index out of bounds!");
+ return Storage[ToIndex(N)];
}
- typename StorageT::const_reference operator[](IndexT n) const {
- assert(toIndex_(n) < storage_.size() && "index out of bounds!");
- return storage_[toIndex_(n)];
+ typename StorageT::const_reference operator[](IndexT N) const {
+ assert(ToIndex(N) < Storage.size() && "index out of bounds!");
+ return Storage[ToIndex(N)];
}
- void reserve(typename StorageT::size_type s) { storage_.reserve(s); }
+ void reserve(typename StorageT::size_type S) { Storage.reserve(S); }
- void resize(typename StorageT::size_type s) { storage_.resize(s, nullVal_); }
+ void resize(typename StorageT::size_type S) { Storage.resize(S, NullVal); }
- void clear() { storage_.clear(); }
+ void clear() { Storage.clear(); }
- void grow(IndexT n) {
- unsigned NewSize = toIndex_(n) + 1;
- if (NewSize > storage_.size())
+ void grow(IndexT N) {
+ unsigned NewSize = ToIndex(N) + 1;
+ if (NewSize > Storage.size())
resize(NewSize);
}
- bool inBounds(IndexT n) const { return toIndex_(n) < storage_.size(); }
+ bool inBounds(IndexT N) const { return ToIndex(N) < Storage.size(); }
- typename StorageT::size_type size() const { return storage_.size(); }
+ typename StorageT::size_type size() const { return Storage.size(); }
};
} // namespace llvm
diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
new file mode 100644
index 0000000..a65acdd
--- /dev/null
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -0,0 +1,351 @@
+//===-- llvm/ADT/RadixTree.h - Radix Tree implementation --------*- 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
+//===----------------------------------------------------------------------===//
+//
+// This file implements a Radix Tree.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_RADIXTREE_H
+#define LLVM_ADT_RADIXTREE_H
+
+#include "llvm/ADT/ADL.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+/// \brief A Radix Tree implementation.
+///
+/// A Radix Tree (also known as a compact prefix tree or radix trie) is a
+/// data structure that stores a dynamic set or associative array where keys
+/// are strings and values are associated with these keys. Unlike a regular
+/// trie, the edges of a radix tree can be labeled with sequences of characters
+/// as well as single characters. This makes radix trees more efficient for
+/// storing sparse data sets, where many nodes in a regular trie would have
+/// only one child.
+///
+/// This implementation supports arbitrary key types that can be iterated over
+/// (e.g., `std::string`, `std::vector<char>`, `ArrayRef<char>`). The key type
+/// must provide `begin()` and `end()` for iteration.
+///
+/// The tree stores `std::pair<const KeyType, T>` as its value type.
+///
+/// Example usage:
+/// \code
+/// llvm::RadixTree<StringRef, int> Tree;
+/// Tree.emplace("apple", 1);
+/// Tree.emplace("grapefruit", 2);
+/// Tree.emplace("grape", 3);
+///
+/// // Find prefixes
+/// for (const auto &[Key, Value] : Tree.find_prefixes("grapefruit juice")) {
+/// // pair will be {"grape", 3}
+/// // pair will be {"grapefruit", 2}
+/// llvm::outs() << Key << ": " << Value << "\n";
+/// }
+///
+/// // Iterate over all elements
+/// for (const auto &[Key, Value] : Tree)
+/// llvm::outs() << Key << ": " << Value << "\n";
+/// \endcode
+///
+/// \note
+/// The `RadixTree` takes ownership of the `KeyType` and `T` objects
+/// inserted into it. When an element is removed or the tree is destroyed,
+/// these objects will be destructed.
+/// However, if `KeyType` is a reference-like type, e.g., StringRef or range,
+/// the user must guarantee that the referenced data has a lifetime longer than
+/// the tree.
+template <typename KeyType, typename T> class RadixTree {
+public:
+ using key_type = KeyType;
+ using mapped_type = T;
+ using value_type = std::pair<const KeyType, mapped_type>;
+
+private:
+ using KeyConstIteratorType =
+ decltype(adl_begin(std::declval<const key_type &>()));
+ using KeyConstIteratorRangeType = iterator_range<KeyConstIteratorType>;
+ using KeyValueType =
+ remove_cvref_t<decltype(*adl_begin(std::declval<key_type &>()))>;
+ using ContainerType = std::list<value_type>;
+
+ /// Represents an internal node in the Radix Tree.
+ struct Node {
+ KeyConstIteratorRangeType Key{KeyConstIteratorType{},
+ KeyConstIteratorType{}};
+ std::vector<Node> Children;
+
+ /// An iterator to the value associated with this node.
+ ///
+ /// If this node does not have a value (i.e., it's an internal node that
+ /// only serves as a path to other values), this iterator will be equal
+ /// to default constructed `ContainerType::iterator()`.
+ typename ContainerType::iterator Value;
+
+ /// The first character of the Key. Used for fast child lookup.
+ KeyValueType KeyFront;
+
+ Node() = default;
+ Node(const KeyConstIteratorRangeType &Key)
+ : Key(Key), KeyFront(*Key.begin()) {
+ assert(!Key.empty());
+ }
+
+ Node(Node &&) = default;
+ Node &operator=(Node &&) = default;
+
+ Node(const Node &) = delete;
+ Node &operator=(const Node &) = delete;
+
+ const Node *findChild(const KeyConstIteratorRangeType &Key) const {
+ if (Key.empty())
+ return nullptr;
+ for (const Node &Child : Children) {
+ assert(!Child.Key.empty()); // Only root can be empty.
+ if (Child.KeyFront == *Key.begin())
+ return &Child;
+ }
+ return nullptr;
+ }
+
+ Node *findChild(const KeyConstIteratorRangeType &Query) {
+ const Node *This = this;
+ return const_cast<Node *>(This->findChild(Query));
+ }
+
+ size_t countNodes() const {
+ size_t R = 1;
+ for (const Node &C : Children)
+ R += C.countNodes();
+ return R;
+ }
+
+ ///
+ /// Splits the current node into two.
+ ///
+ /// This function is used when a new key needs to be inserted that shares
+ /// a common prefix with the current node's key, but then diverges.
+ /// The current `Key` is truncated to the common prefix, and a new child
+ /// node is created for the remainder of the original node's `Key`.
+ ///
+ /// \param SplitPoint An iterator pointing to the character in the current
+ /// `Key` where the split should occur.
+ void split(KeyConstIteratorType SplitPoint) {
+ Node Child(make_range(SplitPoint, Key.end()));
+ Key = make_range(Key.begin(), SplitPoint);
+
+ Children.swap(Child.Children);
+ std::swap(Value, Child.Value);
+
+ Children.emplace_back(std::move(Child));
+ }
+ };
+
+ /// Root always corresponds to the empty key, which is the shortest possible
+ /// prefix for everything.
+ Node Root;
+ ContainerType KeyValuePairs;
+
+ /// Finds or creates a new tail or leaf node corresponding to the `Key`.
+ Node &findOrCreate(KeyConstIteratorRangeType Key) {
+ Node *Curr = &Root;
+ if (Key.empty())
+ return *Curr;
+
+ for (;;) {
+ auto [I1, I2] = llvm::mismatch(Key, Curr->Key);
+ Key = make_range(I1, Key.end());
+
+ if (I2 != Curr->Key.end()) {
+ // Match is partial. Either query is too short, or there is mismatching
+ // character. Split either way, and put new node in between of the
+ // current and its children.
+ Curr->split(I2);
+
+ // Split was caused by mismatch, so `findChild` would fail.
+ break;
+ }
+
+ Node *Child = Curr->findChild(Key);
+ if (!Child)
+ break;
+
+ // Move to child with the same first character.
+ Curr = Child;
+ }
+
+ if (Key.empty()) {
+ // The current node completely matches the key, return it.
+ return *Curr;
+ }
+
+ // `Key` is a suffix of original `Key` unmatched by path from the `Root` to
+ // the `Curr`, and we have no candidate in the children to match more.
+ // Create a new one.
+ return Curr->Children.emplace_back(Key);
+ }
+
+ ///
+ /// An iterator for traversing prefixes search results.
+ ///
+ /// This iterator is used by `find_prefixes` to traverse the tree and find
+ /// elements that are prefixes to the given key. It's a forward iterator.
+ ///
+ /// \tparam MappedType The type of the value pointed to by the iterator.
+ /// This will be `value_type` for non-const iterators
+ /// and `const value_type` for const iterators.
+ template <typename MappedType>
+ class IteratorImpl
+ : public iterator_facade_base<IteratorImpl<MappedType>,
+ std::forward_iterator_tag, MappedType> {
+ const Node *Curr = nullptr;
+ KeyConstIteratorRangeType Query{KeyConstIteratorType{},
+ KeyConstIteratorType{}};
+
+ void findNextValid() {
+ while (Curr && Curr->Value == typename ContainerType::iterator())
+ advance();
+ }
+
+ void advance() {
+ assert(Curr);
+ if (Query.empty()) {
+ Curr = nullptr;
+ return;
+ }
+
+ Curr = Curr->findChild(Query);
+ if (!Curr) {
+ Curr = nullptr;
+ return;
+ }
+
+ auto [I1, I2] = llvm::mismatch(Query, Curr->Key);
+ if (I2 != Curr->Key.end()) {
+ Curr = nullptr;
+ return;
+ }
+ Query = make_range(I1, Query.end());
+ }
+
+ friend class RadixTree;
+ IteratorImpl(const Node *C, const KeyConstIteratorRangeType &Q)
+ : Curr(C), Query(Q) {
+ findNextValid();
+ }
+
+ public:
+ IteratorImpl() = default;
+
+ MappedType &operator*() const { return *Curr->Value; }
+
+ IteratorImpl &operator++() {
+ advance();
+ findNextValid();
+ return *this;
+ }
+
+ bool operator==(const IteratorImpl &Other) const {
+ return Curr == Other.Curr;
+ }
+ };
+
+public:
+ RadixTree() = default;
+ RadixTree(RadixTree &&) = default;
+ RadixTree &operator=(RadixTree &&) = default;
+
+ using prefix_iterator = IteratorImpl<value_type>;
+ using const_prefix_iterator = IteratorImpl<const value_type>;
+
+ using iterator = typename ContainerType::iterator;
+ using const_iterator = typename ContainerType::const_iterator;
+
+ /// Returns true if the tree is empty.
+ bool empty() const { return KeyValuePairs.empty(); }
+
+ /// Returns the number of elements in the tree.
+ size_t size() const { return KeyValuePairs.size(); }
+
+ /// Returns the number of nodes in the tree.
+ ///
+ /// This function counts all internal nodes in the tree. It can be useful for
+ /// understanding the memory footprint or complexity of the tree structure.
+ size_t countNodes() const { return Root.countNodes(); }
+
+ /// Returns an iterator to the first element.
+ iterator begin() { return KeyValuePairs.begin(); }
+ const_iterator begin() const { return KeyValuePairs.begin(); }
+
+ /// Returns an iterator to the end of the tree.
+ iterator end() { return KeyValuePairs.end(); }
+ const_iterator end() const { return KeyValuePairs.end(); }
+
+ /// Constructs and inserts a new element into the tree.
+ ///
+ /// This function constructs an element in place within the tree. If an
+ /// element with the same key already exists, the insertion fails and the
+ /// function returns an iterator to the existing element along with `false`.
+ /// Otherwise, the new element is inserted and the function returns an
+ /// iterator to the new element along with `true`.
+ ///
+ /// \param Key The key of the element to construct.
+ /// \param Args Arguments to forward to the constructor of the mapped_type.
+ /// \return A pair consisting of an iterator to the inserted element (or to
+ /// the element that prevented insertion) and a boolean value
+ /// indicating whether the insertion took place.
+ template <typename... Ts>
+ std::pair<iterator, bool> emplace(key_type &&Key, Ts &&...Args) {
+ // We want to make new `Node` to refer key in the container, not the one
+ // from the argument.
+ // FIXME: Determine that we need a new node, before expanding
+ // `KeyValuePairs`.
+ const value_type &NewValue = KeyValuePairs.emplace_front(
+ std::move(Key), T(std::forward<Ts>(Args)...));
+ Node &Node = findOrCreate(NewValue.first);
+ bool HasValue = Node.Value != typename ContainerType::iterator();
+ if (!HasValue)
+ Node.Value = KeyValuePairs.begin();
+ else
+ KeyValuePairs.pop_front();
+ return {Node.Value, !HasValue};
+ }
+
+ ///
+ /// Finds all elements whose keys are prefixes of the given `Key`.
+ ///
+ /// This function returns an iterator range over all elements in the tree
+ /// whose keys are prefixes of the provided `Key`. For example, if the tree
+ /// contains "abcde", "abc", "abcdefgh", and `Key` is "abcde", this function
+ /// would return iterators to "abcde" and "abc".
+ ///
+ /// \param Key The key to search for prefixes of.
+ /// \return An `iterator_range` of `const_prefix_iterator`s, allowing
+ /// iteration over the found prefix elements.
+ /// \note The returned iterators reference the `Key` provided by the caller.
+ /// The caller must ensure that `Key` remains valid for the lifetime
+ /// of the iterators.
+ iterator_range<const_prefix_iterator>
+ find_prefixes(const key_type &Key) const {
+ return iterator_range<const_prefix_iterator>{
+ const_prefix_iterator(&Root, KeyConstIteratorRangeType(Key)),
+ const_prefix_iterator{}};
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_RADIXTREE_H
diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index 9c81981..e02694f 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -125,7 +125,7 @@ struct detector<std::void_t<Op<Args...>>, Op, Args...> {
template <template <class...> class Op, class... Args>
using is_detected = typename detail::detector<void, Op, Args...>::value_t;
-struct identity_cxx20 // NOLINT(readability-identifier-naming)
+struct identity // NOLINT(readability-identifier-naming)
{
using is_transparent = void;
diff --git a/llvm/include/llvm/ADT/SparseMultiSet.h b/llvm/include/llvm/ADT/SparseMultiSet.h
index 5e4e170..59de4cf 100644
--- a/llvm/include/llvm/ADT/SparseMultiSet.h
+++ b/llvm/include/llvm/ADT/SparseMultiSet.h
@@ -82,7 +82,7 @@ namespace llvm {
/// @tparam SparseT An unsigned integer type. See above.
///
template <typename ValueT, typename KeyT = unsigned,
- typename KeyFunctorT = identity_cxx20, typename SparseT = uint8_t>
+ typename KeyFunctorT = identity, typename SparseT = uint8_t>
class SparseMultiSet {
static_assert(std::is_unsigned_v<SparseT>,
"SparseT must be an unsigned integer type");
diff --git a/llvm/include/llvm/ADT/SparseSet.h b/llvm/include/llvm/ADT/SparseSet.h
index 4697de09..41fd501 100644
--- a/llvm/include/llvm/ADT/SparseSet.h
+++ b/llvm/include/llvm/ADT/SparseSet.h
@@ -59,24 +59,20 @@ template <typename ValueT> struct SparseSetValTraits {
}
};
-/// SparseSetValFunctor - Helper class for selecting SparseSetValTraits. The
-/// generic implementation handles ValueT classes which either provide
-/// getSparseSetIndex() or specialize SparseSetValTraits<>.
+/// SparseSetValFunctor - Helper class for getting a value's index.
///
+/// In the generic case, this is done via SparseSetValTraits. When the value
+/// type is the same as the key type, the KeyFunctor is used directly.
template <typename KeyT, typename ValueT, typename KeyFunctorT>
struct SparseSetValFunctor {
unsigned operator()(const ValueT &Val) const {
- return SparseSetValTraits<ValueT>::getValIndex(Val);
+ if constexpr (std::is_same_v<KeyT, ValueT>)
+ return KeyFunctorT()(Val);
+ else
+ return SparseSetValTraits<ValueT>::getValIndex(Val);
}
};
-/// SparseSetValFunctor<KeyT, KeyT> - Helper class for the common case of
-/// identity key/value sets.
-template <typename KeyT, typename KeyFunctorT>
-struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
- unsigned operator()(const KeyT &Key) const { return KeyFunctorT()(Key); }
-};
-
/// SparseSet - Fast set implementation for objects that can be identified by
/// small unsigned keys.
///
@@ -117,7 +113,7 @@ struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
/// @tparam SparseT An unsigned integer type. See above.
///
template <typename ValueT, typename KeyT = unsigned,
- typename KeyFunctorT = identity_cxx20, typename SparseT = uint8_t>
+ typename KeyFunctorT = identity, typename SparseT = uint8_t>
class SparseSet {
static_assert(std::is_unsigned_v<SparseT>,
"SparseT must be an unsigned integer type");
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 9fddd47..a852555 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -610,14 +610,6 @@ LLVM_ABI ModulePass *createCheckDebugMachineModulePass();
/// caller saved registers with stack slots.
LLVM_ABI extern char &FixupStatepointCallerSavedID;
-/// The pass transforms load/store <256 x i32> to AMX load/store intrinsics
-/// or split the data to two <128 x i32>.
-LLVM_ABI FunctionPass *createX86LowerAMXTypePass();
-
-/// The pass transforms amx intrinsics to scalar operation if the function has
-/// optnone attribute or it is O0.
-LLVM_ABI FunctionPass *createX86LowerAMXIntrinsicsPass();
-
/// When learning an eviction policy, extract score(reward) information,
/// otherwise this does nothing
LLVM_ABI FunctionPass *createRegAllocScoringPass();
diff --git a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 26d7080..ab0d7e3 100644
--- a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -89,7 +89,7 @@ namespace llvm {
/// allocated once for the pass. It can be cleared in constant time and reused
/// without any frees.
using RegUnit2SUnitsMap =
- SparseMultiSet<PhysRegSUOper, unsigned, identity_cxx20, uint16_t>;
+ SparseMultiSet<PhysRegSUOper, unsigned, identity, uint16_t>;
/// Track local uses of virtual registers. These uses are gathered by the DAG
/// builder and may be consulted by the scheduler to avoid iterating an entire
diff --git a/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
index 3a36863..5a46207 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
@@ -34,7 +34,7 @@ class LLVM_ABI AppendingTypeTableBuilder : public TypeCollection {
public:
explicit AppendingTypeTableBuilder(BumpPtrAllocator &Storage);
- ~AppendingTypeTableBuilder();
+ ~AppendingTypeTableBuilder() override;
// TypeCollection overrides
std::optional<TypeIndex> getFirst() override;
diff --git a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
index a587b3e..93e1c99 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
@@ -47,7 +47,7 @@ class LLVM_ABI GlobalTypeTableBuilder : public TypeCollection {
public:
explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage);
- ~GlobalTypeTableBuilder();
+ ~GlobalTypeTableBuilder() override;
// TypeCollection overrides
std::optional<TypeIndex> getFirst() override;
diff --git a/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
index 7302784..b9b2669 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
@@ -43,7 +43,7 @@ class LLVM_ABI MergingTypeTableBuilder : public TypeCollection {
public:
explicit MergingTypeTableBuilder(BumpPtrAllocator &Storage);
- ~MergingTypeTableBuilder();
+ ~MergingTypeTableBuilder() override;
// TypeCollection overrides
std::optional<TypeIndex> getFirst() override;
diff --git a/llvm/include/llvm/DebugInfo/GSYM/GsymContext.h b/llvm/include/llvm/DebugInfo/GSYM/GsymContext.h
index 07d599c..e3e9b2b 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/GsymContext.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/GsymContext.h
@@ -30,7 +30,7 @@ class GsymReader;
class GsymContext : public DIContext {
public:
GsymContext(std::unique_ptr<GsymReader> Reader);
- ~GsymContext();
+ ~GsymContext() override;
GsymContext(GsymContext &) = delete;
GsymContext &operator=(GsymContext &) = delete;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 0e7be45..34bace8 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -143,7 +143,7 @@ public:
VirtualityCode(0) {}
LVElement(const LVElement &) = delete;
LVElement &operator=(const LVElement &) = delete;
- virtual ~LVElement() = default;
+ ~LVElement() override = default;
LVSubclassID getSubclassID() const { return SubclassID; }
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
index 3618ce7..dd17f76 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
@@ -53,7 +53,7 @@ public:
}
LVLine(const LVLine &) = delete;
LVLine &operator=(const LVLine &) = delete;
- virtual ~LVLine() = default;
+ ~LVLine() override = default;
static bool classof(const LVElement *Element) {
return Element->getSubclassID() == LVSubclassID::LV_LINE;
@@ -117,7 +117,7 @@ public:
LVLineDebug() : LVLine() { setIsLineDebug(); }
LVLineDebug(const LVLineDebug &) = delete;
LVLineDebug &operator=(const LVLineDebug &) = delete;
- ~LVLineDebug() = default;
+ ~LVLineDebug() override = default;
// Additional line information. It includes attributes that describes
// states in the machine instructions (basic block, end prologue, etc).
@@ -142,7 +142,7 @@ public:
LVLineAssembler() : LVLine() { setIsLineAssembler(); }
LVLineAssembler(const LVLineAssembler &) = delete;
LVLineAssembler &operator=(const LVLineAssembler &) = delete;
- ~LVLineAssembler() = default;
+ ~LVLineAssembler() override = default;
// Print blanks as the line number.
std::string noLineAsString(bool ShowZero) const override {
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
index 0718e33..090af54 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
@@ -100,7 +100,7 @@ public:
LVLocation() : LVObject() { setIsLocation(); }
LVLocation(const LVLocation &) = delete;
LVLocation &operator=(const LVLocation &) = delete;
- virtual ~LVLocation() = default;
+ ~LVLocation() override = default;
PROPERTY(Property, IsAddressRange);
PROPERTY(Property, IsBaseClassOffset);
@@ -171,7 +171,7 @@ public:
LVLocationSymbol() : LVLocation() {}
LVLocationSymbol(const LVLocationSymbol &) = delete;
LVLocationSymbol &operator=(const LVLocationSymbol &) = delete;
- ~LVLocationSymbol() = default;
+ ~LVLocationSymbol() override = default;
void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset,
uint64_t LocDescOffset) override;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
index b5c8333..4fa6a9a 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
@@ -62,7 +62,7 @@ public:
LVRange() : LVObject(), RangesTree(Allocator) {}
LVRange(const LVRange &) = delete;
LVRange &operator=(const LVRange &) = delete;
- ~LVRange() = default;
+ ~LVRange() override = default;
void addEntry(LVScope *Scope, LVAddress LowerAddress, LVAddress UpperAddress);
void addEntry(LVScope *Scope);
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index f4f3516..2e2619c 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -153,7 +153,7 @@ public:
}
LVScope(const LVScope &) = delete;
LVScope &operator=(const LVScope &) = delete;
- virtual ~LVScope() = default;
+ ~LVScope() override = default;
static bool classof(const LVElement *Element) {
return Element->getSubclassID() == LVSubclassID::LV_SCOPE;
@@ -349,7 +349,7 @@ public:
LVScopeAggregate() : LVScope() {}
LVScopeAggregate(const LVScopeAggregate &) = delete;
LVScopeAggregate &operator=(const LVScopeAggregate &) = delete;
- ~LVScopeAggregate() = default;
+ ~LVScopeAggregate() override = default;
// DW_AT_specification, DW_AT_abstract_origin.
LVScope *getReference() const override { return Reference; }
@@ -387,7 +387,7 @@ public:
}
LVScopeAlias(const LVScopeAlias &) = delete;
LVScopeAlias &operator=(const LVScopeAlias &) = delete;
- ~LVScopeAlias() = default;
+ ~LVScopeAlias() override = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
@@ -401,7 +401,7 @@ public:
LVScopeArray() : LVScope() { setIsArray(); }
LVScopeArray(const LVScopeArray &) = delete;
LVScopeArray &operator=(const LVScopeArray &) = delete;
- ~LVScopeArray() = default;
+ ~LVScopeArray() override = default;
void resolveExtra() override;
@@ -513,7 +513,7 @@ public:
}
LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
- ~LVScopeCompileUnit() = default;
+ ~LVScopeCompileUnit() override = default;
LVScope *getCompileUnitParent() const override {
return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));
@@ -643,7 +643,7 @@ public:
LVScopeEnumeration() : LVScope() { setIsEnumeration(); }
LVScopeEnumeration(const LVScopeEnumeration &) = delete;
LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
- ~LVScopeEnumeration() = default;
+ ~LVScopeEnumeration() override = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
@@ -658,7 +658,7 @@ public:
LVScopeFormalPack() : LVScope() { setIsTemplatePack(); }
LVScopeFormalPack(const LVScopeFormalPack &) = delete;
LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
- ~LVScopeFormalPack() = default;
+ ~LVScopeFormalPack() override = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
@@ -676,7 +676,7 @@ public:
LVScopeFunction() : LVScope() {}
LVScopeFunction(const LVScopeFunction &) = delete;
LVScopeFunction &operator=(const LVScopeFunction &) = delete;
- virtual ~LVScopeFunction() = default;
+ ~LVScopeFunction() override = default;
// DW_AT_specification, DW_AT_abstract_origin.
LVScope *getReference() const override { return Reference; }
@@ -728,7 +728,7 @@ public:
LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); }
LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete;
LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete;
- ~LVScopeFunctionInlined() = default;
+ ~LVScopeFunctionInlined() override = default;
uint32_t getDiscriminator() const override { return Discriminator; }
void setDiscriminator(uint32_t Value) override {
@@ -767,7 +767,7 @@ public:
LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); }
LVScopeFunctionType(const LVScopeFunctionType &) = delete;
LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete;
- ~LVScopeFunctionType() = default;
+ ~LVScopeFunctionType() override = default;
void resolveExtra() override;
};
@@ -781,7 +781,7 @@ public:
}
LVScopeModule(const LVScopeModule &) = delete;
LVScopeModule &operator=(const LVScopeModule &) = delete;
- ~LVScopeModule() = default;
+ ~LVScopeModule() override = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
@@ -797,7 +797,7 @@ public:
LVScopeNamespace() : LVScope() { setIsNamespace(); }
LVScopeNamespace(const LVScopeNamespace &) = delete;
LVScopeNamespace &operator=(const LVScopeNamespace &) = delete;
- ~LVScopeNamespace() = default;
+ ~LVScopeNamespace() override = default;
// Access DW_AT_extension reference.
LVScope *getReference() const override { return Reference; }
@@ -827,7 +827,7 @@ public:
LVScopeRoot() : LVScope() { setIsRoot(); }
LVScopeRoot(const LVScopeRoot &) = delete;
LVScopeRoot &operator=(const LVScopeRoot &) = delete;
- ~LVScopeRoot() = default;
+ ~LVScopeRoot() override = default;
StringRef getFileFormatName() const {
return getStringPool().getString(FileFormatNameIndex);
@@ -859,7 +859,7 @@ public:
LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); }
LVScopeTemplatePack(const LVScopeTemplatePack &) = delete;
LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
- ~LVScopeTemplatePack() = default;
+ ~LVScopeTemplatePack() override = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
index ec9017e..c5314fc 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
@@ -74,7 +74,7 @@ public:
}
LVSymbol(const LVSymbol &) = delete;
LVSymbol &operator=(const LVSymbol &) = delete;
- ~LVSymbol() = default;
+ ~LVSymbol() override = default;
static bool classof(const LVElement *Element) {
return Element->getSubclassID() == LVSubclassID::LV_SYMBOL;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
index 59e6a92..af4abcf 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
@@ -67,7 +67,7 @@ public:
LVType() : LVElement(LVSubclassID::LV_TYPE) { setIsType(); }
LVType(const LVType &) = delete;
LVType &operator=(const LVType &) = delete;
- virtual ~LVType() = default;
+ ~LVType() override = default;
static bool classof(const LVElement *Element) {
return Element->getSubclassID() == LVSubclassID::LV_TYPE;
@@ -157,7 +157,7 @@ public:
}
LVTypeDefinition(const LVTypeDefinition &) = delete;
LVTypeDefinition &operator=(const LVTypeDefinition &) = delete;
- ~LVTypeDefinition() = default;
+ ~LVTypeDefinition() override = default;
// Return the underlying type for a type definition.
LVElement *getUnderlyingType() override;
@@ -183,7 +183,7 @@ public:
}
LVTypeEnumerator(const LVTypeEnumerator &) = delete;
LVTypeEnumerator &operator=(const LVTypeEnumerator &) = delete;
- ~LVTypeEnumerator() = default;
+ ~LVTypeEnumerator() override = default;
// Process the values for a DW_TAG_enumerator.
StringRef getValue() const override {
@@ -206,7 +206,7 @@ public:
LVTypeImport() : LVType() { setIncludeInPrint(); }
LVTypeImport(const LVTypeImport &) = delete;
LVTypeImport &operator=(const LVTypeImport &) = delete;
- ~LVTypeImport() = default;
+ ~LVTypeImport() override = default;
// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;
@@ -223,7 +223,7 @@ public:
LVTypeParam();
LVTypeParam(const LVTypeParam &) = delete;
LVTypeParam &operator=(const LVTypeParam &) = delete;
- ~LVTypeParam() = default;
+ ~LVTypeParam() override = default;
// Template parameter value.
StringRef getValue() const override {
@@ -256,7 +256,7 @@ public:
}
LVTypeSubrange(const LVTypeSubrange &) = delete;
LVTypeSubrange &operator=(const LVTypeSubrange &) = delete;
- ~LVTypeSubrange() = default;
+ ~LVTypeSubrange() override = default;
int64_t getCount() const override {
return getIsSubrangeCount() ? LowerBound : 0;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
index 2cf4a8e..cc8dda2 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
@@ -192,7 +192,7 @@ public:
: LVReader(Filename, FileFormatName, W, BinaryType) {}
LVBinaryReader(const LVBinaryReader &) = delete;
LVBinaryReader &operator=(const LVBinaryReader &) = delete;
- virtual ~LVBinaryReader() = default;
+ ~LVBinaryReader() override = default;
void addInlineeLines(LVScope *Scope, LVLines &Lines) {
CUInlineeLines.emplace(Scope, std::make_unique<LVLines>(std::move(Lines)));
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h
index 4dd7c96..9f6fd553 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h
@@ -200,7 +200,7 @@ public:
Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
LVCodeViewReader(const LVCodeViewReader &) = delete;
LVCodeViewReader &operator=(const LVCodeViewReader &) = delete;
- ~LVCodeViewReader() = default;
+ ~LVCodeViewReader() override = default;
void getLinkageName(const llvm::object::coff_section *CoffSection,
uint32_t RelocOffset, uint32_t Offset,
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h
index 2abc18b..1cf2914 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h
@@ -123,7 +123,7 @@ public:
Obj(Obj) {}
LVDWARFReader(const LVDWARFReader &) = delete;
LVDWARFReader &operator=(const LVDWARFReader &) = delete;
- ~LVDWARFReader() = default;
+ ~LVDWARFReader() override = default;
LVAddress getCUBaseAddress() const { return CUBaseAddress; }
void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; }
diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
index b21cd09..c0b3151 100644
--- a/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
+++ b/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
@@ -20,7 +20,7 @@ namespace pdb {
class LLVM_ABI PDBSymbolTypeBuiltin : public PDBSymbol {
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BuiltinType)
public:
- ~PDBSymbolTypeBuiltin();
+ ~PDBSymbolTypeBuiltin() override;
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getBuiltinType)
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index f05febf..24a0cb7 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -1768,7 +1768,7 @@ private:
// FIXME: We should be able to derive FailedSymsForQuery from each query once
// we fix how the detach operation works.
struct EmitQueries {
- JITDylib::AsynchronousSymbolQuerySet Updated;
+ JITDylib::AsynchronousSymbolQuerySet Completed;
JITDylib::AsynchronousSymbolQuerySet Failed;
DenseMap<AsynchronousSymbolQuery *, std::shared_ptr<SymbolDependenceMap>>
FailedSymsForQuery;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h
index 4a32113b..6adaa8a 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h
@@ -34,7 +34,7 @@ using ExecutorAddrDiff = uint64_t;
class ExecutorAddr {
public:
/// A wrap/unwrap function that leaves pointers unmodified.
- using rawPtr = llvm::identity_cxx20;
+ using rawPtr = llvm::identity;
#if __has_feature(ptrauth_calls)
template <typename T> class PtrauthSignDefault {
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h
deleted file mode 100644
index 5170893..0000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h
+++ /dev/null
@@ -1,173 +0,0 @@
-//===- SymbolFilter.h - Utilities for Symbol Filtering ---------*- 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_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
-
-#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
-
-#include <cmath>
-#include <type_traits>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-namespace shared {
-using SPSBloomFilter =
- SPSTuple<bool, uint32_t, uint32_t, uint32_t, SPSSequence<uint64_t>>;
-}
-
-class BloomFilter {
-public:
- using HashFunc = std::function<uint32_t(StringRef)>;
-
- BloomFilter() = default;
- BloomFilter(BloomFilter &&) noexcept = default;
- BloomFilter &operator=(BloomFilter &&) noexcept = default;
- BloomFilter(const BloomFilter &) = delete;
- BloomFilter &operator=(const BloomFilter &) = delete;
-
- BloomFilter(uint32_t SymbolCount, float FalsePositiveRate, HashFunc hashFn)
- : HashFn(std::move(hashFn)) {
- initialize(SymbolCount, FalsePositiveRate);
- }
- bool isInitialized() const { return Initialized; }
-
- void add(StringRef Sym) {
- assert(Initialized);
- addHash(HashFn(Sym));
- }
-
- bool mayContain(StringRef Sym) const {
- return !isEmpty() && testHash(HashFn(Sym));
- }
-
- bool isEmpty() const { return SymbolCount == 0; }
-
-private:
- friend class shared::SPSSerializationTraits<shared::SPSBloomFilter,
- BloomFilter>;
- static constexpr uint32_t BitsPerEntry = 64;
-
- bool Initialized = false;
- uint32_t SymbolCount = 0;
- uint32_t BloomSize = 0;
- uint32_t BloomShift = 0;
- std::vector<uint64_t> BloomTable;
- HashFunc HashFn;
-
- void initialize(uint32_t SymCount, float FalsePositiveRate) {
- assert(SymCount > 0);
- SymbolCount = SymCount;
- Initialized = true;
-
- float ln2 = std::log(2.0f);
- float M = -1.0f * SymbolCount * std::log(FalsePositiveRate) / (ln2 * ln2);
- BloomSize = static_cast<uint32_t>(std::ceil(M / BitsPerEntry));
- BloomShift = std::min(6u, log2ceil(SymbolCount));
- BloomTable.resize(BloomSize, 0);
- }
-
- void addHash(uint32_t Hash) {
- uint32_t Hash2 = Hash >> BloomShift;
- uint32_t N = (Hash / BitsPerEntry) % BloomSize;
- uint64_t Mask =
- (1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
- BloomTable[N] |= Mask;
- }
-
- bool testHash(uint32_t Hash) const {
- uint32_t Hash2 = Hash >> BloomShift;
- uint32_t N = (Hash / BitsPerEntry) % BloomSize;
- uint64_t Mask =
- (1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
- return (BloomTable[N] & Mask) == Mask;
- }
-
- static constexpr uint32_t log2ceil(uint32_t V) {
- return V <= 1 ? 0 : 32 - countl_zero(V - 1);
- }
-};
-
-class BloomFilterBuilder {
-public:
- using HashFunc = BloomFilter::HashFunc;
-
- BloomFilterBuilder() = default;
-
- BloomFilterBuilder &setFalsePositiveRate(float Rate) {
- assert(Rate > 0.0f && Rate < 1.0f);
- FalsePositiveRate = Rate;
- return *this;
- }
-
- BloomFilterBuilder &setHashFunction(HashFunc Fn) {
- HashFn = std::move(Fn);
- return *this;
- }
-
- BloomFilter build(ArrayRef<StringRef> Symbols) const {
- assert(!Symbols.empty() && "Cannot build filter from empty symbol list.");
- BloomFilter F(static_cast<uint32_t>(Symbols.size()), FalsePositiveRate,
- HashFn);
- for (const auto &Sym : Symbols)
- F.add(Sym);
-
- return F;
- }
-
-private:
- float FalsePositiveRate = 0.02f;
- HashFunc HashFn = [](StringRef S) -> uint32_t {
- uint32_t H = 5381;
- for (char C : S)
- H = ((H << 5) + H) + static_cast<uint8_t>(C); // H * 33 + C
- return H;
- };
-};
-
-namespace shared {
-
-template <> class SPSSerializationTraits<SPSBloomFilter, BloomFilter> {
-public:
- static size_t size(const BloomFilter &Filter) {
- return SPSBloomFilter::AsArgList::size(
- Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
- Filter.BloomShift, Filter.BloomTable);
- }
-
- static bool serialize(SPSOutputBuffer &OB, const BloomFilter &Filter) {
- return SPSBloomFilter::AsArgList::serialize(
- OB, Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
- Filter.BloomShift, Filter.BloomTable);
- }
-
- static bool deserialize(SPSInputBuffer &IB, BloomFilter &Filter) {
- bool IsInitialized;
- uint32_t SymbolCount = 0, BloomSize = 0, BloomShift = 0;
- std::vector<uint64_t> BloomTable;
-
- if (!SPSBloomFilter::AsArgList::deserialize(
- IB, IsInitialized, SymbolCount, BloomSize, BloomShift, BloomTable))
- return false;
-
- Filter.Initialized = IsInitialized;
- Filter.SymbolCount = SymbolCount;
- Filter.BloomSize = BloomSize;
- Filter.BloomShift = BloomShift;
- Filter.BloomTable = std::move(BloomTable);
-
- return true;
- }
-};
-
-} // end namespace shared
-} // end namespace orc
-} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
deleted file mode 100644
index 50d4f6d041..0000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
+++ /dev/null
@@ -1,514 +0,0 @@
-//===- LibraryResolver.h - Automatic Library Symbol Resolution -*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides support for automatically searching symbols across
-// dynamic libraries that have not yet been loaded.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
-
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h"
-#include "llvm/Support/Path.h"
-
-#include <atomic>
-#include <shared_mutex>
-#include <unordered_map>
-
-namespace llvm {
-namespace orc {
-
-/// Manages library metadata and state for symbol resolution.
-///
-/// Tracks libraries by load state and kind (user/system), and stores
-/// associated Bloom filters and hash maps to speed up symbol lookups.
-/// Thread-safe for concurrent access.
-class LibraryManager {
-public:
- enum class LibState : uint8_t { Unloaded = 0, Loaded = 1, Queried = 2 };
-
- class LibraryInfo {
- public:
- LibraryInfo(const LibraryInfo &) = delete;
- LibraryInfo &operator=(const LibraryInfo &) = delete;
-
- LibraryInfo(std::string FilePath, LibState S, PathType K,
- std::optional<BloomFilter> Filter = std::nullopt)
- : FilePath(std::move(FilePath)), S(S), K(K), Filter(std::move(Filter)) {
- }
-
- StringRef getBasePath() const { return sys::path::parent_path(FilePath); }
- StringRef getFileName() const { return sys::path::filename(FilePath); }
-
- std::string getFullPath() const { return FilePath; }
-
- bool setFilter(BloomFilter F) {
- std::lock_guard<std::shared_mutex> Lock(Mtx);
- if (Filter)
- return false;
- Filter.emplace(std::move(F));
- return true;
- }
-
- bool ensureFilterBuilt(const BloomFilterBuilder &FB,
- ArrayRef<StringRef> Symbols) {
- std::lock_guard<std::shared_mutex> Lock(Mtx);
- if (Filter)
- return false;
- Filter.emplace(FB.build(Symbols));
- return true;
- }
-
- bool mayContain(StringRef Symbol) const {
- assert(hasFilter());
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- return Filter->mayContain(Symbol);
- }
-
- bool hasFilter() const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- return Filter.has_value();
- }
-
- LibState getState() const { return S.load(); }
- PathType getKind() const { return K; }
-
- void setState(LibState s) { S.store(s); }
-
- bool operator==(const LibraryInfo &other) const {
- return FilePath == other.FilePath;
- }
-
- private:
- std::string FilePath;
- std::atomic<LibState> S;
- PathType K;
- std::optional<BloomFilter> Filter;
- mutable std::shared_mutex Mtx;
- };
-
- /// A read-only view of libraries filtered by state and kind.
- ///
- /// Lets you loop over only the libraries in a map that match a given State
- /// and PathType.
- class FilteredView {
- public:
- using Map = StringMap<std::shared_ptr<LibraryInfo>>;
- using Iterator = typename Map::const_iterator;
- class FilterIterator {
- public:
- FilterIterator(Iterator it_, Iterator end_, LibState S, PathType K)
- : it(it_), end(end_), S(S), K(K) {
- advance();
- }
-
- bool operator!=(const FilterIterator &other) const {
- return it != other.it;
- }
-
- const std::shared_ptr<LibraryInfo> &operator*() const {
- return it->second;
- }
-
- FilterIterator &operator++() {
- ++it;
- advance();
- return *this;
- }
-
- private:
- void advance() {
- for (; it != end; ++it)
- if (it->second->getState() == S && it->second->getKind() == K)
- break;
- }
- Iterator it;
- Iterator end;
- LibState S;
- PathType K;
- };
- FilteredView(Iterator begin, Iterator end, LibState s, PathType k)
- : mapBegin(begin), mapEnd(end), state(s), kind(k) {}
-
- FilterIterator begin() const {
- return FilterIterator(mapBegin, mapEnd, state, kind);
- }
-
- FilterIterator end() const {
- return FilterIterator(mapEnd, mapEnd, state, kind);
- }
-
- private:
- Iterator mapBegin;
- Iterator mapEnd;
- LibState state;
- PathType kind;
- };
-
-private:
- StringMap<std::shared_ptr<LibraryInfo>> Libraries;
- mutable std::shared_mutex Mtx;
-
-public:
- using LibraryVisitor = std::function<bool(const LibraryInfo &)>;
-
- LibraryManager() = default;
- ~LibraryManager() = default;
-
- bool addLibrary(std::string Path, PathType Kind,
- std::optional<BloomFilter> Filter = std::nullopt) {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- if (Libraries.count(Path) > 0)
- return false;
- Libraries.insert({std::move(Path),
- std::make_shared<LibraryInfo>(Path, LibState::Unloaded,
- Kind, std::move(Filter))});
- return true;
- }
-
- bool hasLibrary(StringRef Path) const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- if (Libraries.count(Path) > 0)
- return true;
- return false;
- }
-
- bool removeLibrary(StringRef Path) {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- auto I = Libraries.find(Path);
- if (I == Libraries.end())
- return false;
- Libraries.erase(I);
- return true;
- }
-
- void markLoaded(StringRef Path) {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- if (auto It = Libraries.find(Path); It != Libraries.end())
- It->second->setState(LibState::Loaded);
- }
-
- void markQueried(StringRef Path) {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- if (auto It = Libraries.find(Path); It != Libraries.end())
- It->second->setState(LibState::Queried);
- }
-
- std::shared_ptr<LibraryInfo> getLibrary(StringRef Path) {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- if (auto It = Libraries.find(Path); It != Libraries.end())
- return It->second;
- return nullptr;
- }
-
- FilteredView getView(LibState S, PathType K) const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- return FilteredView(Libraries.begin(), Libraries.end(), S, K);
- }
-
- void forEachLibrary(const LibraryVisitor &visitor) const {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- for (const auto &[_, entry] : Libraries) {
- if (!visitor(*entry))
- break;
- }
- }
-
- bool isLoaded(StringRef Path) const {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- if (auto It = Libraries.find(Path.str()); It != Libraries.end())
- return It->second->getState() == LibState::Loaded;
- return false;
- }
-
- bool isQueried(StringRef Path) const {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- if (auto It = Libraries.find(Path.str()); It != Libraries.end())
- return It->second->getState() == LibState::Queried;
- return false;
- }
-
- void clear() {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- Libraries.clear();
- }
-};
-
-using LibraryInfo = LibraryManager::LibraryInfo;
-
-struct SearchPlanEntry {
- LibraryManager::LibState State; // Loaded, Queried, Unloaded
- PathType Type; // User, System
-};
-
-struct SearchPolicy {
- std::vector<SearchPlanEntry> Plan;
-
- static SearchPolicy defaultPlan() {
- return {{{LibraryManager::LibState::Loaded, PathType::User},
- {LibraryManager::LibState::Queried, PathType::User},
- {LibraryManager::LibState::Unloaded, PathType::User},
- {LibraryManager::LibState::Loaded, PathType::System},
- {LibraryManager::LibState::Queried, PathType::System},
- {LibraryManager::LibState::Unloaded, PathType::System}}};
- }
-};
-
-struct SymbolEnumeratorOptions {
- enum Filter : uint32_t {
- None = 0,
- IgnoreUndefined = 1 << 0,
- IgnoreWeak = 1 << 1,
- IgnoreIndirect = 1 << 2,
- IgnoreHidden = 1 << 3,
- IgnoreNonGlobal = 1 << 4
- };
-
- static SymbolEnumeratorOptions defaultOptions() {
- return {Filter::IgnoreUndefined | Filter::IgnoreWeak |
- Filter::IgnoreIndirect};
- }
- uint32_t FilterFlags = Filter::None;
-};
-
-struct SearchConfig {
- SearchPolicy Policy;
- SymbolEnumeratorOptions Options;
-
- SearchConfig()
- : Policy(SearchPolicy::defaultPlan()), // default plan
- Options(SymbolEnumeratorOptions::defaultOptions()) {}
-};
-
-/// Scans libraries and resolves Symbols across user and system paths.
-///
-/// Supports symbol enumeration and filtering via SymbolEnumerator, and tracks
-/// symbol resolution results through SymbolQuery. Thread-safe and uses
-/// LibraryScanHelper for efficient path resolution and caching.
-class LibraryResolver {
- friend class LibraryResolutionDriver;
-
-public:
- class SymbolEnumerator {
- public:
- enum class EnumerateResult { Continue, Stop, Error };
-
- using OnEachSymbolFn = std::function<EnumerateResult(StringRef Sym)>;
-
- static bool enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach,
- const SymbolEnumeratorOptions &Opts);
- };
-
- /// Tracks a set of symbols and the libraries where they are resolved.
- ///
- /// SymbolQuery is used to keep track of which symbols have been resolved
- /// to which libraries. It supports concurrent read/write access using a
- /// shared mutex, allowing multiple readers or a single writer at a time.
- class SymbolQuery {
- public:
- /// Holds the result for a single symbol.
- struct Result {
- std::string Name;
- std::string ResolvedLibPath;
- };
-
- private:
- mutable std::shared_mutex Mtx;
- StringMap<Result> Results;
- std::atomic<size_t> ResolvedCount = 0;
-
- public:
- explicit SymbolQuery(const std::vector<std::string> &Symbols) {
- for (const auto &s : Symbols) {
- if (!Results.contains(s))
- Results.insert({s, Result{s, ""}});
- }
- }
-
- SmallVector<StringRef> getUnresolvedSymbols() const {
- SmallVector<StringRef> Unresolved;
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- for (const auto &[name, res] : Results) {
- if (res.ResolvedLibPath.empty())
- Unresolved.push_back(name);
- }
- return Unresolved;
- }
-
- void resolve(StringRef Sym, const std::string &LibPath) {
- std::unique_lock<std::shared_mutex> Lock(Mtx);
- auto It = Results.find(Sym);
- if (It != Results.end() && It->second.ResolvedLibPath.empty()) {
- It->second.ResolvedLibPath = LibPath;
- ResolvedCount.fetch_add(1, std::memory_order_relaxed);
- }
- }
-
- bool allResolved() const {
- return ResolvedCount.load(std::memory_order_relaxed) == Results.size();
- }
-
- bool hasUnresolved() const {
- return ResolvedCount.load(std::memory_order_relaxed) < Results.size();
- }
-
- std::optional<StringRef> getResolvedLib(StringRef Sym) const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- auto It = Results.find(Sym);
- if (It != Results.end() && !It->second.ResolvedLibPath.empty())
- return StringRef(It->second.ResolvedLibPath);
- return std::nullopt;
- }
-
- bool isResolved(StringRef Sym) const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- auto It = Results.find(Sym.str());
- return It != Results.end() && !It->second.ResolvedLibPath.empty();
- }
-
- std::vector<const Result *> getAllResults() const {
- std::shared_lock<std::shared_mutex> Lock(Mtx);
- std::vector<const Result *> Out;
- Out.reserve(Results.size());
- for (const auto &[_, res] : Results)
- Out.push_back(&res);
- return Out;
- }
- };
-
- struct Setup {
- std::vector<std::string> BasePaths;
- std::shared_ptr<LibraryPathCache> Cache;
- std::shared_ptr<PathResolver> PResolver;
-
- size_t ScanBatchSize = 0;
-
- LibraryScanner::ShouldScanFn ShouldScanCall = [](StringRef) {
- return true;
- };
-
- BloomFilterBuilder FilterBuilder = BloomFilterBuilder();
-
- static Setup
- create(std::vector<std::string> BasePaths,
- std::shared_ptr<LibraryPathCache> existingCache = nullptr,
- std::shared_ptr<PathResolver> existingResolver = nullptr,
- LibraryScanner::ShouldScanFn customShouldScan = nullptr) {
- Setup S;
- S.BasePaths = std::move(BasePaths);
-
- S.Cache =
- existingCache ? existingCache : std::make_shared<LibraryPathCache>();
-
- S.PResolver = existingResolver ? existingResolver
- : std::make_shared<PathResolver>(S.Cache);
-
- if (customShouldScan)
- S.ShouldScanCall = std::move(customShouldScan);
-
- return S;
- }
- };
-
- LibraryResolver() = delete;
- explicit LibraryResolver(const Setup &S);
- ~LibraryResolver() = default;
-
- using OnSearchComplete = unique_function<void(SymbolQuery &)>;
-
- void dump() {
- int i = 0;
- LibMgr.forEachLibrary([&](const LibraryInfo &Lib) -> bool {
- dbgs() << ++i << ". Library Path : " << Lib.getFullPath() << " -> \n\t\t:"
- << " ({Type : ("
- << (Lib.getKind() == PathType::User ? "User" : "System")
- << ") }, { State : "
- << (Lib.getState() == LibraryManager::LibState::Loaded
- ? "Loaded"
- : "Unloaded")
- << "})\n";
- return true;
- });
- }
-
- void searchSymbolsInLibraries(std::vector<std::string> &SymList,
- OnSearchComplete OnComplete,
- const SearchConfig &Config = SearchConfig());
-
-private:
- bool scanLibrariesIfNeeded(PathType K, size_t BatchSize = 0);
- void resolveSymbolsInLibrary(LibraryInfo &Lib, SymbolQuery &Q,
- const SymbolEnumeratorOptions &Opts);
- bool
- symbolExistsInLibrary(const LibraryInfo &Lib, StringRef Sym,
- std::vector<std::string> *MatchedSymbols = nullptr);
-
- bool symbolExistsInLibrary(const LibraryInfo &Lib, StringRef SymName,
- std::vector<std::string> *AllSymbols,
- const SymbolEnumeratorOptions &Opts);
-
- std::shared_ptr<LibraryPathCache> LibPathCache;
- std::shared_ptr<PathResolver> LibPathResolver;
- LibraryScanHelper ScanHelper;
- BloomFilterBuilder FB;
- LibraryManager LibMgr;
- LibraryScanner::ShouldScanFn ShouldScanCall;
- size_t scanBatchSize;
-};
-
-using SymbolEnumerator = LibraryResolver::SymbolEnumerator;
-using SymbolQuery = LibraryResolver::SymbolQuery;
-using EnumerateResult = SymbolEnumerator::EnumerateResult;
-
-class LibraryResolutionDriver {
-public:
- static std::unique_ptr<LibraryResolutionDriver>
- create(const LibraryResolver::Setup &S);
-
- void addScanPath(const std::string &Path, PathType Kind);
- bool markLibraryLoaded(StringRef Path);
- bool markLibraryUnLoaded(StringRef Path);
- bool isLibraryLoaded(StringRef Path) const {
- return LR->LibMgr.isLoaded(Path);
- }
-
- void resetAll() {
- LR->LibMgr.clear();
- LR->ScanHelper.resetToScan();
- LR->LibPathCache->clear();
- }
-
- void scanAll(size_t BatchSize = 0) {
- LR->scanLibrariesIfNeeded(PathType::User, BatchSize);
- LR->scanLibrariesIfNeeded(PathType::System, BatchSize);
- }
-
- void scan(PathType PK, size_t BatchSize = 0) {
- LR->scanLibrariesIfNeeded(PK, BatchSize);
- }
-
- void resolveSymbols(std::vector<std::string> Symbols,
- LibraryResolver::OnSearchComplete OnCompletion,
- const SearchConfig &Config = SearchConfig());
-
- ~LibraryResolutionDriver() = default;
-
-private:
- LibraryResolutionDriver(std::unique_ptr<LibraryResolver> L)
- : LR(std::move(L)) {}
-
- std::unique_ptr<LibraryResolver> LR;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
deleted file mode 100644
index d1c2013..0000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
+++ /dev/null
@@ -1,474 +0,0 @@
-//===- LibraryScanner.h - Scanner for Shared Libraries ---------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides functionality for scanning dynamic (shared) libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
-
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/StringSaver.h"
-
-#include <atomic>
-#include <mutex>
-#include <queue>
-#include <shared_mutex>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-
-namespace llvm {
-namespace orc {
-
-class LibraryManager;
-
-class LibraryPathCache {
- friend class PathResolver;
-
-public:
- LibraryPathCache() = default;
-
- void clear(bool isRealPathCache = false) {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- Seen.clear();
- if (isRealPathCache) {
- RealPathCache.clear();
-#ifndef _WIN32
- ReadlinkCache.clear();
- LstatCache.clear();
-#endif
- }
- }
-
- void markSeen(const std::string &CanonPath) {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- Seen.insert(CanonPath);
- }
-
- bool hasSeen(StringRef CanonPath) const {
- std::shared_lock<std::shared_mutex> lock(Mtx);
- return Seen.contains(CanonPath);
- }
-
- bool hasSeenOrMark(StringRef CanonPath) {
- std::string s = CanonPath.str();
- {
- std::shared_lock<std::shared_mutex> lock(Mtx);
- if (Seen.contains(s))
- return true;
- }
- {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- Seen.insert(s);
- }
- return false;
- }
-
-private:
- mutable std::shared_mutex Mtx;
-
- struct PathInfo {
- std::string canonicalPath;
- std::error_code ErrnoCode;
- };
-
- void insert_realpath(StringRef Path, const PathInfo &Info) {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- RealPathCache.insert({Path, Info});
- }
-
- std::optional<PathInfo> read_realpath(StringRef Path) const {
- std::shared_lock<std::shared_mutex> lock(Mtx);
- auto It = RealPathCache.find(Path);
- if (It != RealPathCache.end())
- return It->second;
-
- return std::nullopt;
- }
-
- StringSet<> Seen;
- StringMap<PathInfo> RealPathCache;
-
-#ifndef _WIN32
- StringMap<std::string> ReadlinkCache;
- StringMap<mode_t> LstatCache;
-
- void insert_link(StringRef Path, const std::string &s) {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- ReadlinkCache.insert({Path, s});
- }
-
- std::optional<std::string> read_link(StringRef Path) const {
- std::shared_lock<std::shared_mutex> lock(Mtx);
- auto It = ReadlinkCache.find(Path);
- if (It != ReadlinkCache.end())
- return It->second;
-
- return std::nullopt;
- }
-
- void insert_lstat(StringRef Path, mode_t m) {
- std::unique_lock<std::shared_mutex> lock(Mtx);
- LstatCache.insert({Path, m});
- }
-
- std::optional<mode_t> read_lstat(StringRef Path) const {
- std::shared_lock<std::shared_mutex> lock(Mtx);
- auto It = LstatCache.find(Path);
- if (It != LstatCache.end())
- return It->second;
-
- return std::nullopt;
- }
-
-#endif
-};
-
-/// Resolves file system paths with optional caching of results.
-///
-/// Supports lstat, readlink, and realpath operations. Can resolve paths
-/// relative to a base and handle symbolic links. Caches results to reduce
-/// repeated system calls when enabled.
-class PathResolver {
-private:
- std::shared_ptr<LibraryPathCache> LibPathCache;
-
-public:
- PathResolver(std::shared_ptr<LibraryPathCache> cache)
- : LibPathCache(std::move(cache)) {}
-
- std::optional<std::string> resolve(StringRef Path, std::error_code &ec) {
- return realpathCached(Path, ec);
- }
-#ifndef _WIN32
- mode_t lstatCached(StringRef Path);
- std::optional<std::string> readlinkCached(StringRef Path);
-#endif
- std::optional<std::string> realpathCached(StringRef Path, std::error_code &ec,
- StringRef base = "",
- bool baseIsResolved = false,
- long symloopLevel = 40);
-};
-
-/// Performs placeholder substitution in dynamic library paths.
-///
-/// Configures known placeholders (like @loader_path) and replaces them
-/// in input paths with their resolved values.
-class DylibSubstitutor {
-public:
- void configure(StringRef loaderPath);
-
- std::string substitute(StringRef input) const {
- for (const auto &[ph, value] : Placeholders) {
- if (input.starts_with_insensitive(ph))
- return (Twine(value) + input.drop_front(ph.size())).str();
- }
- return input.str();
- }
-
-private:
- StringMap<std::string> Placeholders;
-};
-
-/// Validates and normalizes dynamic library paths.
-///
-/// Uses a `PathResolver` to resolve paths to their canonical form and
-/// checks whether they point to valid shared libraries.
-class DylibPathValidator {
-public:
- DylibPathValidator(PathResolver &PR) : LibPathResolver(PR) {}
-
- static bool isSharedLibrary(StringRef Path);
-
- std::optional<std::string> normalize(StringRef Path) const {
- std::error_code ec;
- auto real = LibPathResolver.resolve(Path, ec);
- if (!real || ec)
- return std::nullopt;
-
- return real;
- }
-
- /// Validate the given path as a shared library.
- std::optional<std::string> validate(StringRef Path) const {
- auto realOpt = normalize(Path);
- if (!realOpt)
- return std::nullopt;
-
- if (!isSharedLibrary(*realOpt))
- return std::nullopt;
-
- return realOpt;
- }
-
-private:
- PathResolver &LibPathResolver;
-};
-
-enum class SearchPathType {
- RPath,
- UsrOrSys,
- RunPath,
-};
-
-struct SearchPathConfig {
- ArrayRef<StringRef> Paths;
- SearchPathType type;
-};
-
-class SearchPathResolver {
-public:
- SearchPathResolver(const SearchPathConfig &Cfg,
- StringRef PlaceholderPrefix = "")
- : Kind(Cfg.type), PlaceholderPrefix(PlaceholderPrefix) {
- for (auto &path : Cfg.Paths)
- Paths.emplace_back(path.str());
- }
-
- std::optional<std::string> resolve(StringRef libStem,
- const DylibSubstitutor &Subst,
- DylibPathValidator &Validator) const;
- SearchPathType searchPathType() const { return Kind; }
-
-private:
- std::vector<std::string> Paths;
- SearchPathType Kind;
- std::string PlaceholderPrefix;
-};
-
-class DylibResolverImpl {
-public:
- DylibResolverImpl(DylibSubstitutor Substitutor, DylibPathValidator &Validator,
- std::vector<SearchPathResolver> Resolvers)
- : Substitutor(std::move(Substitutor)), Validator(Validator),
- Resolvers(std::move(Resolvers)) {}
-
- std::optional<std::string> resolve(StringRef Stem,
- bool VariateLibStem = false) const;
-
-private:
- std::optional<std::string> tryWithExtensions(StringRef libstem) const;
-
- DylibSubstitutor Substitutor;
- DylibPathValidator &Validator;
- std::vector<SearchPathResolver> Resolvers;
-};
-
-class DylibResolver {
-public:
- DylibResolver(DylibPathValidator &Validator) : Validator(Validator) {}
-
- void configure(StringRef loaderPath,
- ArrayRef<SearchPathConfig> SearchPathCfg) {
- DylibSubstitutor Substitutor;
- Substitutor.configure(loaderPath);
-
- std::vector<SearchPathResolver> Resolvers;
- for (const auto &cfg : SearchPathCfg) {
- Resolvers.emplace_back(cfg,
- cfg.type == SearchPathType::RPath ? "@rpath" : "");
- }
-
- impl_ = std::make_unique<DylibResolverImpl>(
- std::move(Substitutor), Validator, std::move(Resolvers));
- }
-
- std::optional<std::string> resolve(StringRef libStem,
- bool VariateLibStem = false) const {
- if (!impl_)
- return std::nullopt;
- return impl_->resolve(libStem, VariateLibStem);
- }
-
- static std::string resolvelinkerFlag(StringRef libStem,
- StringRef loaderPath) {
- DylibSubstitutor Substitutor;
- Substitutor.configure(loaderPath);
- return Substitutor.substitute(libStem);
- }
-
-private:
- DylibPathValidator &Validator;
- std::unique_ptr<DylibResolverImpl> impl_;
-};
-
-enum class PathType : uint8_t { User, System, Unknown };
-
-enum class ScanState : uint8_t { NotScanned, Scanning, Scanned };
-
-struct LibrarySearchPath {
- std::string BasePath; // Canonical base directory path
- PathType Kind; // User or System
- std::atomic<ScanState> State;
-
- LibrarySearchPath(std::string Base, PathType K)
- : BasePath(std::move(Base)), Kind(K), State(ScanState::NotScanned) {}
-};
-
-/// Scans and tracks libraries for symbol resolution.
-///
-/// Maintains a list of library paths to scan, caches scanned units,
-/// and resolves paths canonically for consistent tracking.
-class LibraryScanHelper {
-public:
- explicit LibraryScanHelper(const std::vector<std::string> &SPaths,
- std::shared_ptr<LibraryPathCache> LibPathCache,
- std::shared_ptr<PathResolver> LibPathResolver)
- : LibPathCache(std::move(LibPathCache)),
- LibPathResolver(std::move(LibPathResolver)) {
- DEBUG_WITH_TYPE(
- "orc", dbgs() << "LibraryScanHelper::LibraryScanHelper: base paths : "
- << SPaths.size() << "\n";);
- for (const auto &p : SPaths)
- addBasePath(p);
- }
-
- void
- addBasePath(const std::string &P,
- PathType Kind =
- PathType::Unknown); // Add a canonical directory for scanning
- std::vector<std::shared_ptr<LibrarySearchPath>>
- getNextBatch(PathType Kind, size_t batchSize);
-
- bool leftToScan(PathType K) const;
- void resetToScan();
-
- bool isTrackedBasePath(StringRef P) const;
- std::vector<std::shared_ptr<LibrarySearchPath>> getAllUnits() const;
-
- SmallVector<StringRef> getSearchPaths() const {
- SmallVector<StringRef> SearchPaths;
- for (const auto &[_, SP] : LibSearchPaths)
- SearchPaths.push_back(SP->BasePath);
- return SearchPaths;
- }
-
- PathResolver &getPathResolver() const { return *LibPathResolver; }
-
- LibraryPathCache &getCache() const { return *LibPathCache; }
-
- bool hasSeenOrMark(StringRef P) const {
- return LibPathCache->hasSeenOrMark(P);
- }
-
- std::optional<std::string> resolve(StringRef P, std::error_code &ec) const {
- return LibPathResolver->resolve(P.str(), ec);
- }
-
-private:
- std::string resolveCanonical(StringRef P, std::error_code &ec) const;
- PathType classifyKind(StringRef P) const;
-
- mutable std::shared_mutex Mtx;
- std::shared_ptr<LibraryPathCache> LibPathCache;
- std::shared_ptr<PathResolver> LibPathResolver;
-
- StringMap<std::shared_ptr<LibrarySearchPath>>
- LibSearchPaths; // key: canonical path
- std::deque<StringRef> UnscannedUsr;
- std::deque<StringRef> UnscannedSys;
-};
-
-/// Loads an object file and provides access to it.
-///
-/// Owns the underlying `ObjectFile` and ensures it is valid.
-/// Any errors encountered during construction are stored and
-/// returned when attempting to access the file.
-class ObjectFileLoader {
-public:
- /// Construct an object file loader from the given path.
- explicit ObjectFileLoader(StringRef Path) {
- auto ObjOrErr = loadObjectFileWithOwnership(Path);
- if (ObjOrErr)
- Obj = std::move(*ObjOrErr);
- else {
- consumeError(std::move(Err));
- Err = ObjOrErr.takeError();
- }
- }
-
- ObjectFileLoader(const ObjectFileLoader &) = delete;
- ObjectFileLoader &operator=(const ObjectFileLoader &) = delete;
-
- ObjectFileLoader(ObjectFileLoader &&) = default;
- ObjectFileLoader &operator=(ObjectFileLoader &&) = default;
-
- /// Get the loaded object file, or return an error if loading failed.
- Expected<object::ObjectFile &> getObjectFile() {
- if (Err)
- return std::move(Err);
- return *Obj.getBinary();
- }
-
- static bool isArchitectureCompatible(const object::ObjectFile &Obj);
-
-private:
- object::OwningBinary<object::ObjectFile> Obj;
- Error Err = Error::success();
-
- static Expected<object::OwningBinary<object::ObjectFile>>
- loadObjectFileWithOwnership(StringRef FilePath);
-};
-
-/// Scans libraries, resolves dependencies, and registers them.
-class LibraryScanner {
-public:
- using ShouldScanFn = std::function<bool(StringRef)>;
-
- LibraryScanner(
- LibraryScanHelper &H, LibraryManager &LibMgr,
- ShouldScanFn ShouldScanCall = [](StringRef path) { return true; })
- : ScanHelper(H), LibMgr(LibMgr),
- ShouldScanCall(std::move(ShouldScanCall)) {}
-
- void scanNext(PathType Kind, size_t batchSize = 1);
-
- /// Dependency info for a library.
- struct LibraryDepsInfo {
- llvm::BumpPtrAllocator Alloc;
- llvm::StringSaver Saver{Alloc};
-
- SmallVector<StringRef, 2> rpath;
- SmallVector<StringRef, 2> runPath;
- SmallVector<StringRef, 4> deps;
- bool isPIE = false;
-
- void addRPath(StringRef s) { rpath.push_back(Saver.save(s)); }
-
- void addRunPath(StringRef s) { runPath.push_back(Saver.save(s)); }
-
- void addDep(StringRef s) { deps.push_back(Saver.save(s)); }
- };
-
-private:
- LibraryScanHelper &ScanHelper;
- LibraryManager &LibMgr;
- ShouldScanFn ShouldScanCall;
-
- std::optional<std::string> shouldScan(StringRef FilePath);
- Expected<LibraryDepsInfo> extractDeps(StringRef FilePath);
-
- void handleLibrary(StringRef P, PathType K, int level = 1);
-
- void scanBaseDir(std::shared_ptr<LibrarySearchPath> U);
-};
-
-using LibraryDepsInfo = LibraryScanner::LibraryDepsInfo;
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h
index ead7655..a235975 100644
--- a/llvm/include/llvm/Support/SpecialCaseList.h
+++ b/llvm/include/llvm/Support/SpecialCaseList.h
@@ -13,7 +13,10 @@
#define LLVM_SUPPORT_SPECIALCASELIST_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/RadixTree.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/GlobPattern.h"
@@ -162,6 +165,10 @@ private:
};
std::vector<GlobMatcher::Glob> Globs;
+
+ RadixTree<iterator_range<StringRef::const_iterator>,
+ SmallVector<const GlobMatcher::Glob *, 1>>
+ PrefixToGlob;
};
/// Represents a set of patterns and their line numbers