]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / DataFormatters / TypeCategory.cpp
1 //===-- TypeCategory.cpp -----------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/DataFormatters/TypeCategory.h"
10 #include "lldb/Target/Language.h"
11
12
13 using namespace lldb;
14 using namespace lldb_private;
15
16 TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener *clist,
17                                    ConstString name)
18     : m_format_cont("format", "regex-format", clist),
19       m_summary_cont("summary", "regex-summary", clist),
20       m_filter_cont("filter", "regex-filter", clist),
21       m_synth_cont("synth", "regex-synth", clist), m_enabled(false),
22       m_change_listener(clist), m_mutex(), m_name(name), m_languages() {}
23
24 static bool IsApplicable(lldb::LanguageType category_lang,
25                          lldb::LanguageType valobj_lang) {
26   switch (category_lang) {
27   // Unless we know better, allow only exact equality.
28   default:
29     return category_lang == valobj_lang;
30
31   // the C family, we consider it as one
32   case eLanguageTypeC89:
33   case eLanguageTypeC:
34   case eLanguageTypeC99:
35     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
36            valobj_lang == eLanguageTypeC99;
37
38   // ObjC knows about C and itself
39   case eLanguageTypeObjC:
40     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
41            valobj_lang == eLanguageTypeC99 || valobj_lang == eLanguageTypeObjC;
42
43   // C++ knows about C and C++
44   case eLanguageTypeC_plus_plus:
45     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
46            valobj_lang == eLanguageTypeC99 ||
47            valobj_lang == eLanguageTypeC_plus_plus;
48
49   // ObjC++ knows about C,C++,ObjC and ObjC++
50   case eLanguageTypeObjC_plus_plus:
51     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
52            valobj_lang == eLanguageTypeC99 ||
53            valobj_lang == eLanguageTypeC_plus_plus ||
54            valobj_lang == eLanguageTypeObjC;
55
56   // Categories with unspecified language match everything.
57   case eLanguageTypeUnknown:
58     return true;
59   }
60 }
61
62 bool TypeCategoryImpl::IsApplicable(lldb::LanguageType lang) {
63   for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
64     const lldb::LanguageType category_lang = GetLanguageAtIndex(idx);
65     if (::IsApplicable(category_lang, lang))
66       return true;
67   }
68   return false;
69 }
70
71 size_t TypeCategoryImpl::GetNumLanguages() {
72   if (m_languages.empty())
73     return 1;
74   return m_languages.size();
75 }
76
77 lldb::LanguageType TypeCategoryImpl::GetLanguageAtIndex(size_t idx) {
78   if (m_languages.empty())
79     return lldb::eLanguageTypeUnknown;
80   return m_languages[idx];
81 }
82
83 void TypeCategoryImpl::AddLanguage(lldb::LanguageType lang) {
84   m_languages.push_back(lang);
85 }
86
87 bool TypeCategoryImpl::Get(lldb::LanguageType lang,
88                            const FormattersMatchVector &candidates,
89                            lldb::TypeFormatImplSP &entry, uint32_t *reason) {
90   if (!IsEnabled() || !IsApplicable(lang))
91     return false;
92   if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
93     return true;
94   bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
95   if (regex && reason)
96     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
97   return regex;
98 }
99
100 bool TypeCategoryImpl::Get(lldb::LanguageType lang,
101                            const FormattersMatchVector &candidates,
102                            lldb::TypeSummaryImplSP &entry, uint32_t *reason) {
103   if (!IsEnabled() || !IsApplicable(lang))
104     return false;
105   if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
106     return true;
107   bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
108   if (regex && reason)
109     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
110   return regex;
111 }
112
113 bool TypeCategoryImpl::Get(lldb::LanguageType lang,
114                            const FormattersMatchVector &candidates,
115                            lldb::SyntheticChildrenSP &entry, uint32_t *reason) {
116   if (!IsEnabled() || !IsApplicable(lang))
117     return false;
118   TypeFilterImpl::SharedPointer filter_sp;
119   uint32_t reason_filter = 0;
120   bool regex_filter = false;
121   // first find both Filter and Synth, and then check which is most recent
122
123   if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter))
124     regex_filter = GetRegexTypeFiltersContainer()->Get(candidates, filter_sp,
125                                                        &reason_filter);
126
127   bool regex_synth = false;
128   uint32_t reason_synth = 0;
129   bool pick_synth = false;
130   ScriptedSyntheticChildren::SharedPointer synth;
131   if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth))
132     regex_synth = GetRegexTypeSyntheticsContainer()->Get(candidates, synth,
133                                                          &reason_synth);
134   if (!filter_sp.get() && !synth.get())
135     return false;
136   else if (!filter_sp.get() && synth.get())
137     pick_synth = true;
138
139   else if (filter_sp.get() && !synth.get())
140     pick_synth = false;
141
142   else /*if (filter_sp.get() && synth.get())*/
143   {
144     pick_synth = filter_sp->GetRevision() <= synth->GetRevision();
145   }
146   if (pick_synth) {
147     if (regex_synth && reason)
148       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
149     entry = synth;
150     return true;
151   } else {
152     if (regex_filter && reason)
153       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
154     entry = filter_sp;
155     return true;
156   }
157   return false;
158 }
159
160 void TypeCategoryImpl::Clear(FormatCategoryItems items) {
161   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
162     GetTypeFormatsContainer()->Clear();
163   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
164     GetRegexTypeFormatsContainer()->Clear();
165
166   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
167     GetTypeSummariesContainer()->Clear();
168   if ((items & eFormatCategoryItemRegexSummary) ==
169       eFormatCategoryItemRegexSummary)
170     GetRegexTypeSummariesContainer()->Clear();
171
172   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
173     GetTypeFiltersContainer()->Clear();
174   if ((items & eFormatCategoryItemRegexFilter) ==
175       eFormatCategoryItemRegexFilter)
176     GetRegexTypeFiltersContainer()->Clear();
177
178   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
179     GetTypeSyntheticsContainer()->Clear();
180   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
181     GetRegexTypeSyntheticsContainer()->Clear();
182 }
183
184 bool TypeCategoryImpl::Delete(ConstString name, FormatCategoryItems items) {
185   bool success = false;
186
187   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
188     success = GetTypeFormatsContainer()->Delete(name) || success;
189   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
190     success = GetRegexTypeFormatsContainer()->Delete(name) || success;
191
192   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
193     success = GetTypeSummariesContainer()->Delete(name) || success;
194   if ((items & eFormatCategoryItemRegexSummary) ==
195       eFormatCategoryItemRegexSummary)
196     success = GetRegexTypeSummariesContainer()->Delete(name) || success;
197
198   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
199     success = GetTypeFiltersContainer()->Delete(name) || success;
200   if ((items & eFormatCategoryItemRegexFilter) ==
201       eFormatCategoryItemRegexFilter)
202     success = GetRegexTypeFiltersContainer()->Delete(name) || success;
203
204   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
205     success = GetTypeSyntheticsContainer()->Delete(name) || success;
206   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
207     success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
208
209   return success;
210 }
211
212 uint32_t TypeCategoryImpl::GetCount(FormatCategoryItems items) {
213   uint32_t count = 0;
214
215   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
216     count += GetTypeFormatsContainer()->GetCount();
217   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
218     count += GetRegexTypeFormatsContainer()->GetCount();
219
220   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
221     count += GetTypeSummariesContainer()->GetCount();
222   if ((items & eFormatCategoryItemRegexSummary) ==
223       eFormatCategoryItemRegexSummary)
224     count += GetRegexTypeSummariesContainer()->GetCount();
225
226   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
227     count += GetTypeFiltersContainer()->GetCount();
228   if ((items & eFormatCategoryItemRegexFilter) ==
229       eFormatCategoryItemRegexFilter)
230     count += GetRegexTypeFiltersContainer()->GetCount();
231
232   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
233     count += GetTypeSyntheticsContainer()->GetCount();
234   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
235     count += GetRegexTypeSyntheticsContainer()->GetCount();
236
237   return count;
238 }
239
240 bool TypeCategoryImpl::AnyMatches(ConstString type_name,
241                                   FormatCategoryItems items, bool only_enabled,
242                                   const char **matching_category,
243                                   FormatCategoryItems *matching_type) {
244   if (!IsEnabled() && only_enabled)
245     return false;
246
247   lldb::TypeFormatImplSP format_sp;
248   lldb::TypeSummaryImplSP summary_sp;
249   TypeFilterImpl::SharedPointer filter_sp;
250   ScriptedSyntheticChildren::SharedPointer synth_sp;
251
252   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue) {
253     if (GetTypeFormatsContainer()->Get(type_name, format_sp)) {
254       if (matching_category)
255         *matching_category = m_name.GetCString();
256       if (matching_type)
257         *matching_type = eFormatCategoryItemValue;
258       return true;
259     }
260   }
261   if ((items & eFormatCategoryItemRegexValue) ==
262       eFormatCategoryItemRegexValue) {
263     if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp)) {
264       if (matching_category)
265         *matching_category = m_name.GetCString();
266       if (matching_type)
267         *matching_type = eFormatCategoryItemRegexValue;
268       return true;
269     }
270   }
271
272   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary) {
273     if (GetTypeSummariesContainer()->Get(type_name, summary_sp)) {
274       if (matching_category)
275         *matching_category = m_name.GetCString();
276       if (matching_type)
277         *matching_type = eFormatCategoryItemSummary;
278       return true;
279     }
280   }
281   if ((items & eFormatCategoryItemRegexSummary) ==
282       eFormatCategoryItemRegexSummary) {
283     if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp)) {
284       if (matching_category)
285         *matching_category = m_name.GetCString();
286       if (matching_type)
287         *matching_type = eFormatCategoryItemRegexSummary;
288       return true;
289     }
290   }
291
292   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter) {
293     if (GetTypeFiltersContainer()->Get(type_name, filter_sp)) {
294       if (matching_category)
295         *matching_category = m_name.GetCString();
296       if (matching_type)
297         *matching_type = eFormatCategoryItemFilter;
298       return true;
299     }
300   }
301   if ((items & eFormatCategoryItemRegexFilter) ==
302       eFormatCategoryItemRegexFilter) {
303     if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp)) {
304       if (matching_category)
305         *matching_category = m_name.GetCString();
306       if (matching_type)
307         *matching_type = eFormatCategoryItemRegexFilter;
308       return true;
309     }
310   }
311
312   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth) {
313     if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
314       if (matching_category)
315         *matching_category = m_name.GetCString();
316       if (matching_type)
317         *matching_type = eFormatCategoryItemSynth;
318       return true;
319     }
320   }
321   if ((items & eFormatCategoryItemRegexSynth) ==
322       eFormatCategoryItemRegexSynth) {
323     if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
324       if (matching_category)
325         *matching_category = m_name.GetCString();
326       if (matching_type)
327         *matching_type = eFormatCategoryItemRegexSynth;
328       return true;
329     }
330   }
331
332   return false;
333 }
334
335 TypeCategoryImpl::FormatContainer::MapValueType
336 TypeCategoryImpl::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
337   FormatContainer::MapValueType retval;
338
339   if (type_sp) {
340     if (type_sp->IsRegex())
341       GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
342                                                retval);
343     else
344       GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
345                                           retval);
346   }
347
348   return retval;
349 }
350
351 TypeCategoryImpl::SummaryContainer::MapValueType
352 TypeCategoryImpl::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
353   SummaryContainer::MapValueType retval;
354
355   if (type_sp) {
356     if (type_sp->IsRegex())
357       GetRegexTypeSummariesContainer()->GetExact(
358           ConstString(type_sp->GetName()), retval);
359     else
360       GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),
361                                             retval);
362   }
363
364   return retval;
365 }
366
367 TypeCategoryImpl::FilterContainer::MapValueType
368 TypeCategoryImpl::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
369   FilterContainer::MapValueType retval;
370
371   if (type_sp) {
372     if (type_sp->IsRegex())
373       GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
374                                                retval);
375     else
376       GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
377                                           retval);
378   }
379
380   return retval;
381 }
382
383 TypeCategoryImpl::SynthContainer::MapValueType
384 TypeCategoryImpl::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
385   SynthContainer::MapValueType retval;
386
387   if (type_sp) {
388     if (type_sp->IsRegex())
389       GetRegexTypeSyntheticsContainer()->GetExact(
390           ConstString(type_sp->GetName()), retval);
391     else
392       GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),
393                                              retval);
394   }
395
396   return retval;
397 }
398
399 lldb::TypeNameSpecifierImplSP
400 TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex(size_t index) {
401   if (index < GetTypeSummariesContainer()->GetCount())
402     return GetTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index);
403   else
404     return GetRegexTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(
405         index - GetTypeSummariesContainer()->GetCount());
406 }
407
408 TypeCategoryImpl::FormatContainer::MapValueType
409 TypeCategoryImpl::GetFormatAtIndex(size_t index) {
410   if (index < GetTypeFormatsContainer()->GetCount())
411     return GetTypeFormatsContainer()->GetAtIndex(index);
412   else
413     return GetRegexTypeFormatsContainer()->GetAtIndex(
414         index - GetTypeFormatsContainer()->GetCount());
415 }
416
417 TypeCategoryImpl::SummaryContainer::MapValueType
418 TypeCategoryImpl::GetSummaryAtIndex(size_t index) {
419   if (index < GetTypeSummariesContainer()->GetCount())
420     return GetTypeSummariesContainer()->GetAtIndex(index);
421   else
422     return GetRegexTypeSummariesContainer()->GetAtIndex(
423         index - GetTypeSummariesContainer()->GetCount());
424 }
425
426 TypeCategoryImpl::FilterContainer::MapValueType
427 TypeCategoryImpl::GetFilterAtIndex(size_t index) {
428   if (index < GetTypeFiltersContainer()->GetCount())
429     return GetTypeFiltersContainer()->GetAtIndex(index);
430   else
431     return GetRegexTypeFiltersContainer()->GetAtIndex(
432         index - GetTypeFiltersContainer()->GetCount());
433 }
434
435 lldb::TypeNameSpecifierImplSP
436 TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex(size_t index) {
437   if (index < GetTypeFormatsContainer()->GetCount())
438     return GetTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index);
439   else
440     return GetRegexTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(
441         index - GetTypeFormatsContainer()->GetCount());
442 }
443
444 lldb::TypeNameSpecifierImplSP
445 TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex(size_t index) {
446   if (index < GetTypeFiltersContainer()->GetCount())
447     return GetTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index);
448   else
449     return GetRegexTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(
450         index - GetTypeFiltersContainer()->GetCount());
451 }
452
453 TypeCategoryImpl::SynthContainer::MapValueType
454 TypeCategoryImpl::GetSyntheticAtIndex(size_t index) {
455   if (index < GetTypeSyntheticsContainer()->GetCount())
456     return GetTypeSyntheticsContainer()->GetAtIndex(index);
457   else
458     return GetRegexTypeSyntheticsContainer()->GetAtIndex(
459         index - GetTypeSyntheticsContainer()->GetCount());
460 }
461
462 lldb::TypeNameSpecifierImplSP
463 TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex(size_t index) {
464   if (index < GetTypeSyntheticsContainer()->GetCount())
465     return GetTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index);
466   else
467     return GetRegexTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(
468         index - GetTypeSyntheticsContainer()->GetCount());
469 }
470
471 void TypeCategoryImpl::Enable(bool value, uint32_t position) {
472   std::lock_guard<std::recursive_mutex> guard(m_mutex);
473   if ((m_enabled = value))
474     m_enabled_position = position;
475   if (m_change_listener)
476     m_change_listener->Changed();
477 }
478
479 std::string TypeCategoryImpl::GetDescription() {
480   StreamString stream;
481   stream.Printf("%s (%s", GetName(), (IsEnabled() ? "enabled" : "disabled"));
482   StreamString lang_stream;
483   lang_stream.Printf(", applicable for language(s): ");
484   bool print_lang = false;
485   for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
486     const lldb::LanguageType lang = GetLanguageAtIndex(idx);
487     if (lang != lldb::eLanguageTypeUnknown)
488       print_lang = true;
489     lang_stream.Printf("%s%s", Language::GetNameForLanguageType(lang),
490                        idx + 1 < GetNumLanguages() ? ", " : "");
491   }
492   if (print_lang)
493     stream.PutCString(lang_stream.GetString());
494   stream.PutChar(')');
495   return stream.GetString();
496 }