| 1 | //===-- TypeMap.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 | #include <vector> |
| 10 | |
| 11 | #include "llvm/Support/FormattedStream.h" |
| 12 | #include "llvm/Support/raw_ostream.h" |
| 13 | |
| 14 | #include "lldb/Symbol/SymbolFile.h" |
| 15 | #include "lldb/Symbol/SymbolVendor.h" |
| 16 | #include "lldb/Symbol/Type.h" |
| 17 | #include "lldb/Symbol/TypeMap.h" |
| 18 | |
| 19 | using namespace lldb; |
| 20 | using namespace lldb_private; |
| 21 | |
| 22 | TypeMap::TypeMap() : m_types() {} |
| 23 | |
| 24 | // Destructor |
| 25 | TypeMap::~TypeMap() = default; |
| 26 | |
| 27 | void TypeMap::Insert(const TypeSP &type_sp) { |
| 28 | // Just push each type on the back for now. We will worry about uniquing |
| 29 | // later |
| 30 | if (type_sp) |
| 31 | m_types.insert(x: std::make_pair(x: type_sp->GetID(), y: type_sp)); |
| 32 | } |
| 33 | |
| 34 | bool TypeMap::InsertUnique(const TypeSP &type_sp) { |
| 35 | if (type_sp) { |
| 36 | user_id_t type_uid = type_sp->GetID(); |
| 37 | iterator pos, end = m_types.end(); |
| 38 | |
| 39 | for (pos = m_types.find(x: type_uid); |
| 40 | pos != end && pos->second->GetID() == type_uid; ++pos) { |
| 41 | if (pos->second.get() == type_sp.get()) |
| 42 | return false; |
| 43 | } |
| 44 | Insert(type_sp); |
| 45 | } |
| 46 | return true; |
| 47 | } |
| 48 | |
| 49 | // Find a base type by its unique ID. |
| 50 | // TypeSP |
| 51 | // TypeMap::FindType(lldb::user_id_t uid) |
| 52 | //{ |
| 53 | // iterator pos = m_types.find(uid); |
| 54 | // if (pos != m_types.end()) |
| 55 | // return pos->second; |
| 56 | // return TypeSP(); |
| 57 | //} |
| 58 | |
| 59 | // Find a type by name. |
| 60 | // TypeMap |
| 61 | // TypeMap::FindTypes (ConstString name) |
| 62 | //{ |
| 63 | // // Do we ever need to make a lookup by name map? Here we are doing |
| 64 | // // a linear search which isn't going to be fast. |
| 65 | // TypeMap types(m_ast.getTargetInfo()->getTriple().getTriple().c_str()); |
| 66 | // iterator pos, end; |
| 67 | // for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) |
| 68 | // if (pos->second->GetName() == name) |
| 69 | // types.Insert (pos->second); |
| 70 | // return types; |
| 71 | //} |
| 72 | |
| 73 | void TypeMap::Clear() { m_types.clear(); } |
| 74 | |
| 75 | uint32_t TypeMap::GetSize() const { return m_types.size(); } |
| 76 | |
| 77 | bool TypeMap::Empty() const { return m_types.empty(); } |
| 78 | |
| 79 | // GetTypeAtIndex isn't used a lot for large type lists, currently only for |
| 80 | // type lists that are returned for "image dump -t TYPENAME" commands and other |
| 81 | // simple symbol queries that grab the first result... |
| 82 | |
| 83 | TypeSP TypeMap::GetTypeAtIndex(uint32_t idx) { |
| 84 | iterator pos, end; |
| 85 | uint32_t i = idx; |
| 86 | for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { |
| 87 | if (i == 0) |
| 88 | return pos->second; |
| 89 | --i; |
| 90 | } |
| 91 | return TypeSP(); |
| 92 | } |
| 93 | |
| 94 | lldb::TypeSP TypeMap::FirstType() const { |
| 95 | if (m_types.empty()) |
| 96 | return TypeSP(); |
| 97 | return m_types.begin()->second; |
| 98 | } |
| 99 | |
| 100 | void TypeMap::ForEach( |
| 101 | std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const { |
| 102 | for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { |
| 103 | if (!callback(pos->second)) |
| 104 | break; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | void TypeMap::ForEach( |
| 109 | std::function<bool(lldb::TypeSP &type_sp)> const &callback) { |
| 110 | for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { |
| 111 | if (!callback(pos->second)) |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | bool TypeMap::Remove(const lldb::TypeSP &type_sp) { |
| 117 | if (type_sp) { |
| 118 | lldb::user_id_t uid = type_sp->GetID(); |
| 119 | for (iterator pos = m_types.find(x: uid), end = m_types.end(); |
| 120 | pos != end && pos->first == uid; ++pos) { |
| 121 | if (pos->second == type_sp) { |
| 122 | m_types.erase(position: pos); |
| 123 | return true; |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | return false; |
| 128 | } |
| 129 | |
| 130 | void TypeMap::Dump(Stream *s, bool show_context, |
| 131 | lldb::DescriptionLevel level) const { |
| 132 | for (const auto &pair : m_types) |
| 133 | pair.second->Dump(s, show_context, level); |
| 134 | } |
| 135 | |