LLDB mainline
TypeCategoryMap.cpp
Go to the documentation of this file.
1//===-- TypeCategoryMap.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
10
13#include "lldb/Utility/Log.h"
14
15using namespace lldb;
16using namespace lldb_private;
17
20 constexpr llvm::StringRef default_category_name("default");
21 lldb::TypeCategoryImplSP default_sp = std::make_shared<TypeCategoryImpl>(
22 listener, ConstString(default_category_name));
23 Add(default_category_name, default_sp);
24 Enable(default_category_name, First);
25}
26
27void TypeCategoryMap::Add(llvm::StringRef name,
28 const TypeCategoryImplSP &entry) {
29 {
30 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
31 m_map[name] = entry;
32 }
33 // Release the mutex to avoid a potential deadlock between
34 // TypeCategoryMap::m_map_mutex and
35 // FormatManager::m_language_categories_mutex which can be acquired in
36 // reverse order when calling FormatManager::Changed.
37 if (listener)
38 listener->Changed();
39}
40
41bool TypeCategoryMap::Delete(llvm::StringRef name) {
42 {
43 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
44 MapIterator iter = m_map.find(name);
45 if (iter == m_map.end())
46 return false;
47 m_map.erase(name);
48 Disable(name);
49 }
50 // Release the mutex to avoid a potential deadlock between
51 // TypeCategoryMap::m_map_mutex and
52 // FormatManager::m_language_categories_mutex which can be acquired in
53 // reverse order when calling FormatManager::Changed.
54 if (listener)
55 listener->Changed();
56 return true;
57}
58
59bool TypeCategoryMap::Enable(llvm::StringRef category_name, Position pos) {
60 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
61 TypeCategoryImplSP category;
62 if (!Get(category_name, category))
63 return false;
64 return Enable(category, pos);
65}
66
67bool TypeCategoryMap::Disable(llvm::StringRef category_name) {
68 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
69 TypeCategoryImplSP category;
70 if (!Get(category_name, category))
71 return false;
72 return Disable(category);
73}
74
76 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
77 if (category.get()) {
78 Position pos_w = pos;
79 if (pos == First || m_active_categories.size() == 0)
80 m_active_categories.push_front(category);
81 else if (pos == Last || pos == m_active_categories.size())
82 m_active_categories.push_back(category);
83 else if (pos < m_active_categories.size()) {
84 ActiveCategoriesList::iterator iter = m_active_categories.begin();
85 while (pos_w) {
86 pos_w--, iter++;
87 }
88 m_active_categories.insert(iter, category);
89 } else
90 return false;
91 category->Enable(true, pos);
92 return true;
93 }
94 return false;
95}
96
98 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
99 if (category.get()) {
101 category->Disable();
102 return true;
103 }
104 return false;
105}
106
108 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
109 std::vector<TypeCategoryImplSP> sorted_categories(m_map.size(), TypeCategoryImplSP());
110 MapType::iterator iter = m_map.begin(), end = m_map.end();
111 for (; iter != end; ++iter) {
112 if (iter->second->IsEnabled())
113 continue;
114 auto pos = iter->second->GetLastEnabledPosition();
115 if (pos >= sorted_categories.size()) {
116 auto iter = llvm::find_if(sorted_categories,
117 [](const TypeCategoryImplSP &sp) -> bool {
118 return sp.get() == nullptr;
119 });
120 pos = std::distance(sorted_categories.begin(), iter);
121 }
122 sorted_categories.at(pos) = iter->second;
123 }
124 decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
125 vend = sorted_categories.end();
126 for (; viter != vend; viter++)
127 if (*viter)
128 Enable(*viter, Last);
129}
130
132 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
133 for (Position p = First; !m_active_categories.empty(); p++) {
134 m_active_categories.front()->SetEnabledPosition(p);
136 }
137}
138
140 {
141 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
142 m_map.clear();
143 m_active_categories.clear();
144 }
145 // Release the mutex to avoid a potential deadlock between
146 // TypeCategoryMap::m_map_mutex and
147 // FormatManager::m_language_categories_mutex which can be acquired in
148 // reverse order when calling FormatManager::Changed.
149 if (listener)
150 listener->Changed();
151}
152
153bool TypeCategoryMap::Get(llvm::StringRef name, TypeCategoryImplSP &entry) {
154 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
155 MapIterator iter = m_map.find(name);
156 if (iter == m_map.end())
157 return false;
158 entry = iter->second;
159 return true;
160}
161
162template <typename ImplSP>
163void TypeCategoryMap::Get(FormattersMatchData &match_data, ImplSP &retval) {
164 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
165
167
169
170 if (log) {
171 for (auto match : match_data.GetMatchesVector()) {
172 LLDB_LOGF(
173 log, "[%s] candidate match = %s %s %s %s ptr-stripped-depth=%u",
174 __FUNCTION__, match.GetTypeName().GetCString(),
175 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
176 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
177 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
178 match.GetPtrStrippedDepth());
179 }
180 }
181
182 for (begin = m_active_categories.begin(); begin != end; begin++) {
183 lldb::TypeCategoryImplSP category_sp = *begin;
184 ImplSP current_format;
185 LLDB_LOGF(log, "[%s] Trying to use category %s", __FUNCTION__,
186 category_sp->GetName());
187 if (!category_sp->Get(
189 match_data.GetMatchesVector(), current_format))
190 continue;
191
192 retval = std::move(current_format);
193 return;
194 }
195 LLDB_LOGF(log, "[%s] nothing found - returning empty SP", __FUNCTION__);
196}
197
198/// Explicit instantiations for the three types.
199/// \{
200template void
202 lldb::TypeFormatImplSP &retval);
203template void
208/// \}
209
211 if (callback) {
212 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
213
214 // loop through enabled categories in respective order
215 {
217 for (begin = m_active_categories.begin(); begin != end; begin++) {
218 lldb::TypeCategoryImplSP category = *begin;
219 if (!callback(category))
220 break;
221 }
222 }
223
224 // loop through disabled categories in just any order
225 {
226 MapIterator pos, end = m_map.end();
227 for (pos = m_map.begin(); pos != end; pos++) {
228 if (pos->second->IsEnabled())
229 continue;
230 if (!callback(pos->second))
231 break;
232 }
233 }
234 }
235}
236
238 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
239
240 if (index < m_map.size()) {
241 MapIterator pos, end = m_map.end();
242 for (pos = m_map.begin(); pos != end; pos++) {
243 if (index == 0)
244 return pos->second;
245 index--;
246 }
247 }
248
249 return TypeCategoryImplSP();
250}
#define LLDB_LOGF(log,...)
Definition Log.h:390
A uniqued constant string class.
Definition ConstString.h:40
FormattersMatchVector GetMatchesVector()
bool Enable(llvm::StringRef category_name, Position pos=Default)
bool Disable(llvm::StringRef category_name)
std::function< bool(const lldb::TypeCategoryImplSP &)> ForEachCallback
static const Position Last
lldb::TypeCategoryImplSP GetAtIndex(uint32_t)
std::recursive_mutex m_map_mutex
bool Delete(llvm::StringRef name)
ActiveCategoriesList m_active_categories
ActiveCategoriesList::iterator ActiveCategoriesIterator
bool Get(llvm::StringRef name, lldb::TypeCategoryImplSP &entry)
IFormatChangeListener * listener
void Add(llvm::StringRef name, const lldb::TypeCategoryImplSP &entry)
static const Position First
void ForEach(ForEachCallback callback)
TypeCategoryMap(IFormatChangeListener *lst)
lldb::LanguageType GetObjectRuntimeLanguage()
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:339
std::shared_ptr< lldb_private::TypeSummaryImpl > TypeSummaryImplSP
std::shared_ptr< lldb_private::TypeFormatImpl > TypeFormatImplSP
std::shared_ptr< lldb_private::SyntheticChildren > SyntheticChildrenSP
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP