1 //===-- TypeCategory.cpp -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/TypeCategory.h"
11 #include "lldb/Target/Language.h"
15 // Other libraries and framework includes
19 using namespace lldb_private;
21 TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
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),
30 m_validator_cont("validator","regex-validator",clist),
32 m_change_listener(clist),
33 m_mutex(Mutex::eMutexTypeRecursive),
37 for (const lldb::LanguageType lang : langs)
42 IsApplicable(lldb::LanguageType category_lang,
43 lldb::LanguageType valobj_lang)
45 switch (category_lang)
47 // these are not languages that LLDB would ordinarily deal with
48 // only allow an exact equality here, since we really don't know
50 case eLanguageTypeAda83:
51 case eLanguageTypeCobol74:
52 case eLanguageTypeCobol85:
53 case eLanguageTypeFortran77:
54 case eLanguageTypeFortran90:
55 case eLanguageTypePascal83:
56 case eLanguageTypeModula2:
57 case eLanguageTypeJava:
58 case eLanguageTypeAda95:
59 case eLanguageTypeFortran95:
60 case eLanguageTypePLI:
61 case eLanguageTypeUPC:
63 case eLanguageTypePython:
64 return category_lang == valobj_lang;
66 // the C family, we consider it as one
67 case eLanguageTypeC89:
69 case eLanguageTypeC99:
70 return valobj_lang == eLanguageTypeC89 ||
71 valobj_lang == eLanguageTypeC ||
72 valobj_lang == eLanguageTypeC99;
74 // ObjC knows about C and itself
75 case eLanguageTypeObjC:
76 return valobj_lang == eLanguageTypeC89 ||
77 valobj_lang == eLanguageTypeC ||
78 valobj_lang == eLanguageTypeC99 ||
79 valobj_lang == eLanguageTypeObjC;
81 // C++ knows about C and C++
82 case eLanguageTypeC_plus_plus:
83 return valobj_lang == eLanguageTypeC89 ||
84 valobj_lang == eLanguageTypeC ||
85 valobj_lang == eLanguageTypeC99 ||
86 valobj_lang == eLanguageTypeC_plus_plus;
88 // ObjC++ knows about C,C++,ObjC and ObjC++
89 case eLanguageTypeObjC_plus_plus:
90 return valobj_lang == eLanguageTypeC89 ||
91 valobj_lang == eLanguageTypeC ||
92 valobj_lang == eLanguageTypeC99 ||
93 valobj_lang == eLanguageTypeC_plus_plus ||
94 valobj_lang == eLanguageTypeObjC;
97 case eLanguageTypeUnknown:
103 TypeCategoryImpl::IsApplicable (ValueObject& valobj)
105 lldb::LanguageType valobj_lang = valobj.GetObjectRuntimeLanguage();
107 idx < GetNumLanguages();
110 const lldb::LanguageType category_lang = GetLanguageAtIndex(idx);
111 if (::IsApplicable(category_lang,valobj_lang))
118 TypeCategoryImpl::GetNumLanguages ()
120 if (m_languages.empty())
122 return m_languages.size();
126 TypeCategoryImpl::GetLanguageAtIndex (size_t idx)
128 if (m_languages.empty())
129 return lldb::eLanguageTypeUnknown;
130 return m_languages[idx];
134 TypeCategoryImpl::AddLanguage (lldb::LanguageType lang)
136 m_languages.push_back(lang);
140 TypeCategoryImpl::HasLanguage (lldb::LanguageType lang)
142 const auto iter = std::find(m_languages.begin(), m_languages.end(), lang),
143 end = m_languages.end();
144 return (iter != end);
148 TypeCategoryImpl::Get (ValueObject& valobj,
149 const FormattersMatchVector& candidates,
150 lldb::TypeFormatImplSP& entry,
153 if (!IsEnabled() || !IsApplicable(valobj))
155 if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
157 bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
159 *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
164 TypeCategoryImpl::Get (ValueObject& valobj,
165 const FormattersMatchVector& candidates,
166 lldb::TypeSummaryImplSP& entry,
169 if (!IsEnabled() || !IsApplicable(valobj))
171 if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
173 bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
175 *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
180 TypeCategoryImpl::Get (ValueObject& valobj,
181 const FormattersMatchVector& candidates,
182 lldb::SyntheticChildrenSP& entry,
185 if (!IsEnabled() || !IsApplicable(valobj))
187 TypeFilterImpl::SharedPointer filter_sp;
188 uint32_t reason_filter = 0;
189 bool regex_filter = false;
190 // first find both Filter and Synth, and then check which is most recent
192 if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter))
193 regex_filter = GetRegexTypeFiltersContainer()->Get (candidates, filter_sp, &reason_filter);
195 #ifndef LLDB_DISABLE_PYTHON
196 bool regex_synth = false;
197 uint32_t reason_synth = 0;
198 bool pick_synth = false;
199 ScriptedSyntheticChildren::SharedPointer synth;
200 if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth))
201 regex_synth = GetRegexTypeSyntheticsContainer()->Get (candidates, synth, &reason_synth);
202 if (!filter_sp.get() && !synth.get())
204 else if (!filter_sp.get() && synth.get())
207 else if (filter_sp.get() && !synth.get())
210 else /*if (filter_sp.get() && synth.get())*/
212 if (filter_sp->GetRevision() > synth->GetRevision())
219 if (regex_synth && reason)
220 *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
226 if (regex_filter && reason)
227 *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
244 TypeCategoryImpl::Get (ValueObject& valobj,
245 const FormattersMatchVector& candidates,
246 lldb::TypeValidatorImplSP& entry,
251 if (GetTypeValidatorsContainer()->Get(candidates, entry, reason))
253 bool regex = GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason);
255 *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
260 TypeCategoryImpl::Clear (FormatCategoryItems items)
262 if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
263 GetTypeFormatsContainer()->Clear();
264 if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
265 GetRegexTypeFormatsContainer()->Clear();
267 if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
268 GetTypeSummariesContainer()->Clear();
269 if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
270 GetRegexTypeSummariesContainer()->Clear();
272 if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
273 GetTypeFiltersContainer()->Clear();
274 if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
275 GetRegexTypeFiltersContainer()->Clear();
277 #ifndef LLDB_DISABLE_PYTHON
278 if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
279 GetTypeSyntheticsContainer()->Clear();
280 if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
281 GetRegexTypeSyntheticsContainer()->Clear();
284 if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
285 GetTypeValidatorsContainer()->Clear();
286 if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
287 GetRegexTypeValidatorsContainer()->Clear();
291 TypeCategoryImpl::Delete (ConstString name,
292 FormatCategoryItems items)
294 bool success = false;
296 if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
297 success = GetTypeFormatsContainer()->Delete(name) || success;
298 if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
299 success = GetRegexTypeFormatsContainer()->Delete(name) || success;
301 if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
302 success = GetTypeSummariesContainer()->Delete(name) || success;
303 if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
304 success = GetRegexTypeSummariesContainer()->Delete(name) || success;
306 if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
307 success = GetTypeFiltersContainer()->Delete(name) || success;
308 if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
309 success = GetRegexTypeFiltersContainer()->Delete(name) || success;
311 #ifndef LLDB_DISABLE_PYTHON
312 if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
313 success = GetTypeSyntheticsContainer()->Delete(name) || success;
314 if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
315 success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
318 if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
319 success = GetTypeValidatorsContainer()->Delete(name) || success;
320 if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
321 success = GetRegexTypeValidatorsContainer()->Delete(name) || success;
327 TypeCategoryImpl::GetCount (FormatCategoryItems items)
331 if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
332 count += GetTypeFormatsContainer()->GetCount();
333 if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
334 count += GetRegexTypeFormatsContainer()->GetCount();
336 if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
337 count += GetTypeSummariesContainer()->GetCount();
338 if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
339 count += GetRegexTypeSummariesContainer()->GetCount();
341 if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
342 count += GetTypeFiltersContainer()->GetCount();
343 if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
344 count += GetRegexTypeFiltersContainer()->GetCount();
346 #ifndef LLDB_DISABLE_PYTHON
347 if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
348 count += GetTypeSyntheticsContainer()->GetCount();
349 if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
350 count += GetRegexTypeSyntheticsContainer()->GetCount();
353 if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
354 count += GetTypeValidatorsContainer()->GetCount();
355 if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
356 count += GetRegexTypeValidatorsContainer()->GetCount();
362 TypeCategoryImpl::AnyMatches(ConstString type_name,
363 FormatCategoryItems items,
365 const char** matching_category,
366 FormatCategoryItems* matching_type)
368 if (!IsEnabled() && only_enabled)
371 lldb::TypeFormatImplSP format_sp;
372 lldb::TypeSummaryImplSP summary_sp;
373 TypeFilterImpl::SharedPointer filter_sp;
374 #ifndef LLDB_DISABLE_PYTHON
375 ScriptedSyntheticChildren::SharedPointer synth_sp;
377 TypeValidatorImpl::SharedPointer validator_sp;
379 if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
381 if (GetTypeFormatsContainer()->Get(type_name, format_sp))
383 if (matching_category)
384 *matching_category = m_name.GetCString();
386 *matching_type = eFormatCategoryItemValue;
390 if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
392 if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp))
394 if (matching_category)
395 *matching_category = m_name.GetCString();
397 *matching_type = eFormatCategoryItemRegexValue;
402 if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
404 if (GetTypeSummariesContainer()->Get(type_name, summary_sp))
406 if (matching_category)
407 *matching_category = m_name.GetCString();
409 *matching_type = eFormatCategoryItemSummary;
413 if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
415 if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp))
417 if (matching_category)
418 *matching_category = m_name.GetCString();
420 *matching_type = eFormatCategoryItemRegexSummary;
425 if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
427 if (GetTypeFiltersContainer()->Get(type_name, filter_sp))
429 if (matching_category)
430 *matching_category = m_name.GetCString();
432 *matching_type = eFormatCategoryItemFilter;
436 if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
438 if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp))
440 if (matching_category)
441 *matching_category = m_name.GetCString();
443 *matching_type = eFormatCategoryItemRegexFilter;
448 #ifndef LLDB_DISABLE_PYTHON
449 if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
451 if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp))
453 if (matching_category)
454 *matching_category = m_name.GetCString();
456 *matching_type = eFormatCategoryItemSynth;
460 if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
462 if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp))
464 if (matching_category)
465 *matching_category = m_name.GetCString();
467 *matching_type = eFormatCategoryItemRegexSynth;
473 if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
475 if (GetTypeValidatorsContainer()->Get(type_name, validator_sp))
477 if (matching_category)
478 *matching_category = m_name.GetCString();
480 *matching_type = eFormatCategoryItemValidator;
484 if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
486 if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp))
488 if (matching_category)
489 *matching_category = m_name.GetCString();
491 *matching_type = eFormatCategoryItemRegexValidator;
499 TypeCategoryImpl::FormatContainer::MapValueType
500 TypeCategoryImpl::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
502 FormatContainer::MapValueType retval;
506 if (type_sp->IsRegex())
507 GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
509 GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
515 TypeCategoryImpl::SummaryContainer::MapValueType
516 TypeCategoryImpl::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
518 SummaryContainer::MapValueType retval;
522 if (type_sp->IsRegex())
523 GetRegexTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),retval);
525 GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),retval);
531 TypeCategoryImpl::FilterContainer::MapValueType
532 TypeCategoryImpl::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
534 FilterContainer::MapValueType retval;
538 if (type_sp->IsRegex())
539 GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),retval);
541 GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),retval);
547 #ifndef LLDB_DISABLE_PYTHON
548 TypeCategoryImpl::SynthContainer::MapValueType
549 TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
551 SynthContainer::MapValueType retval;
555 if (type_sp->IsRegex())
556 GetRegexTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
558 GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
565 TypeCategoryImpl::ValidatorContainer::MapValueType
566 TypeCategoryImpl::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
568 ValidatorContainer::MapValueType retval;
572 if (type_sp->IsRegex())
573 GetRegexTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
575 GetTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
581 lldb::TypeNameSpecifierImplSP
582 TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
584 if (index < GetTypeSummariesContainer()->GetCount())
585 return GetTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index);
587 return GetRegexTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeSummariesContainer()->GetCount());
590 TypeCategoryImpl::FormatContainer::MapValueType
591 TypeCategoryImpl::GetFormatAtIndex (size_t index)
593 if (index < GetTypeFormatsContainer()->GetCount())
594 return GetTypeFormatsContainer()->GetAtIndex(index);
596 return GetRegexTypeFormatsContainer()->GetAtIndex(index-GetTypeFormatsContainer()->GetCount());
599 TypeCategoryImpl::SummaryContainer::MapValueType
600 TypeCategoryImpl::GetSummaryAtIndex (size_t index)
602 if (index < GetTypeSummariesContainer()->GetCount())
603 return GetTypeSummariesContainer()->GetAtIndex(index);
605 return GetRegexTypeSummariesContainer()->GetAtIndex(index-GetTypeSummariesContainer()->GetCount());
608 TypeCategoryImpl::FilterContainer::MapValueType
609 TypeCategoryImpl::GetFilterAtIndex (size_t index)
611 if (index < GetTypeFiltersContainer()->GetCount())
612 return GetTypeFiltersContainer()->GetAtIndex(index);
614 return GetRegexTypeFiltersContainer()->GetAtIndex(index-GetTypeFiltersContainer()->GetCount());
617 lldb::TypeNameSpecifierImplSP
618 TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex (size_t index)
620 if (index < GetTypeFormatsContainer()->GetCount())
621 return GetTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index);
623 return GetRegexTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeFormatsContainer()->GetCount());
626 lldb::TypeNameSpecifierImplSP
627 TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex (size_t index)
629 if (index < GetTypeFiltersContainer()->GetCount())
630 return GetTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index);
632 return GetRegexTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeFiltersContainer()->GetCount());
635 #ifndef LLDB_DISABLE_PYTHON
636 TypeCategoryImpl::SynthContainer::MapValueType
637 TypeCategoryImpl::GetSyntheticAtIndex (size_t index)
639 if (index < GetTypeSyntheticsContainer()->GetCount())
640 return GetTypeSyntheticsContainer()->GetAtIndex(index);
642 return GetRegexTypeSyntheticsContainer()->GetAtIndex(index-GetTypeSyntheticsContainer()->GetCount());
645 lldb::TypeNameSpecifierImplSP
646 TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
648 if (index < GetTypeSyntheticsContainer()->GetCount())
649 return GetTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index);
651 return GetRegexTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index - GetTypeSyntheticsContainer()->GetCount());
655 TypeCategoryImpl::ValidatorContainer::MapValueType
656 TypeCategoryImpl::GetValidatorAtIndex (size_t index)
658 if (index < GetTypeValidatorsContainer()->GetCount())
659 return GetTypeValidatorsContainer()->GetAtIndex(index);
661 return GetRegexTypeValidatorsContainer()->GetAtIndex(index-GetTypeValidatorsContainer()->GetCount());
664 lldb::TypeNameSpecifierImplSP
665 TypeCategoryImpl::GetTypeNameSpecifierForValidatorAtIndex (size_t index)
667 if (index < GetTypeValidatorsContainer()->GetCount())
668 return GetTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(index);
670 return GetRegexTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(index - GetTypeValidatorsContainer()->GetCount());
674 TypeCategoryImpl::Enable (bool value, uint32_t position)
676 Mutex::Locker locker(m_mutex);
677 if ( (m_enabled = value) )
678 m_enabled_position = position;
679 if (m_change_listener)
680 m_change_listener->Changed();
684 TypeCategoryImpl::GetDescription ()
687 stream.Printf("%s (%s",
689 (IsEnabled() ? "enabled" : "disabled"));
690 StreamString lang_stream;
691 lang_stream.Printf(", applicable for language(s): ");
692 bool print_lang = false;
694 idx < GetNumLanguages();
697 const lldb::LanguageType lang = GetLanguageAtIndex(idx);
698 if (lang != lldb::eLanguageTypeUnknown)
700 lang_stream.Printf("%s%s",
701 Language::GetNameForLanguageType(lang),
702 idx+1<GetNumLanguages() ? ", " : "");
705 stream.Printf("%s",lang_stream.GetData());
707 return stream.GetData();