1 //===-- FormatManager.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/FormatManager.h"
12 #include "llvm/ADT/STLExtras.h"
16 // Other libraries and framework includes
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Log.h"
21 #include "lldb/DataFormatters/FormattersHelpers.h"
22 #include "lldb/DataFormatters/LanguageCategory.h"
23 #include "lldb/Target/ExecutionContext.h"
24 #include "lldb/Target/Language.h"
27 using namespace lldb_private;
28 using namespace lldb_private::formatters;
33 const char format_char; // One or more format characters that can be used for this format.
34 const char *format_name; // Long format name that can be used to specify the current format
40 { eFormatDefault , '\0' , "default" },
41 { eFormatBoolean , 'B' , "boolean" },
42 { eFormatBinary , 'b' , "binary" },
43 { eFormatBytes , 'y' , "bytes" },
44 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
45 { eFormatChar , 'c' , "character" },
46 { eFormatCharPrintable , 'C' , "printable character" },
47 { eFormatComplexFloat , 'F' , "complex float" },
48 { eFormatCString , 's' , "c-string" },
49 { eFormatDecimal , 'd' , "decimal" },
50 { eFormatEnum , 'E' , "enumeration" },
51 { eFormatHex , 'x' , "hex" },
52 { eFormatHexUppercase , 'X' , "uppercase hex" },
53 { eFormatFloat , 'f' , "float" },
54 { eFormatOctal , 'o' , "octal" },
55 { eFormatOSType , 'O' , "OSType" },
56 { eFormatUnicode16 , 'U' , "unicode16" },
57 { eFormatUnicode32 , '\0' , "unicode32" },
58 { eFormatUnsigned , 'u' , "unsigned decimal" },
59 { eFormatPointer , 'p' , "pointer" },
60 { eFormatVectorOfChar , '\0' , "char[]" },
61 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
62 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
63 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
64 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
65 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
66 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
67 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
68 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
69 { eFormatVectorOfFloat16, '\0' , "float16[]" },
70 { eFormatVectorOfFloat32, '\0' , "float32[]" },
71 { eFormatVectorOfFloat64, '\0' , "float64[]" },
72 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
73 { eFormatComplexInteger , 'I' , "complex integer" },
74 { eFormatCharArray , 'a' , "character array" },
75 { eFormatAddressInfo , 'A' , "address" },
76 { eFormatHexFloat , '\0' , "hex float" },
77 { eFormatInstruction , 'i' , "instruction" },
78 { eFormatVoid , 'v' , "void" }
81 static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
84 GetFormatFromFormatChar (char format_char, Format &format)
86 for (uint32_t i=0; i<g_num_format_infos; ++i)
88 if (g_format_infos[i].format_char == format_char)
90 format = g_format_infos[i].format;
94 format = eFormatInvalid;
99 GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
102 for (i=0; i<g_num_format_infos; ++i)
104 if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
106 format = g_format_infos[i].format;
111 if (partial_match_ok)
113 for (i=0; i<g_num_format_infos; ++i)
115 if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
117 format = g_format_infos[i].format;
122 format = eFormatInvalid;
127 FormatManager::Changed ()
130 m_format_cache.Clear ();
131 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
132 for (auto& iter : m_language_categories_map)
135 iter.second->GetFormatCache().Clear();
140 FormatManager::GetFormatFromCString (const char *format_cstr,
141 bool partial_match_ok,
142 lldb::Format &format)
144 bool success = false;
145 if (format_cstr && format_cstr[0])
147 if (format_cstr[1] == '\0')
149 success = GetFormatFromFormatChar (format_cstr[0], format);
154 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
157 format = eFormatInvalid;
162 FormatManager::GetFormatAsFormatChar (lldb::Format format)
164 for (uint32_t i=0; i<g_num_format_infos; ++i)
166 if (g_format_infos[i].format == format)
167 return g_format_infos[i].format_char;
173 FormatManager::GetFormatAsCString (Format format)
175 if (format >= eFormatDefault && format < kNumFormats)
176 return g_format_infos[format].format_name;
181 FormatManager::EnableAllCategories ()
183 m_categories_map.EnableAllCategories ();
184 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
185 for (auto& iter : m_language_categories_map)
188 iter.second->Enable();
193 FormatManager::DisableAllCategories ()
195 m_categories_map.DisableAllCategories ();
196 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
197 for (auto& iter : m_language_categories_map)
200 iter.second->Disable();
205 FormatManager::GetPossibleMatches (ValueObject& valobj,
206 CompilerType compiler_type,
208 lldb::DynamicValueType use_dynamic,
209 FormattersMatchVector& entries,
212 bool did_strip_typedef,
215 compiler_type = compiler_type.GetTypeForFormatters();
216 ConstString type_name(compiler_type.GetConstTypeName());
217 if (valobj.GetBitfieldBitSize() > 0)
219 StreamString sstring;
220 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
221 ConstString bitfieldname = ConstString(sstring.GetData());
222 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
223 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
226 if (!compiler_type.IsMeaninglessWithoutDynamicResolution())
228 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
230 ConstString display_type_name(compiler_type.GetDisplayTypeName());
231 if (display_type_name != type_name)
232 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
235 for (bool is_rvalue_ref = true, j = true; j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false)
237 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
238 GetPossibleMatches(valobj,
240 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
246 if (non_ref_type.IsTypedefType())
248 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
249 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
250 GetPossibleMatches(valobj,
251 deffed_referenced_type,
252 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
257 true); // this is not exactly the usual meaning of stripping typedefs
261 if (compiler_type.IsPointerType())
263 CompilerType non_ptr_type = compiler_type.GetPointeeType();
264 GetPossibleMatches(valobj,
266 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
272 if (non_ptr_type.IsTypedefType())
274 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
275 GetPossibleMatches(valobj,
277 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
282 true); // this is not exactly the usual meaning of stripping typedefs
286 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
288 if (Language* language = Language::FindPlugin(language_type))
290 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
292 entries.push_back({candidate,
293 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
301 // try to strip typedef chains
302 if (compiler_type.IsTypedefType())
304 CompilerType deffed_type = compiler_type.GetTypedefedType();
305 GetPossibleMatches(valobj,
307 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
318 if (!compiler_type.IsValid())
321 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
322 if (!unqual_compiler_ast_type.IsValid())
324 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
325 GetPossibleMatches (valobj,
326 unqual_compiler_ast_type,
336 // if all else fails, go to static type
337 if (valobj.IsDynamic())
339 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
341 GetPossibleMatches(*static_value_sp.get(),
342 static_value_sp->GetCompilerType(),
343 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
354 lldb::TypeFormatImplSP
355 FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
358 return lldb::TypeFormatImplSP();
359 lldb::TypeFormatImplSP format_chosen_sp;
360 uint32_t num_categories = m_categories_map.GetCount();
361 lldb::TypeCategoryImplSP category_sp;
362 uint32_t prio_category = UINT32_MAX;
363 for (uint32_t category_id = 0;
364 category_id < num_categories;
367 category_sp = GetCategoryAtIndex(category_id);
368 if (category_sp->IsEnabled() == false)
370 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
371 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
373 prio_category = category_sp->GetEnabledPosition();
374 format_chosen_sp = format_current_sp;
377 return format_chosen_sp;
380 lldb::TypeSummaryImplSP
381 FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
384 return lldb::TypeSummaryImplSP();
385 lldb::TypeSummaryImplSP summary_chosen_sp;
386 uint32_t num_categories = m_categories_map.GetCount();
387 lldb::TypeCategoryImplSP category_sp;
388 uint32_t prio_category = UINT32_MAX;
389 for (uint32_t category_id = 0;
390 category_id < num_categories;
393 category_sp = GetCategoryAtIndex(category_id);
394 if (category_sp->IsEnabled() == false)
396 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
397 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
399 prio_category = category_sp->GetEnabledPosition();
400 summary_chosen_sp = summary_current_sp;
403 return summary_chosen_sp;
406 lldb::TypeFilterImplSP
407 FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
410 return lldb::TypeFilterImplSP();
411 lldb::TypeFilterImplSP filter_chosen_sp;
412 uint32_t num_categories = m_categories_map.GetCount();
413 lldb::TypeCategoryImplSP category_sp;
414 uint32_t prio_category = UINT32_MAX;
415 for (uint32_t category_id = 0;
416 category_id < num_categories;
419 category_sp = GetCategoryAtIndex(category_id);
420 if (category_sp->IsEnabled() == false)
422 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
423 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
425 prio_category = category_sp->GetEnabledPosition();
426 filter_chosen_sp = filter_current_sp;
429 return filter_chosen_sp;
432 #ifndef LLDB_DISABLE_PYTHON
433 lldb::ScriptedSyntheticChildrenSP
434 FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
437 return lldb::ScriptedSyntheticChildrenSP();
438 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
439 uint32_t num_categories = m_categories_map.GetCount();
440 lldb::TypeCategoryImplSP category_sp;
441 uint32_t prio_category = UINT32_MAX;
442 for (uint32_t category_id = 0;
443 category_id < num_categories;
446 category_sp = GetCategoryAtIndex(category_id);
447 if (category_sp->IsEnabled() == false)
449 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
450 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
452 prio_category = category_sp->GetEnabledPosition();
453 synth_chosen_sp = synth_current_sp;
456 return synth_chosen_sp;
460 #ifndef LLDB_DISABLE_PYTHON
461 lldb::SyntheticChildrenSP
462 FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
465 return lldb::SyntheticChildrenSP();
466 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
467 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
468 if (filter_sp->GetRevision() > synth_sp->GetRevision())
469 return lldb::SyntheticChildrenSP(filter_sp.get());
471 return lldb::SyntheticChildrenSP(synth_sp.get());
475 lldb::TypeValidatorImplSP
476 FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
479 return lldb::TypeValidatorImplSP();
480 lldb::TypeValidatorImplSP validator_chosen_sp;
481 uint32_t num_categories = m_categories_map.GetCount();
482 lldb::TypeCategoryImplSP category_sp;
483 uint32_t prio_category = UINT32_MAX;
484 for (uint32_t category_id = 0;
485 category_id < num_categories;
488 category_sp = GetCategoryAtIndex(category_id);
489 if (category_sp->IsEnabled() == false)
491 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
492 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
494 prio_category = category_sp->GetEnabledPosition();
495 validator_chosen_sp = validator_current_sp;
498 return validator_chosen_sp;
502 FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback)
504 m_categories_map.ForEach(callback);
505 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
506 for (const auto& entry : m_language_categories_map)
508 if (auto category_sp = entry.second->GetCategory())
510 if (!callback(category_sp))
516 lldb::TypeCategoryImplSP
517 FormatManager::GetCategory (const ConstString& category_name,
521 return GetCategory(m_default_category_name);
522 lldb::TypeCategoryImplSP category;
523 if (m_categories_map.Get(category_name, category))
527 return lldb::TypeCategoryImplSP();
529 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
530 return GetCategory(category_name);
534 FormatManager::GetSingleItemFormat(lldb::Format vector_format)
536 switch(vector_format)
538 case eFormatVectorOfChar:
539 return eFormatCharArray;
541 case eFormatVectorOfSInt8:
542 case eFormatVectorOfSInt16:
543 case eFormatVectorOfSInt32:
544 case eFormatVectorOfSInt64:
545 return eFormatDecimal;
547 case eFormatVectorOfUInt8:
548 case eFormatVectorOfUInt16:
549 case eFormatVectorOfUInt32:
550 case eFormatVectorOfUInt64:
551 case eFormatVectorOfUInt128:
554 case eFormatVectorOfFloat16:
555 case eFormatVectorOfFloat32:
556 case eFormatVectorOfFloat64:
560 return lldb::eFormatInvalid;
565 FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
567 // if settings say no oneline whatsoever
568 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
569 return false; // then don't oneline
571 // if this object has a summary, then ask the summary
572 if (valobj.GetSummaryFormat().get() != nullptr)
573 return valobj.GetSummaryFormat()->IsOneLiner();
575 // no children, no party
576 if (valobj.GetNumChildren() == 0)
579 // ask the type if it has any opinion about this
580 // eLazyBoolCalculate == no opinion; other values should be self explanatory
581 CompilerType compiler_type(valobj.GetCompilerType());
582 if (compiler_type.IsValid())
584 switch (compiler_type.ShouldPrintAsOneLiner(&valobj))
590 case eLazyBoolCalculate:
595 size_t total_children_name_len = 0;
598 idx < valobj.GetNumChildren();
601 bool is_synth_val = false;
602 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
603 // something is wrong here - bail out
607 // also ask the child's type if it has any opinion
608 CompilerType child_compiler_type(child_sp->GetCompilerType());
609 if (child_compiler_type.IsValid())
611 switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get()))
614 // an opinion of yes is only binding for the child, so keep going
615 case eLazyBoolCalculate:
618 // but if the child says no, then it's a veto on the whole thing
623 // if we decided to define synthetic children for a type, we probably care enough
624 // to show them, but avoid nesting children in children
625 if (child_sp->GetSyntheticChildren().get() != nullptr)
627 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
628 // wait.. wat? just get out of here..
631 // but if we only have them to provide a value, keep going
632 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
638 total_children_name_len += child_sp->GetName().GetLength();
640 // 50 itself is a "randomly" chosen number - the idea is that
641 // overly long structs should not get this treatment
642 // FIXME: maybe make this a user-tweakable setting?
643 if (total_children_name_len > 50)
646 // if a summary is there..
647 if (child_sp->GetSummaryFormat())
649 // and it wants children, then bail out
650 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
654 // if this child has children..
655 if (child_sp->GetNumChildren())
657 // ...and no summary...
658 // (if it had a summary and the summary wanted children, we would have bailed out anyway
659 // so this only makes us bail out if this has no summary and we would then print children)
660 if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do that if not a synthetic valued child
661 return false; // then bail out
668 FormatManager::GetValidTypeName (const ConstString& type)
670 return ::GetValidTypeName_Impl(type);
674 FormatManager::GetTypeForCache (ValueObject& valobj,
675 lldb::DynamicValueType use_dynamic)
677 ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(use_dynamic, valobj.IsSynthetic());
678 if (valobj_sp && valobj_sp->GetCompilerType().IsValid())
680 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
681 return valobj_sp->GetQualifiedTypeName();
683 return ConstString();
686 std::vector<lldb::LanguageType>
687 FormatManager::GetCandidateLanguages (ValueObject& valobj)
689 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
690 return GetCandidateLanguages(lang_type);
693 std::vector<lldb::LanguageType>
694 FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
698 case lldb::eLanguageTypeC:
699 case lldb::eLanguageTypeC89:
700 case lldb::eLanguageTypeC99:
701 case lldb::eLanguageTypeC11:
702 case lldb::eLanguageTypeC_plus_plus:
703 case lldb::eLanguageTypeC_plus_plus_03:
704 case lldb::eLanguageTypeC_plus_plus_11:
705 case lldb::eLanguageTypeC_plus_plus_14:
706 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
713 FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
715 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
716 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
718 return iter->second.get();
719 LanguageCategory* lang_category = new LanguageCategory(lang_type);
720 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
721 return lang_category;
724 lldb::TypeFormatImplSP
725 FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
727 TypeFormatImplSP retval_sp;
729 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
731 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
733 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
741 lldb::TypeFormatImplSP
742 FormatManager::GetFormat (ValueObject& valobj,
743 lldb::DynamicValueType use_dynamic)
745 FormattersMatchData match_data(valobj, use_dynamic);
747 TypeFormatImplSP retval;
748 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
749 if (match_data.GetTypeForCache())
752 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
753 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
757 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
759 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
764 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
767 retval = m_categories_map.GetFormat(match_data);
771 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
772 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
774 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
776 if (lang_category->Get(match_data, retval))
783 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
790 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
791 retval = GetHardcodedFormat(match_data);
794 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
797 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
798 static_cast<void*>(retval.get()),
799 match_data.GetTypeForCache().AsCString("<invalid>"));
800 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
802 if (log && log->GetDebug())
803 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
807 lldb::TypeSummaryImplSP
808 FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
810 TypeSummaryImplSP retval_sp;
812 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
814 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
816 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
824 lldb::TypeSummaryImplSP
825 FormatManager::GetSummaryFormat (ValueObject& valobj,
826 lldb::DynamicValueType use_dynamic)
828 FormattersMatchData match_data(valobj, use_dynamic);
830 TypeSummaryImplSP retval;
831 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
832 if (match_data.GetTypeForCache())
835 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
836 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
840 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
842 log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
847 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
850 retval = m_categories_map.GetSummaryFormat(match_data);
854 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
855 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
857 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
859 if (lang_category->Get(match_data, retval))
866 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
873 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
874 retval = GetHardcodedSummaryFormat(match_data);
877 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
880 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
881 static_cast<void*>(retval.get()),
882 match_data.GetTypeForCache().AsCString("<invalid>"));
883 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
885 if (log && log->GetDebug())
886 log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
890 #ifndef LLDB_DISABLE_PYTHON
891 lldb::SyntheticChildrenSP
892 FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
894 SyntheticChildrenSP retval_sp;
896 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
898 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
900 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
908 lldb::SyntheticChildrenSP
909 FormatManager::GetSyntheticChildren (ValueObject& valobj,
910 lldb::DynamicValueType use_dynamic)
912 FormattersMatchData match_data(valobj, use_dynamic);
914 SyntheticChildrenSP retval;
915 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
916 if (match_data.GetTypeForCache())
919 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
920 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
924 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
926 log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
931 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
934 retval = m_categories_map.GetSyntheticChildren(match_data);
938 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
939 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
941 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
943 if (lang_category->Get(match_data, retval))
950 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
957 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
958 retval = GetHardcodedSyntheticChildren(match_data);
961 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
964 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
965 static_cast<void*>(retval.get()),
966 match_data.GetTypeForCache().AsCString("<invalid>"));
967 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
969 if (log && log->GetDebug())
970 log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
975 lldb::TypeValidatorImplSP
976 FormatManager::GetValidator (ValueObject& valobj,
977 lldb::DynamicValueType use_dynamic)
979 FormattersMatchData match_data(valobj, use_dynamic);
981 TypeValidatorImplSP retval;
982 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
983 if (match_data.GetTypeForCache())
986 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
987 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
991 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
993 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
998 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
1001 retval = m_categories_map.GetValidator(match_data);
1005 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
1006 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
1008 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1010 if (lang_category->Get(match_data, retval))
1017 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
1024 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
1025 retval = GetHardcodedValidator(match_data);
1028 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
1031 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1032 static_cast<void*>(retval.get()),
1033 match_data.GetTypeForCache().AsCString("<invalid>"));
1034 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
1036 if (log && log->GetDebug())
1037 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1041 lldb::TypeValidatorImplSP
1042 FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
1044 TypeValidatorImplSP retval_sp;
1046 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
1048 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1050 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
1058 FormatManager::FormatManager()
1059 : m_last_revision(0),
1061 m_language_categories_mutex(),
1062 m_language_categories_map(),
1063 m_named_summaries_map(this),
1064 m_categories_map(this),
1065 m_default_category_name(ConstString("default")),
1066 m_system_category_name(ConstString("system")),
1067 m_vectortypes_category_name(ConstString("VectorTypes"))
1069 LoadSystemFormatters();
1070 LoadVectorFormatters();
1072 EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1073 EnableCategory(m_system_category_name, TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1077 FormatManager::LoadSystemFormatters()
1079 TypeSummaryImpl::Flags string_flags;
1080 string_flags.SetCascades(true)
1081 .SetSkipPointers(true)
1082 .SetSkipReferences(false)
1083 .SetDontShowChildren(true)
1084 .SetDontShowValue(false)
1085 .SetShowMembersOneLiner(false)
1086 .SetHideItemNames(false);
1088 TypeSummaryImpl::Flags string_array_flags;
1089 string_array_flags.SetCascades(true)
1090 .SetSkipPointers(true)
1091 .SetSkipReferences(false)
1092 .SetDontShowChildren(true)
1093 .SetDontShowValue(true)
1094 .SetShowMembersOneLiner(false)
1095 .SetHideItemNames(false);
1097 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
1100 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
1103 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
1104 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
1106 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
1108 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1109 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1110 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
1112 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1113 .SetSkipPointers(true)
1114 .SetSkipReferences(true)
1115 .SetDontShowChildren(true)
1116 .SetDontShowValue(false)
1117 .SetShowMembersOneLiner(false)
1118 .SetHideItemNames(false),
1121 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
1123 #ifndef LLDB_DISABLE_PYTHON
1124 TypeFormatImpl::Flags fourchar_flags;
1125 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1127 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
1132 FormatManager::LoadVectorFormatters()
1134 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
1136 TypeSummaryImpl::Flags vector_flags;
1137 vector_flags.SetCascades(true)
1138 .SetSkipPointers(true)
1139 .SetSkipReferences(false)
1140 .SetDontShowChildren(true)
1141 .SetDontShowValue(false)
1142 .SetShowMembersOneLiner(true)
1143 .SetHideItemNames(true);
1145 AddStringSummary(vectors_category_sp,
1147 ConstString("builtin_type_vec128"),
1150 AddStringSummary(vectors_category_sp,
1152 ConstString("float [4]"),
1154 AddStringSummary(vectors_category_sp,
1156 ConstString("int32_t [4]"),
1158 AddStringSummary(vectors_category_sp,
1160 ConstString("int16_t [8]"),
1162 AddStringSummary(vectors_category_sp,
1164 ConstString("vDouble"),
1166 AddStringSummary(vectors_category_sp,
1168 ConstString("vFloat"),
1170 AddStringSummary(vectors_category_sp,
1172 ConstString("vSInt8"),
1174 AddStringSummary(vectors_category_sp,
1176 ConstString("vSInt16"),
1178 AddStringSummary(vectors_category_sp,
1180 ConstString("vSInt32"),
1182 AddStringSummary(vectors_category_sp,
1184 ConstString("vUInt16"),
1186 AddStringSummary(vectors_category_sp,
1188 ConstString("vUInt8"),
1190 AddStringSummary(vectors_category_sp,
1192 ConstString("vUInt16"),
1194 AddStringSummary(vectors_category_sp,
1196 ConstString("vUInt32"),
1198 AddStringSummary(vectors_category_sp,
1200 ConstString("vBool32"),