1 //===-- TypeCategoryMap.cpp ----------------------------------------*- C++
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/TypeCategoryMap.h"
12 #include "lldb/DataFormatters/FormatClasses.h"
13 #include "lldb/Utility/Log.h"
17 using namespace lldb_private;
19 TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
20 : m_map_mutex(), listener(lst), m_map(), m_active_categories() {
21 ConstString default_cs("default");
22 lldb::TypeCategoryImplSP default_sp =
23 lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
24 Add(default_cs, default_sp);
25 Enable(default_cs, First);
28 void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
29 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
35 bool TypeCategoryMap::Delete(KeyType name) {
36 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
37 MapIterator iter = m_map.find(name);
38 if (iter == m_map.end())
47 bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
48 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
50 if (!Get(category_name, category))
52 return Enable(category, pos);
55 bool TypeCategoryMap::Disable(KeyType category_name) {
56 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
58 if (!Get(category_name, category))
60 return Disable(category);
63 bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
64 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
67 if (pos == First || m_active_categories.size() == 0)
68 m_active_categories.push_front(category);
69 else if (pos == Last || pos == m_active_categories.size())
70 m_active_categories.push_back(category);
71 else if (pos < m_active_categories.size()) {
72 ActiveCategoriesList::iterator iter = m_active_categories.begin();
76 m_active_categories.insert(iter, category);
79 category->Enable(true, pos);
85 bool TypeCategoryMap::Disable(ValueSP category) {
86 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
88 m_active_categories.remove_if(delete_matching_categories(category));
95 void TypeCategoryMap::EnableAllCategories() {
96 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
97 std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP());
98 MapType::iterator iter = m_map.begin(), end = m_map.end();
99 for (; iter != end; ++iter) {
100 if (iter->second->IsEnabled())
102 auto pos = iter->second->GetLastEnabledPosition();
103 if (pos >= sorted_categories.size()) {
104 auto iter = std::find_if(
105 sorted_categories.begin(), sorted_categories.end(),
106 [](const ValueSP &sp) -> bool { return sp.get() == nullptr; });
107 pos = std::distance(sorted_categories.begin(), iter);
109 sorted_categories.at(pos) = iter->second;
111 decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
112 vend = sorted_categories.end();
113 for (; viter != vend; viter++)
115 Enable(*viter, Last);
118 void TypeCategoryMap::DisableAllCategories() {
119 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
120 for (Position p = First; !m_active_categories.empty(); p++) {
121 m_active_categories.front()->SetEnabledPosition(p);
122 Disable(m_active_categories.front());
126 void TypeCategoryMap::Clear() {
127 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
129 m_active_categories.clear();
134 bool TypeCategoryMap::Get(KeyType name, ValueSP &entry) {
135 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
136 MapIterator iter = m_map.find(name);
137 if (iter == m_map.end())
139 entry = iter->second;
143 bool TypeCategoryMap::Get(uint32_t pos, ValueSP &entry) {
144 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
145 MapIterator iter = m_map.begin();
146 MapIterator end = m_map.end();
153 entry = iter->second;
157 bool TypeCategoryMap::AnyMatches(
158 ConstString type_name, TypeCategoryImpl::FormatCategoryItems items,
159 bool only_enabled, const char **matching_category,
160 TypeCategoryImpl::FormatCategoryItems *matching_type) {
161 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
163 MapIterator pos, end = m_map.end();
164 for (pos = m_map.begin(); pos != end; pos++) {
165 if (pos->second->AnyMatches(type_name, items, only_enabled,
166 matching_category, matching_type))
172 lldb::TypeFormatImplSP
173 TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
174 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
177 ActiveCategoriesIterator begin, end = m_active_categories.end();
179 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
182 for (auto match : match_data.GetMatchesVector()) {
184 "[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
186 match.GetTypeName().GetCString(),
187 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
188 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
189 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
194 for (begin = m_active_categories.begin(); begin != end; begin++) {
195 lldb::TypeCategoryImplSP category_sp = *begin;
196 lldb::TypeFormatImplSP current_format;
198 log->Printf("[TypeCategoryMap::GetFormat] Trying to use category %s",
199 category_sp->GetName());
200 if (!category_sp->Get(match_data.GetValueObject(),
201 match_data.GetMatchesVector(), current_format,
204 return current_format;
208 "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
209 return lldb::TypeFormatImplSP();
212 lldb::TypeSummaryImplSP
213 TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
214 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
217 ActiveCategoriesIterator begin, end = m_active_categories.end();
219 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
222 for (auto match : match_data.GetMatchesVector()) {
224 "[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
226 match.GetTypeName().GetCString(),
227 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
228 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
229 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
234 for (begin = m_active_categories.begin(); begin != end; begin++) {
235 lldb::TypeCategoryImplSP category_sp = *begin;
236 lldb::TypeSummaryImplSP current_format;
238 log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s",
239 category_sp->GetName());
240 if (!category_sp->Get(match_data.GetValueObject(),
241 match_data.GetMatchesVector(), current_format,
244 return current_format;
248 "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
249 return lldb::TypeSummaryImplSP();
252 lldb::SyntheticChildrenSP
253 TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
254 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
258 ActiveCategoriesIterator begin, end = m_active_categories.end();
260 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
263 for (auto match : match_data.GetMatchesVector()) {
265 "[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
267 match.GetTypeName().GetCString(),
268 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
269 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
270 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
275 for (begin = m_active_categories.begin(); begin != end; begin++) {
276 lldb::TypeCategoryImplSP category_sp = *begin;
277 lldb::SyntheticChildrenSP current_format;
280 "[CategoryMap::GetSyntheticChildren] Trying to use category %s",
281 category_sp->GetName());
282 if (!category_sp->Get(match_data.GetValueObject(),
283 match_data.GetMatchesVector(), current_format,
286 return current_format;
289 log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
291 return lldb::SyntheticChildrenSP();
294 lldb::TypeValidatorImplSP
295 TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
296 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
299 ActiveCategoriesIterator begin, end = m_active_categories.end();
301 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
304 for (auto match : match_data.GetMatchesVector()) {
306 "[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
308 match.GetTypeName().GetCString(),
309 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
310 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
311 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
316 for (begin = m_active_categories.begin(); begin != end; begin++) {
317 lldb::TypeCategoryImplSP category_sp = *begin;
318 lldb::TypeValidatorImplSP current_format;
320 log->Printf("[CategoryMap::GetValidator] Trying to use category %s",
321 category_sp->GetName());
322 if (!category_sp->Get(match_data.GetValueObject(),
323 match_data.GetMatchesVector(), current_format,
326 return current_format;
330 "[CategoryMap::GetValidator] nothing found - returning empty SP");
331 return lldb::TypeValidatorImplSP();
334 void TypeCategoryMap::ForEach(ForEachCallback callback) {
336 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
338 // loop through enabled categories in respective order
340 ActiveCategoriesIterator begin, end = m_active_categories.end();
341 for (begin = m_active_categories.begin(); begin != end; begin++) {
342 lldb::TypeCategoryImplSP category = *begin;
343 if (!callback(category))
348 // loop through disabled categories in just any order
350 MapIterator pos, end = m_map.end();
351 for (pos = m_map.begin(); pos != end; pos++) {
352 if (pos->second->IsEnabled())
354 if (!callback(pos->second))
361 TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
362 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
364 if (index < m_map.size()) {
365 MapIterator pos, end = m_map.end();
366 for (pos = m_map.begin(); pos != end; pos++) {
373 return TypeCategoryImplSP();