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