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 // Other libraries and framework includes
22 using namespace lldb_private;
24 TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
25 : m_map_mutex(), listener(lst), m_map(), m_active_categories() {
26 ConstString default_cs("default");
27 lldb::TypeCategoryImplSP default_sp =
28 lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
29 Add(default_cs, default_sp);
30 Enable(default_cs, First);
33 void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
34 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
40 bool TypeCategoryMap::Delete(KeyType name) {
41 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
42 MapIterator iter = m_map.find(name);
43 if (iter == m_map.end())
52 bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
53 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
55 if (!Get(category_name, category))
57 return Enable(category, pos);
60 bool TypeCategoryMap::Disable(KeyType category_name) {
61 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
63 if (!Get(category_name, category))
65 return Disable(category);
68 bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
69 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
72 if (pos == First || m_active_categories.size() == 0)
73 m_active_categories.push_front(category);
74 else if (pos == Last || pos == m_active_categories.size())
75 m_active_categories.push_back(category);
76 else if (pos < m_active_categories.size()) {
77 ActiveCategoriesList::iterator iter = m_active_categories.begin();
81 m_active_categories.insert(iter, category);
84 category->Enable(true, pos);
90 bool TypeCategoryMap::Disable(ValueSP category) {
91 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
93 m_active_categories.remove_if(delete_matching_categories(category));
100 void TypeCategoryMap::EnableAllCategories() {
101 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
102 std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP());
103 MapType::iterator iter = m_map.begin(), end = m_map.end();
104 for (; iter != end; ++iter) {
105 if (iter->second->IsEnabled())
107 auto pos = iter->second->GetLastEnabledPosition();
108 if (pos >= sorted_categories.size()) {
109 auto iter = std::find_if(
110 sorted_categories.begin(), sorted_categories.end(),
111 [](const ValueSP &sp) -> bool { return sp.get() == nullptr; });
112 pos = std::distance(sorted_categories.begin(), iter);
114 sorted_categories.at(pos) = iter->second;
116 decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
117 vend = sorted_categories.end();
118 for (; viter != vend; viter++)
120 Enable(*viter, Last);
123 void TypeCategoryMap::DisableAllCategories() {
124 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
126 for (; false == m_active_categories.empty(); p++) {
127 m_active_categories.front()->SetEnabledPosition(p);
128 Disable(m_active_categories.front());
132 void TypeCategoryMap::Clear() {
133 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
135 m_active_categories.clear();
140 bool TypeCategoryMap::Get(KeyType name, ValueSP &entry) {
141 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
142 MapIterator iter = m_map.find(name);
143 if (iter == m_map.end())
145 entry = iter->second;
149 bool TypeCategoryMap::Get(uint32_t pos, ValueSP &entry) {
150 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
151 MapIterator iter = m_map.begin();
152 MapIterator end = m_map.end();
159 entry = iter->second;
163 bool TypeCategoryMap::AnyMatches(
164 ConstString type_name, TypeCategoryImpl::FormatCategoryItems items,
165 bool only_enabled, const char **matching_category,
166 TypeCategoryImpl::FormatCategoryItems *matching_type) {
167 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
169 MapIterator pos, end = m_map.end();
170 for (pos = m_map.begin(); pos != end; pos++) {
171 if (pos->second->AnyMatches(type_name, items, only_enabled,
172 matching_category, matching_type))
178 lldb::TypeFormatImplSP
179 TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
180 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
183 ActiveCategoriesIterator begin, end = m_active_categories.end();
185 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
188 for (auto match : match_data.GetMatchesVector()) {
190 "[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
192 match.GetTypeName().GetCString(),
193 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
194 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
195 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
200 for (begin = m_active_categories.begin(); begin != end; begin++) {
201 lldb::TypeCategoryImplSP category_sp = *begin;
202 lldb::TypeFormatImplSP current_format;
204 log->Printf("[TypeCategoryMap::GetFormat] Trying to use category %s",
205 category_sp->GetName());
206 if (!category_sp->Get(match_data.GetValueObject(),
207 match_data.GetMatchesVector(), current_format,
210 return current_format;
214 "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
215 return lldb::TypeFormatImplSP();
218 lldb::TypeSummaryImplSP
219 TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
220 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
223 ActiveCategoriesIterator begin, end = m_active_categories.end();
225 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
228 for (auto match : match_data.GetMatchesVector()) {
230 "[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
232 match.GetTypeName().GetCString(),
233 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
234 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
235 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
240 for (begin = m_active_categories.begin(); begin != end; begin++) {
241 lldb::TypeCategoryImplSP category_sp = *begin;
242 lldb::TypeSummaryImplSP current_format;
244 log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s",
245 category_sp->GetName());
246 if (!category_sp->Get(match_data.GetValueObject(),
247 match_data.GetMatchesVector(), current_format,
250 return current_format;
254 "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
255 return lldb::TypeSummaryImplSP();
258 #ifndef LLDB_DISABLE_PYTHON
259 lldb::SyntheticChildrenSP
260 TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
261 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
265 ActiveCategoriesIterator begin, end = m_active_categories.end();
267 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
270 for (auto match : match_data.GetMatchesVector()) {
272 "[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
274 match.GetTypeName().GetCString(),
275 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
276 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
277 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
282 for (begin = m_active_categories.begin(); begin != end; begin++) {
283 lldb::TypeCategoryImplSP category_sp = *begin;
284 lldb::SyntheticChildrenSP current_format;
287 "[CategoryMap::GetSyntheticChildren] Trying to use category %s",
288 category_sp->GetName());
289 if (!category_sp->Get(match_data.GetValueObject(),
290 match_data.GetMatchesVector(), current_format,
293 return current_format;
296 log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
298 return lldb::SyntheticChildrenSP();
302 lldb::TypeValidatorImplSP
303 TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
304 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
307 ActiveCategoriesIterator begin, end = m_active_categories.end();
309 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
312 for (auto match : match_data.GetMatchesVector()) {
314 "[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
316 match.GetTypeName().GetCString(),
317 match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
318 match.DidStripReference() ? "strip-reference" : "no-strip-reference",
319 match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
324 for (begin = m_active_categories.begin(); begin != end; begin++) {
325 lldb::TypeCategoryImplSP category_sp = *begin;
326 lldb::TypeValidatorImplSP current_format;
328 log->Printf("[CategoryMap::GetValidator] Trying to use category %s",
329 category_sp->GetName());
330 if (!category_sp->Get(match_data.GetValueObject(),
331 match_data.GetMatchesVector(), current_format,
334 return current_format;
338 "[CategoryMap::GetValidator] nothing found - returning empty SP");
339 return lldb::TypeValidatorImplSP();
342 void TypeCategoryMap::ForEach(ForEachCallback callback) {
344 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
346 // loop through enabled categories in respective order
348 ActiveCategoriesIterator begin, end = m_active_categories.end();
349 for (begin = m_active_categories.begin(); begin != end; begin++) {
350 lldb::TypeCategoryImplSP category = *begin;
351 if (!callback(category))
356 // loop through disabled categories in just any order
358 MapIterator pos, end = m_map.end();
359 for (pos = m_map.begin(); pos != end; pos++) {
360 if (pos->second->IsEnabled())
362 if (!callback(pos->second))
369 TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
370 std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
372 if (index < m_map.size()) {
373 MapIterator pos, end = m_map.end();
374 for (pos = m_map.begin(); pos != end; pos++) {
381 return TypeCategoryImplSP();