1 //===-- TypeCategoryMap.cpp ----------------------------------------*- C++
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "lldb/DataFormatters/TypeCategoryMap.h"
13 #include "lldb/DataFormatters/FormatClasses.h"
14 #include "lldb/Utility/Log.h"
18 using namespace lldb_private;
20 TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
21 : m_map_mutex(), listener(lst), m_map(), m_active_categories() {
22 ConstString default_cs("default");
23 lldb::TypeCategoryImplSP default_sp =
24 lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
25 Add(default_cs, default_sp);
26 Enable(default_cs, First);
29 void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
30 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
36 bool TypeCategoryMap::Delete(KeyType name) {
37 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
38 MapIterator iter = m_map.find(name);
39 if (iter == m_map.end())
48 bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
49 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
51 if (!Get(category_name, category))
53 return Enable(category, pos);
56 bool TypeCategoryMap::Disable(KeyType category_name) {
57 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
59 if (!Get(category_name, category))
61 return Disable(category);
64 bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
65 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
68 if (pos == First || m_active_categories.size() == 0)
69 m_active_categories.push_front(category);
70 else if (pos == Last || pos == m_active_categories.size())
71 m_active_categories.push_back(category);
72 else if (pos < m_active_categories.size()) {
73 ActiveCategoriesList::iterator iter = m_active_categories.begin();
77 m_active_categories.insert(iter, category);
80 category->Enable(true, pos);
86 bool TypeCategoryMap::Disable(ValueSP category) {
87 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
89 m_active_categories.remove_if(delete_matching_categories(category));
96 void TypeCategoryMap::EnableAllCategories() {
97 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
98 std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP());
99 MapType::iterator iter = m_map.begin(), end = m_map.end();
100 for (; iter != end; ++iter) {
101 if (iter->second->IsEnabled())
103 auto pos = iter->second->GetLastEnabledPosition();
104 if (pos >= sorted_categories.size()) {
105 auto iter = std::find_if(
106 sorted_categories.begin(), sorted_categories.end(),
107 [](const ValueSP &sp) -> bool { return sp.get() == nullptr; });
108 pos = std::distance(sorted_categories.begin(), iter);
110 sorted_categories.at(pos) = iter->second;
112 decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
113 vend = sorted_categories.end();
114 for (; viter != vend; viter++)
116 Enable(*viter, Last);
119 void TypeCategoryMap::DisableAllCategories() {
120 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
121 for (Position p = First; !m_active_categories.empty(); p++) {
122 m_active_categories.front()->SetEnabledPosition(p);
123 Disable(m_active_categories.front());
127 void TypeCategoryMap::Clear() {
128 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
130 m_active_categories.clear();
135 bool TypeCategoryMap::Get(KeyType name, ValueSP &entry) {
136 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
137 MapIterator iter = m_map.find(name);
138 if (iter == m_map.end())
140 entry = iter->second;
144 bool TypeCategoryMap::Get(uint32_t pos, ValueSP &entry) {
145 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
146 MapIterator iter = m_map.begin();
147 MapIterator end = m_map.end();
154 entry = iter->second;
158 bool TypeCategoryMap::AnyMatches(
159 ConstString type_name, TypeCategoryImpl::FormatCategoryItems items,
160 bool only_enabled, const char **matching_category,
161 TypeCategoryImpl::FormatCategoryItems *matching_type) {
162 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
164 MapIterator pos, end = m_map.end();
165 for (pos = m_map.begin(); pos != end; pos++) {
166 if (pos->second->AnyMatches(type_name, items, only_enabled,
167 matching_category, matching_type))
173 lldb::TypeFormatImplSP
174 TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
175 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
178 ActiveCategoriesIterator begin, end = m_active_categories.end();
180 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
183 for (auto match : match_data.GetMatchesVector()) {
185 "[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
187 match.GetTypeName().GetCString(),
188 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
189 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
190 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
195 for (begin = m_active_categories.begin(); begin != end; begin++) {
196 lldb::TypeCategoryImplSP category_sp = *begin;
197 lldb::TypeFormatImplSP current_format;
199 log->Printf("[TypeCategoryMap::GetFormat] Trying to use category %s",
200 category_sp->GetName());
201 if (!category_sp->Get(match_data.GetValueObject(),
202 match_data.GetMatchesVector(), current_format,
205 return current_format;
209 "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
210 return lldb::TypeFormatImplSP();
213 lldb::TypeSummaryImplSP
214 TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
215 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
218 ActiveCategoriesIterator begin, end = m_active_categories.end();
220 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
223 for (auto match : match_data.GetMatchesVector()) {
225 "[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
227 match.GetTypeName().GetCString(),
228 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
229 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
230 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
235 for (begin = m_active_categories.begin(); begin != end; begin++) {
236 lldb::TypeCategoryImplSP category_sp = *begin;
237 lldb::TypeSummaryImplSP current_format;
239 log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s",
240 category_sp->GetName());
241 if (!category_sp->Get(match_data.GetValueObject(),
242 match_data.GetMatchesVector(), current_format,
245 return current_format;
249 "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
250 return lldb::TypeSummaryImplSP();
253 #ifndef LLDB_DISABLE_PYTHON
254 lldb::SyntheticChildrenSP
255 TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
256 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
260 ActiveCategoriesIterator begin, end = m_active_categories.end();
262 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
265 for (auto match : match_data.GetMatchesVector()) {
267 "[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
269 match.GetTypeName().GetCString(),
270 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
271 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
272 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
277 for (begin = m_active_categories.begin(); begin != end; begin++) {
278 lldb::TypeCategoryImplSP category_sp = *begin;
279 lldb::SyntheticChildrenSP current_format;
282 "[CategoryMap::GetSyntheticChildren] Trying to use category %s",
283 category_sp->GetName());
284 if (!category_sp->Get(match_data.GetValueObject(),
285 match_data.GetMatchesVector(), current_format,
288 return current_format;
291 log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
293 return lldb::SyntheticChildrenSP();
297 lldb::TypeValidatorImplSP
298 TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
299 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
302 ActiveCategoriesIterator begin, end = m_active_categories.end();
304 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
307 for (auto match : match_data.GetMatchesVector()) {
309 "[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
311 match.GetTypeName().GetCString(),
312 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
313 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
314 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
319 for (begin = m_active_categories.begin(); begin != end; begin++) {
320 lldb::TypeCategoryImplSP category_sp = *begin;
321 lldb::TypeValidatorImplSP current_format;
323 log->Printf("[CategoryMap::GetValidator] Trying to use category %s",
324 category_sp->GetName());
325 if (!category_sp->Get(match_data.GetValueObject(),
326 match_data.GetMatchesVector(), current_format,
329 return current_format;
333 "[CategoryMap::GetValidator] nothing found - returning empty SP");
334 return lldb::TypeValidatorImplSP();
337 void TypeCategoryMap::ForEach(ForEachCallback callback) {
339 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
341 // loop through enabled categories in respective order
343 ActiveCategoriesIterator begin, end = m_active_categories.end();
344 for (begin = m_active_categories.begin(); begin != end; begin++) {
345 lldb::TypeCategoryImplSP category = *begin;
346 if (!callback(category))
351 // loop through disabled categories in just any order
353 MapIterator pos, end = m_map.end();
354 for (pos = m_map.begin(); pos != end; pos++) {
355 if (pos->second->IsEnabled())
357 if (!callback(pos->second))
364 TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
365 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
367 if (index < m_map.size()) {
368 MapIterator pos, end = m_map.end();
369 for (pos = m_map.begin(); pos != end; pos++) {
376 return TypeCategoryImplSP();