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