]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[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
17 using namespace lldb;
18 using namespace lldb_private;
19
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);
27 }
28
29 void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
30   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
31   m_map[name] = entry;
32   if (listener)
33     listener->Changed();
34 }
35
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())
40     return false;
41   m_map.erase(name);
42   Disable(name);
43   if (listener)
44     listener->Changed();
45   return true;
46 }
47
48 bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
49   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
50   ValueSP category;
51   if (!Get(category_name, category))
52     return false;
53   return Enable(category, pos);
54 }
55
56 bool TypeCategoryMap::Disable(KeyType category_name) {
57   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
58   ValueSP category;
59   if (!Get(category_name, category))
60     return false;
61   return Disable(category);
62 }
63
64 bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
65   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
66   if (category.get()) {
67     Position pos_w = pos;
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();
74       while (pos_w) {
75         pos_w--, iter++;
76       }
77       m_active_categories.insert(iter, category);
78     } else
79       return false;
80     category->Enable(true, pos);
81     return true;
82   }
83   return false;
84 }
85
86 bool TypeCategoryMap::Disable(ValueSP category) {
87   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
88   if (category.get()) {
89     m_active_categories.remove_if(delete_matching_categories(category));
90     category->Disable();
91     return true;
92   }
93   return false;
94 }
95
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())
102       continue;
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);
109     }
110     sorted_categories.at(pos) = iter->second;
111   }
112   decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
113                                         vend = sorted_categories.end();
114   for (; viter != vend; viter++)
115     if (viter->get())
116       Enable(*viter, Last);
117 }
118
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());
124   }
125 }
126
127 void TypeCategoryMap::Clear() {
128   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
129   m_map.clear();
130   m_active_categories.clear();
131   if (listener)
132     listener->Changed();
133 }
134
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())
139     return false;
140   entry = iter->second;
141   return true;
142 }
143
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();
148   while (pos > 0) {
149     iter++;
150     pos--;
151     if (iter == end)
152       return false;
153   }
154   entry = iter->second;
155   return false;
156 }
157
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);
163
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))
168       return true;
169   }
170   return false;
171 }
172
173 lldb::TypeFormatImplSP
174 TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
175   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
176
177   uint32_t reason_why;
178   ActiveCategoriesIterator begin, end = m_active_categories.end();
179
180   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
181
182   if (log) {
183     for (auto match : match_data.GetMatchesVector()) {
184       log->Printf(
185           "[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
186           "%" PRIu32,
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",
191           match.GetReason());
192     }
193   }
194
195   for (begin = m_active_categories.begin(); begin != end; begin++) {
196     lldb::TypeCategoryImplSP category_sp = *begin;
197     lldb::TypeFormatImplSP current_format;
198     if (log)
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,
203                           &reason_why))
204       continue;
205     return current_format;
206   }
207   if (log)
208     log->Printf(
209         "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
210   return lldb::TypeFormatImplSP();
211 }
212
213 lldb::TypeSummaryImplSP
214 TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
215   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
216
217   uint32_t reason_why;
218   ActiveCategoriesIterator begin, end = m_active_categories.end();
219
220   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
221
222   if (log) {
223     for (auto match : match_data.GetMatchesVector()) {
224       log->Printf(
225           "[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
226           "reason = %" PRIu32,
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",
231           match.GetReason());
232     }
233   }
234
235   for (begin = m_active_categories.begin(); begin != end; begin++) {
236     lldb::TypeCategoryImplSP category_sp = *begin;
237     lldb::TypeSummaryImplSP current_format;
238     if (log)
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,
243                           &reason_why))
244       continue;
245     return current_format;
246   }
247   if (log)
248     log->Printf(
249         "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
250   return lldb::TypeSummaryImplSP();
251 }
252
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);
257
258   uint32_t reason_why;
259
260   ActiveCategoriesIterator begin, end = m_active_categories.end();
261
262   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
263
264   if (log) {
265     for (auto match : match_data.GetMatchesVector()) {
266       log->Printf(
267           "[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
268           "reason = %" PRIu32,
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",
273           match.GetReason());
274     }
275   }
276
277   for (begin = m_active_categories.begin(); begin != end; begin++) {
278     lldb::TypeCategoryImplSP category_sp = *begin;
279     lldb::SyntheticChildrenSP current_format;
280     if (log)
281       log->Printf(
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,
286                           &reason_why))
287       continue;
288     return current_format;
289   }
290   if (log)
291     log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
292                 "empty SP");
293   return lldb::SyntheticChildrenSP();
294 }
295 #endif
296
297 lldb::TypeValidatorImplSP
298 TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
299   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
300
301   uint32_t reason_why;
302   ActiveCategoriesIterator begin, end = m_active_categories.end();
303
304   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
305
306   if (log) {
307     for (auto match : match_data.GetMatchesVector()) {
308       log->Printf(
309           "[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
310           "%" PRIu32,
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",
315           match.GetReason());
316     }
317   }
318
319   for (begin = m_active_categories.begin(); begin != end; begin++) {
320     lldb::TypeCategoryImplSP category_sp = *begin;
321     lldb::TypeValidatorImplSP current_format;
322     if (log)
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,
327                           &reason_why))
328       continue;
329     return current_format;
330   }
331   if (log)
332     log->Printf(
333         "[CategoryMap::GetValidator] nothing found - returning empty SP");
334   return lldb::TypeValidatorImplSP();
335 }
336
337 void TypeCategoryMap::ForEach(ForEachCallback callback) {
338   if (callback) {
339     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
340
341     // loop through enabled categories in respective order
342     {
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))
347           break;
348       }
349     }
350
351     // loop through disabled categories in just any order
352     {
353       MapIterator pos, end = m_map.end();
354       for (pos = m_map.begin(); pos != end; pos++) {
355         if (pos->second->IsEnabled())
356           continue;
357         if (!callback(pos->second))
358           break;
359       }
360     }
361   }
362 }
363
364 TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
365   std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
366
367   if (index < m_map.size()) {
368     MapIterator pos, end = m_map.end();
369     for (pos = m_map.begin(); pos != end; pos++) {
370       if (index == 0)
371         return pos->second;
372       index--;
373     }
374   }
375
376   return TypeCategoryImplSP();
377 }