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