1 //===-- TypeCategory.cpp -----------------------------------------*- C++-*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/DataFormatters/TypeCategory.h"
11 #include "lldb/Target/Language.h"
12 
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
TypeCategoryImpl(IFormatChangeListener * clist,ConstString name,std::initializer_list<lldb::LanguageType> langs)17 TypeCategoryImpl::TypeCategoryImpl(
18     IFormatChangeListener *clist, ConstString name,
19     std::initializer_list<lldb::LanguageType> langs)
20     : m_format_cont("format", "regex-format", clist),
21       m_summary_cont("summary", "regex-summary", clist),
22       m_filter_cont("filter", "regex-filter", clist),
23 #ifndef LLDB_DISABLE_PYTHON
24       m_synth_cont("synth", "regex-synth", clist),
25 #endif
26       m_validator_cont("validator", "regex-validator", clist), m_enabled(false),
27       m_change_listener(clist), m_mutex(), m_name(name), m_languages() {
28   for (const lldb::LanguageType lang : langs)
29     AddLanguage(lang);
30 }
31 
IsApplicable(lldb::LanguageType category_lang,lldb::LanguageType valobj_lang)32 static bool IsApplicable(lldb::LanguageType category_lang,
33                          lldb::LanguageType valobj_lang) {
34   switch (category_lang) {
35   // Unless we know better, allow only exact equality.
36   default:
37     return category_lang == valobj_lang;
38 
39   // the C family, we consider it as one
40   case eLanguageTypeC89:
41   case eLanguageTypeC:
42   case eLanguageTypeC99:
43     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
44            valobj_lang == eLanguageTypeC99;
45 
46   // ObjC knows about C and itself
47   case eLanguageTypeObjC:
48     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
49            valobj_lang == eLanguageTypeC99 || valobj_lang == eLanguageTypeObjC;
50 
51   // C++ knows about C and C++
52   case eLanguageTypeC_plus_plus:
53     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
54            valobj_lang == eLanguageTypeC99 ||
55            valobj_lang == eLanguageTypeC_plus_plus;
56 
57   // ObjC++ knows about C,C++,ObjC and ObjC++
58   case eLanguageTypeObjC_plus_plus:
59     return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
60            valobj_lang == eLanguageTypeC99 ||
61            valobj_lang == eLanguageTypeC_plus_plus ||
62            valobj_lang == eLanguageTypeObjC;
63 
64   // Categories with unspecified language match everything.
65   case eLanguageTypeUnknown:
66     return true;
67   }
68 }
69 
IsApplicable(ValueObject & valobj)70 bool TypeCategoryImpl::IsApplicable(ValueObject &valobj) {
71   lldb::LanguageType valobj_lang = valobj.GetObjectRuntimeLanguage();
72   for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
73     const lldb::LanguageType category_lang = GetLanguageAtIndex(idx);
74     if (::IsApplicable(category_lang, valobj_lang))
75       return true;
76   }
77   return false;
78 }
79 
GetNumLanguages()80 size_t TypeCategoryImpl::GetNumLanguages() {
81   if (m_languages.empty())
82     return 1;
83   return m_languages.size();
84 }
85 
GetLanguageAtIndex(size_t idx)86 lldb::LanguageType TypeCategoryImpl::GetLanguageAtIndex(size_t idx) {
87   if (m_languages.empty())
88     return lldb::eLanguageTypeUnknown;
89   return m_languages[idx];
90 }
91 
AddLanguage(lldb::LanguageType lang)92 void TypeCategoryImpl::AddLanguage(lldb::LanguageType lang) {
93   m_languages.push_back(lang);
94 }
95 
HasLanguage(lldb::LanguageType lang)96 bool TypeCategoryImpl::HasLanguage(lldb::LanguageType lang) {
97   const auto iter = std::find(m_languages.begin(), m_languages.end(), lang),
98              end = m_languages.end();
99   return (iter != end);
100 }
101 
Get(ValueObject & valobj,const FormattersMatchVector & candidates,lldb::TypeFormatImplSP & entry,uint32_t * reason)102 bool TypeCategoryImpl::Get(ValueObject &valobj,
103                            const FormattersMatchVector &candidates,
104                            lldb::TypeFormatImplSP &entry, uint32_t *reason) {
105   if (!IsEnabled() || !IsApplicable(valobj))
106     return false;
107   if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
108     return true;
109   bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
110   if (regex && reason)
111     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
112   return regex;
113 }
114 
Get(ValueObject & valobj,const FormattersMatchVector & candidates,lldb::TypeSummaryImplSP & entry,uint32_t * reason)115 bool TypeCategoryImpl::Get(ValueObject &valobj,
116                            const FormattersMatchVector &candidates,
117                            lldb::TypeSummaryImplSP &entry, uint32_t *reason) {
118   if (!IsEnabled() || !IsApplicable(valobj))
119     return false;
120   if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
121     return true;
122   bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
123   if (regex && reason)
124     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
125   return regex;
126 }
127 
Get(ValueObject & valobj,const FormattersMatchVector & candidates,lldb::SyntheticChildrenSP & entry,uint32_t * reason)128 bool TypeCategoryImpl::Get(ValueObject &valobj,
129                            const FormattersMatchVector &candidates,
130                            lldb::SyntheticChildrenSP &entry, uint32_t *reason) {
131   if (!IsEnabled() || !IsApplicable(valobj))
132     return false;
133   TypeFilterImpl::SharedPointer filter_sp;
134   uint32_t reason_filter = 0;
135   bool regex_filter = false;
136   // first find both Filter and Synth, and then check which is most recent
137 
138   if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter))
139     regex_filter = GetRegexTypeFiltersContainer()->Get(candidates, filter_sp,
140                                                        &reason_filter);
141 
142 #ifndef LLDB_DISABLE_PYTHON
143   bool regex_synth = false;
144   uint32_t reason_synth = 0;
145   bool pick_synth = false;
146   ScriptedSyntheticChildren::SharedPointer synth;
147   if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth))
148     regex_synth = GetRegexTypeSyntheticsContainer()->Get(candidates, synth,
149                                                          &reason_synth);
150   if (!filter_sp.get() && !synth.get())
151     return false;
152   else if (!filter_sp.get() && synth.get())
153     pick_synth = true;
154 
155   else if (filter_sp.get() && !synth.get())
156     pick_synth = false;
157 
158   else /*if (filter_sp.get() && synth.get())*/
159   {
160     pick_synth = filter_sp->GetRevision() <= synth->GetRevision();
161   }
162   if (pick_synth) {
163     if (regex_synth && reason)
164       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
165     entry = synth;
166     return true;
167   } else {
168     if (regex_filter && reason)
169       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
170     entry = filter_sp;
171     return true;
172   }
173 
174 #else
175   if (filter_sp) {
176     entry = filter_sp;
177     return true;
178   }
179 #endif
180 
181   return false;
182 }
183 
Get(ValueObject & valobj,const FormattersMatchVector & candidates,lldb::TypeValidatorImplSP & entry,uint32_t * reason)184 bool TypeCategoryImpl::Get(ValueObject &valobj,
185                            const FormattersMatchVector &candidates,
186                            lldb::TypeValidatorImplSP &entry, uint32_t *reason) {
187   if (!IsEnabled())
188     return false;
189   if (GetTypeValidatorsContainer()->Get(candidates, entry, reason))
190     return true;
191   bool regex =
192       GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason);
193   if (regex && reason)
194     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
195   return regex;
196 }
197 
Clear(FormatCategoryItems items)198 void TypeCategoryImpl::Clear(FormatCategoryItems items) {
199   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
200     GetTypeFormatsContainer()->Clear();
201   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
202     GetRegexTypeFormatsContainer()->Clear();
203 
204   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
205     GetTypeSummariesContainer()->Clear();
206   if ((items & eFormatCategoryItemRegexSummary) ==
207       eFormatCategoryItemRegexSummary)
208     GetRegexTypeSummariesContainer()->Clear();
209 
210   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
211     GetTypeFiltersContainer()->Clear();
212   if ((items & eFormatCategoryItemRegexFilter) ==
213       eFormatCategoryItemRegexFilter)
214     GetRegexTypeFiltersContainer()->Clear();
215 
216 #ifndef LLDB_DISABLE_PYTHON
217   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
218     GetTypeSyntheticsContainer()->Clear();
219   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
220     GetRegexTypeSyntheticsContainer()->Clear();
221 #endif
222 
223   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator)
224     GetTypeValidatorsContainer()->Clear();
225   if ((items & eFormatCategoryItemRegexValidator) ==
226       eFormatCategoryItemRegexValidator)
227     GetRegexTypeValidatorsContainer()->Clear();
228 }
229 
Delete(ConstString name,FormatCategoryItems items)230 bool TypeCategoryImpl::Delete(ConstString name, FormatCategoryItems items) {
231   bool success = false;
232 
233   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
234     success = GetTypeFormatsContainer()->Delete(name) || success;
235   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
236     success = GetRegexTypeFormatsContainer()->Delete(name) || success;
237 
238   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
239     success = GetTypeSummariesContainer()->Delete(name) || success;
240   if ((items & eFormatCategoryItemRegexSummary) ==
241       eFormatCategoryItemRegexSummary)
242     success = GetRegexTypeSummariesContainer()->Delete(name) || success;
243 
244   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
245     success = GetTypeFiltersContainer()->Delete(name) || success;
246   if ((items & eFormatCategoryItemRegexFilter) ==
247       eFormatCategoryItemRegexFilter)
248     success = GetRegexTypeFiltersContainer()->Delete(name) || success;
249 
250 #ifndef LLDB_DISABLE_PYTHON
251   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
252     success = GetTypeSyntheticsContainer()->Delete(name) || success;
253   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
254     success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
255 #endif
256 
257   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator)
258     success = GetTypeValidatorsContainer()->Delete(name) || success;
259   if ((items & eFormatCategoryItemRegexValidator) ==
260       eFormatCategoryItemRegexValidator)
261     success = GetRegexTypeValidatorsContainer()->Delete(name) || success;
262 
263   return success;
264 }
265 
GetCount(FormatCategoryItems items)266 uint32_t TypeCategoryImpl::GetCount(FormatCategoryItems items) {
267   uint32_t count = 0;
268 
269   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
270     count += GetTypeFormatsContainer()->GetCount();
271   if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
272     count += GetRegexTypeFormatsContainer()->GetCount();
273 
274   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
275     count += GetTypeSummariesContainer()->GetCount();
276   if ((items & eFormatCategoryItemRegexSummary) ==
277       eFormatCategoryItemRegexSummary)
278     count += GetRegexTypeSummariesContainer()->GetCount();
279 
280   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
281     count += GetTypeFiltersContainer()->GetCount();
282   if ((items & eFormatCategoryItemRegexFilter) ==
283       eFormatCategoryItemRegexFilter)
284     count += GetRegexTypeFiltersContainer()->GetCount();
285 
286 #ifndef LLDB_DISABLE_PYTHON
287   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
288     count += GetTypeSyntheticsContainer()->GetCount();
289   if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
290     count += GetRegexTypeSyntheticsContainer()->GetCount();
291 #endif
292 
293   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator)
294     count += GetTypeValidatorsContainer()->GetCount();
295   if ((items & eFormatCategoryItemRegexValidator) ==
296       eFormatCategoryItemRegexValidator)
297     count += GetRegexTypeValidatorsContainer()->GetCount();
298 
299   return count;
300 }
301 
AnyMatches(ConstString type_name,FormatCategoryItems items,bool only_enabled,const char ** matching_category,FormatCategoryItems * matching_type)302 bool TypeCategoryImpl::AnyMatches(ConstString type_name,
303                                   FormatCategoryItems items, bool only_enabled,
304                                   const char **matching_category,
305                                   FormatCategoryItems *matching_type) {
306   if (!IsEnabled() && only_enabled)
307     return false;
308 
309   lldb::TypeFormatImplSP format_sp;
310   lldb::TypeSummaryImplSP summary_sp;
311   TypeFilterImpl::SharedPointer filter_sp;
312 #ifndef LLDB_DISABLE_PYTHON
313   ScriptedSyntheticChildren::SharedPointer synth_sp;
314 #endif
315   TypeValidatorImpl::SharedPointer validator_sp;
316 
317   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue) {
318     if (GetTypeFormatsContainer()->Get(type_name, format_sp)) {
319       if (matching_category)
320         *matching_category = m_name.GetCString();
321       if (matching_type)
322         *matching_type = eFormatCategoryItemValue;
323       return true;
324     }
325   }
326   if ((items & eFormatCategoryItemRegexValue) ==
327       eFormatCategoryItemRegexValue) {
328     if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp)) {
329       if (matching_category)
330         *matching_category = m_name.GetCString();
331       if (matching_type)
332         *matching_type = eFormatCategoryItemRegexValue;
333       return true;
334     }
335   }
336 
337   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary) {
338     if (GetTypeSummariesContainer()->Get(type_name, summary_sp)) {
339       if (matching_category)
340         *matching_category = m_name.GetCString();
341       if (matching_type)
342         *matching_type = eFormatCategoryItemSummary;
343       return true;
344     }
345   }
346   if ((items & eFormatCategoryItemRegexSummary) ==
347       eFormatCategoryItemRegexSummary) {
348     if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp)) {
349       if (matching_category)
350         *matching_category = m_name.GetCString();
351       if (matching_type)
352         *matching_type = eFormatCategoryItemRegexSummary;
353       return true;
354     }
355   }
356 
357   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter) {
358     if (GetTypeFiltersContainer()->Get(type_name, filter_sp)) {
359       if (matching_category)
360         *matching_category = m_name.GetCString();
361       if (matching_type)
362         *matching_type = eFormatCategoryItemFilter;
363       return true;
364     }
365   }
366   if ((items & eFormatCategoryItemRegexFilter) ==
367       eFormatCategoryItemRegexFilter) {
368     if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp)) {
369       if (matching_category)
370         *matching_category = m_name.GetCString();
371       if (matching_type)
372         *matching_type = eFormatCategoryItemRegexFilter;
373       return true;
374     }
375   }
376 
377 #ifndef LLDB_DISABLE_PYTHON
378   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth) {
379     if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
380       if (matching_category)
381         *matching_category = m_name.GetCString();
382       if (matching_type)
383         *matching_type = eFormatCategoryItemSynth;
384       return true;
385     }
386   }
387   if ((items & eFormatCategoryItemRegexSynth) ==
388       eFormatCategoryItemRegexSynth) {
389     if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
390       if (matching_category)
391         *matching_category = m_name.GetCString();
392       if (matching_type)
393         *matching_type = eFormatCategoryItemRegexSynth;
394       return true;
395     }
396   }
397 #endif
398 
399   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator) {
400     if (GetTypeValidatorsContainer()->Get(type_name, validator_sp)) {
401       if (matching_category)
402         *matching_category = m_name.GetCString();
403       if (matching_type)
404         *matching_type = eFormatCategoryItemValidator;
405       return true;
406     }
407   }
408   if ((items & eFormatCategoryItemRegexValidator) ==
409       eFormatCategoryItemRegexValidator) {
410     if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp)) {
411       if (matching_category)
412         *matching_category = m_name.GetCString();
413       if (matching_type)
414         *matching_type = eFormatCategoryItemRegexValidator;
415       return true;
416     }
417   }
418 
419   return false;
420 }
421 
422 TypeCategoryImpl::FormatContainer::MapValueType
GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp)423 TypeCategoryImpl::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
424   FormatContainer::MapValueType retval;
425 
426   if (type_sp) {
427     if (type_sp->IsRegex())
428       GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
429                                                retval);
430     else
431       GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
432                                           retval);
433   }
434 
435   return retval;
436 }
437 
438 TypeCategoryImpl::SummaryContainer::MapValueType
GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp)439 TypeCategoryImpl::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
440   SummaryContainer::MapValueType retval;
441 
442   if (type_sp) {
443     if (type_sp->IsRegex())
444       GetRegexTypeSummariesContainer()->GetExact(
445           ConstString(type_sp->GetName()), retval);
446     else
447       GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),
448                                             retval);
449   }
450 
451   return retval;
452 }
453 
454 TypeCategoryImpl::FilterContainer::MapValueType
GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp)455 TypeCategoryImpl::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
456   FilterContainer::MapValueType retval;
457 
458   if (type_sp) {
459     if (type_sp->IsRegex())
460       GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
461                                                retval);
462     else
463       GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
464                                           retval);
465   }
466 
467   return retval;
468 }
469 
470 #ifndef LLDB_DISABLE_PYTHON
471 TypeCategoryImpl::SynthContainer::MapValueType
GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp)472 TypeCategoryImpl::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
473   SynthContainer::MapValueType retval;
474 
475   if (type_sp) {
476     if (type_sp->IsRegex())
477       GetRegexTypeSyntheticsContainer()->GetExact(
478           ConstString(type_sp->GetName()), retval);
479     else
480       GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),
481                                              retval);
482   }
483 
484   return retval;
485 }
486 #endif
487 
488 TypeCategoryImpl::ValidatorContainer::MapValueType
GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp)489 TypeCategoryImpl::GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp) {
490   ValidatorContainer::MapValueType retval;
491 
492   if (type_sp) {
493     if (type_sp->IsRegex())
494       GetRegexTypeValidatorsContainer()->GetExact(
495           ConstString(type_sp->GetName()), retval);
496     else
497       GetTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),
498                                              retval);
499   }
500 
501   return retval;
502 }
503 
504 lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForSummaryAtIndex(size_t index)505 TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex(size_t index) {
506   if (index < GetTypeSummariesContainer()->GetCount())
507     return GetTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index);
508   else
509     return GetRegexTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(
510         index - GetTypeSummariesContainer()->GetCount());
511 }
512 
513 TypeCategoryImpl::FormatContainer::MapValueType
GetFormatAtIndex(size_t index)514 TypeCategoryImpl::GetFormatAtIndex(size_t index) {
515   if (index < GetTypeFormatsContainer()->GetCount())
516     return GetTypeFormatsContainer()->GetAtIndex(index);
517   else
518     return GetRegexTypeFormatsContainer()->GetAtIndex(
519         index - GetTypeFormatsContainer()->GetCount());
520 }
521 
522 TypeCategoryImpl::SummaryContainer::MapValueType
GetSummaryAtIndex(size_t index)523 TypeCategoryImpl::GetSummaryAtIndex(size_t index) {
524   if (index < GetTypeSummariesContainer()->GetCount())
525     return GetTypeSummariesContainer()->GetAtIndex(index);
526   else
527     return GetRegexTypeSummariesContainer()->GetAtIndex(
528         index - GetTypeSummariesContainer()->GetCount());
529 }
530 
531 TypeCategoryImpl::FilterContainer::MapValueType
GetFilterAtIndex(size_t index)532 TypeCategoryImpl::GetFilterAtIndex(size_t index) {
533   if (index < GetTypeFiltersContainer()->GetCount())
534     return GetTypeFiltersContainer()->GetAtIndex(index);
535   else
536     return GetRegexTypeFiltersContainer()->GetAtIndex(
537         index - GetTypeFiltersContainer()->GetCount());
538 }
539 
540 lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForFormatAtIndex(size_t index)541 TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex(size_t index) {
542   if (index < GetTypeFormatsContainer()->GetCount())
543     return GetTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index);
544   else
545     return GetRegexTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(
546         index - GetTypeFormatsContainer()->GetCount());
547 }
548 
549 lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForFilterAtIndex(size_t index)550 TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex(size_t index) {
551   if (index < GetTypeFiltersContainer()->GetCount())
552     return GetTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index);
553   else
554     return GetRegexTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(
555         index - GetTypeFiltersContainer()->GetCount());
556 }
557 
558 #ifndef LLDB_DISABLE_PYTHON
559 TypeCategoryImpl::SynthContainer::MapValueType
GetSyntheticAtIndex(size_t index)560 TypeCategoryImpl::GetSyntheticAtIndex(size_t index) {
561   if (index < GetTypeSyntheticsContainer()->GetCount())
562     return GetTypeSyntheticsContainer()->GetAtIndex(index);
563   else
564     return GetRegexTypeSyntheticsContainer()->GetAtIndex(
565         index - GetTypeSyntheticsContainer()->GetCount());
566 }
567 
568 lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForSyntheticAtIndex(size_t index)569 TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex(size_t index) {
570   if (index < GetTypeSyntheticsContainer()->GetCount())
571     return GetTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index);
572   else
573     return GetRegexTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(
574         index - GetTypeSyntheticsContainer()->GetCount());
575 }
576 #endif
577 
578 TypeCategoryImpl::ValidatorContainer::MapValueType
GetValidatorAtIndex(size_t index)579 TypeCategoryImpl::GetValidatorAtIndex(size_t index) {
580   if (index < GetTypeValidatorsContainer()->GetCount())
581     return GetTypeValidatorsContainer()->GetAtIndex(index);
582   else
583     return GetRegexTypeValidatorsContainer()->GetAtIndex(
584         index - GetTypeValidatorsContainer()->GetCount());
585 }
586 
587 lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForValidatorAtIndex(size_t index)588 TypeCategoryImpl::GetTypeNameSpecifierForValidatorAtIndex(size_t index) {
589   if (index < GetTypeValidatorsContainer()->GetCount())
590     return GetTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(index);
591   else
592     return GetRegexTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(
593         index - GetTypeValidatorsContainer()->GetCount());
594 }
595 
Enable(bool value,uint32_t position)596 void TypeCategoryImpl::Enable(bool value, uint32_t position) {
597   std::lock_guard<std::recursive_mutex> guard(m_mutex);
598   if ((m_enabled = value))
599     m_enabled_position = position;
600   if (m_change_listener)
601     m_change_listener->Changed();
602 }
603 
GetDescription()604 std::string TypeCategoryImpl::GetDescription() {
605   StreamString stream;
606   stream.Printf("%s (%s", GetName(), (IsEnabled() ? "enabled" : "disabled"));
607   StreamString lang_stream;
608   lang_stream.Printf(", applicable for language(s): ");
609   bool print_lang = false;
610   for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
611     const lldb::LanguageType lang = GetLanguageAtIndex(idx);
612     if (lang != lldb::eLanguageTypeUnknown)
613       print_lang = true;
614     lang_stream.Printf("%s%s", Language::GetNameForLanguageType(lang),
615                        idx + 1 < GetNumLanguages() ? ", " : "");
616   }
617   if (print_lang)
618     stream.PutCString(lang_stream.GetString());
619   stream.PutChar(')');
620   return stream.GetString();
621 }
622