]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp
Merge ^/head r320398 through r320572.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / TypeCategoryMap.cpp
1 //===-- TypeCategoryMap.cpp ----------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "lldb/DataFormatters/TypeCategoryMap.h"
12
13 #include "lldb/DataFormatters/FormatClasses.h"
14 #include "lldb/Utility/Log.h"
15
16 // C Includes
17 // C++ Includes
18 // Other libraries and framework includes
19 // Project includes
20
21 using namespace lldb;
22 using namespace lldb_private;
23
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);
31 }
32
33 void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
34   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
35   m_map[name] = entry;
36   if (listener)
37     listener->Changed();
38 }
39
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())
44     return false;
45   m_map.erase(name);
46   Disable(name);
47   if (listener)
48     listener->Changed();
49   return true;
50 }
51
52 bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
53   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
54   ValueSP category;
55   if (!Get(category_name, category))
56     return false;
57   return Enable(category, pos);
58 }
59
60 bool TypeCategoryMap::Disable(KeyType category_name) {
61   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
62   ValueSP category;
63   if (!Get(category_name, category))
64     return false;
65   return Disable(category);
66 }
67
68 bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
69   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
70   if (category.get()) {
71     Position pos_w = pos;
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();
78       while (pos_w) {
79         pos_w--, iter++;
80       }
81       m_active_categories.insert(iter, category);
82     } else
83       return false;
84     category->Enable(true, pos);
85     return true;
86   }
87   return false;
88 }
89
90 bool TypeCategoryMap::Disable(ValueSP category) {
91   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
92   if (category.get()) {
93     m_active_categories.remove_if(delete_matching_categories(category));
94     category->Disable();
95     return true;
96   }
97   return false;
98 }
99
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())
106       continue;
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);
113     }
114     sorted_categories.at(pos) = iter->second;
115   }
116   decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
117                                         vend = sorted_categories.end();
118   for (; viter != vend; viter++)
119     if (viter->get())
120       Enable(*viter, Last);
121 }
122
123 void TypeCategoryMap::DisableAllCategories() {
124   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
125   Position p = First;
126   for (; false == m_active_categories.empty(); p++) {
127     m_active_categories.front()->SetEnabledPosition(p);
128     Disable(m_active_categories.front());
129   }
130 }
131
132 void TypeCategoryMap::Clear() {
133   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
134   m_map.clear();
135   m_active_categories.clear();
136   if (listener)
137     listener->Changed();
138 }
139
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())
144     return false;
145   entry = iter->second;
146   return true;
147 }
148
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();
153   while (pos > 0) {
154     iter++;
155     pos--;
156     if (iter == end)
157       return false;
158   }
159   entry = iter->second;
160   return false;
161 }
162
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);
168
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))
173       return true;
174   }
175   return false;
176 }
177
178 lldb::TypeFormatImplSP
179 TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
180   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
181
182   uint32_t reason_why;
183   ActiveCategoriesIterator begin, end = m_active_categories.end();
184
185   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
186
187   if (log) {
188     for (auto match : match_data.GetMatchesVector()) {
189       log->Printf(
190           "[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
191           "%" PRIu32,
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",
196           match.GetReason());
197     }
198   }
199
200   for (begin = m_active_categories.begin(); begin != end; begin++) {
201     lldb::TypeCategoryImplSP category_sp = *begin;
202     lldb::TypeFormatImplSP current_format;
203     if (log)
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,
208                           &reason_why))
209       continue;
210     return current_format;
211   }
212   if (log)
213     log->Printf(
214         "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
215   return lldb::TypeFormatImplSP();
216 }
217
218 lldb::TypeSummaryImplSP
219 TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
220   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
221
222   uint32_t reason_why;
223   ActiveCategoriesIterator begin, end = m_active_categories.end();
224
225   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
226
227   if (log) {
228     for (auto match : match_data.GetMatchesVector()) {
229       log->Printf(
230           "[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
231           "reason = %" PRIu32,
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",
236           match.GetReason());
237     }
238   }
239
240   for (begin = m_active_categories.begin(); begin != end; begin++) {
241     lldb::TypeCategoryImplSP category_sp = *begin;
242     lldb::TypeSummaryImplSP current_format;
243     if (log)
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,
248                           &reason_why))
249       continue;
250     return current_format;
251   }
252   if (log)
253     log->Printf(
254         "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
255   return lldb::TypeSummaryImplSP();
256 }
257
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);
262
263   uint32_t reason_why;
264
265   ActiveCategoriesIterator begin, end = m_active_categories.end();
266
267   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
268
269   if (log) {
270     for (auto match : match_data.GetMatchesVector()) {
271       log->Printf(
272           "[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
273           "reason = %" PRIu32,
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",
278           match.GetReason());
279     }
280   }
281
282   for (begin = m_active_categories.begin(); begin != end; begin++) {
283     lldb::TypeCategoryImplSP category_sp = *begin;
284     lldb::SyntheticChildrenSP current_format;
285     if (log)
286       log->Printf(
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,
291                           &reason_why))
292       continue;
293     return current_format;
294   }
295   if (log)
296     log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
297                 "empty SP");
298   return lldb::SyntheticChildrenSP();
299 }
300 #endif
301
302 lldb::TypeValidatorImplSP
303 TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
304   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
305
306   uint32_t reason_why;
307   ActiveCategoriesIterator begin, end = m_active_categories.end();
308
309   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
310
311   if (log) {
312     for (auto match : match_data.GetMatchesVector()) {
313       log->Printf(
314           "[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
315           "%" PRIu32,
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",
320           match.GetReason());
321     }
322   }
323
324   for (begin = m_active_categories.begin(); begin != end; begin++) {
325     lldb::TypeCategoryImplSP category_sp = *begin;
326     lldb::TypeValidatorImplSP current_format;
327     if (log)
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,
332                           &reason_why))
333       continue;
334     return current_format;
335   }
336   if (log)
337     log->Printf(
338         "[CategoryMap::GetValidator] nothing found - returning empty SP");
339   return lldb::TypeValidatorImplSP();
340 }
341
342 void TypeCategoryMap::ForEach(ForEachCallback callback) {
343   if (callback) {
344     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
345
346     // loop through enabled categories in respective order
347     {
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))
352           break;
353       }
354     }
355
356     // loop through disabled categories in just any order
357     {
358       MapIterator pos, end = m_map.end();
359       for (pos = m_map.begin(); pos != end; pos++) {
360         if (pos->second->IsEnabled())
361           continue;
362         if (!callback(pos->second))
363           break;
364       }
365     }
366   }
367 }
368
369 TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
370   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
371
372   if (index < m_map.size()) {
373     MapIterator pos, end = m_map.end();
374     for (pos = m_map.begin(); pos != end; pos++) {
375       if (index == 0)
376         return pos->second;
377       index--;
378     }
379   }
380
381   return TypeCategoryImplSP();
382 }