18 #include "llvm/ADT/STLExtras.h"
77 "All formats must have a corresponding info entry.");
93 bool partial_match_ok,
Format &format) {
102 if (partial_match_ok) {
105 .startswith_insensitive(format_name)) {
115 void FormatManager::Changed() {
117 m_format_cache.Clear();
118 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
119 for (
auto &iter : m_language_categories_map) {
121 iter.second->GetFormatCache().Clear();
125 bool FormatManager::GetFormatFromCString(
const char *format_cstr,
126 bool partial_match_ok,
128 bool success =
false;
129 if (format_cstr && format_cstr[0]) {
130 if (format_cstr[1] ==
'\0') {
151 const char *FormatManager::GetFormatAsCString(
Format format) {
157 void FormatManager::EnableAllCategories() {
158 m_categories_map.EnableAllCategories();
159 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
160 for (
auto &iter : m_language_categories_map) {
162 iter.second->Enable();
166 void FormatManager::DisableAllCategories() {
167 m_categories_map.DisableAllCategories();
168 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
169 for (
auto &iter : m_language_categories_map) {
171 iter.second->Disable();
175 void FormatManager::GetPossibleMatches(
185 entries.push_back({bitfieldname, current_flags});
189 entries.push_back({type_name, current_flags});
192 if (display_type_name != type_name)
193 entries.push_back({display_type_name, current_flags});
196 for (
bool is_rvalue_ref =
true, j =
true;
197 j && compiler_type.
IsReferenceType(
nullptr, &is_rvalue_ref); j =
false) {
199 GetPossibleMatches(valobj, non_ref_type, use_dynamic, entries,
203 deffed_referenced_type =
208 valobj, deffed_referenced_type,
215 GetPossibleMatches(valobj, non_ptr_type, use_dynamic, entries,
221 GetPossibleMatches(valobj, deffed_pointed_type, use_dynamic, entries,
229 if (compiler_type.
IsArrayType(
nullptr, &array_size,
nullptr)) {
240 valobj, deffed_array_type,
247 if (
Language *language = Language::FindPlugin(language_type)) {
249 language->GetPossibleFormattersMatches(valobj, use_dynamic)) {
250 entries.push_back({candidate, current_flags});
258 GetPossibleMatches(valobj, deffed_type, use_dynamic, entries,
269 if (!unqual_compiler_ast_type.
IsValid())
273 GetPossibleMatches(valobj, unqual_compiler_ast_type, use_dynamic,
274 entries, current_flags);
281 GetPossibleMatches(*static_value_sp.get(),
282 static_value_sp->GetCompilerType(), use_dynamic,
283 entries, current_flags,
true);
288 lldb::TypeFormatImplSP
289 FormatManager::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
291 return lldb::TypeFormatImplSP();
292 lldb::TypeFormatImplSP format_chosen_sp;
293 uint32_t num_categories = m_categories_map.GetCount();
294 lldb::TypeCategoryImplSP category_sp;
296 for (
uint32_t category_id = 0; category_id < num_categories; category_id++) {
297 category_sp = GetCategoryAtIndex(category_id);
298 if (!category_sp->IsEnabled())
300 lldb::TypeFormatImplSP format_current_sp =
301 category_sp->GetFormatForType(type_sp);
302 if (format_current_sp &&
303 (format_chosen_sp.get() ==
nullptr ||
304 (prio_category > category_sp->GetEnabledPosition()))) {
305 prio_category = category_sp->GetEnabledPosition();
306 format_chosen_sp = format_current_sp;
309 return format_chosen_sp;
312 lldb::TypeSummaryImplSP
313 FormatManager::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
315 return lldb::TypeSummaryImplSP();
316 lldb::TypeSummaryImplSP summary_chosen_sp;
317 uint32_t num_categories = m_categories_map.GetCount();
318 lldb::TypeCategoryImplSP category_sp;
320 for (
uint32_t category_id = 0; category_id < num_categories; category_id++) {
321 category_sp = GetCategoryAtIndex(category_id);
322 if (!category_sp->IsEnabled())
324 lldb::TypeSummaryImplSP summary_current_sp =
325 category_sp->GetSummaryForType(type_sp);
326 if (summary_current_sp &&
327 (summary_chosen_sp.get() ==
nullptr ||
328 (prio_category > category_sp->GetEnabledPosition()))) {
329 prio_category = category_sp->GetEnabledPosition();
330 summary_chosen_sp = summary_current_sp;
333 return summary_chosen_sp;
336 lldb::TypeFilterImplSP
337 FormatManager::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
339 return lldb::TypeFilterImplSP();
340 lldb::TypeFilterImplSP filter_chosen_sp;
341 uint32_t num_categories = m_categories_map.GetCount();
342 lldb::TypeCategoryImplSP category_sp;
344 for (
uint32_t category_id = 0; category_id < num_categories; category_id++) {
345 category_sp = GetCategoryAtIndex(category_id);
346 if (!category_sp->IsEnabled())
348 lldb::TypeFilterImplSP filter_current_sp(
350 if (filter_current_sp &&
351 (filter_chosen_sp.get() ==
nullptr ||
352 (prio_category > category_sp->GetEnabledPosition()))) {
353 prio_category = category_sp->GetEnabledPosition();
354 filter_chosen_sp = filter_current_sp;
357 return filter_chosen_sp;
360 lldb::ScriptedSyntheticChildrenSP
361 FormatManager::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
363 return lldb::ScriptedSyntheticChildrenSP();
364 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
365 uint32_t num_categories = m_categories_map.GetCount();
366 lldb::TypeCategoryImplSP category_sp;
368 for (
uint32_t category_id = 0; category_id < num_categories; category_id++) {
369 category_sp = GetCategoryAtIndex(category_id);
370 if (!category_sp->IsEnabled())
372 lldb::ScriptedSyntheticChildrenSP synth_current_sp(
375 if (synth_current_sp &&
376 (synth_chosen_sp.get() ==
nullptr ||
377 (prio_category > category_sp->GetEnabledPosition()))) {
378 prio_category = category_sp->GetEnabledPosition();
379 synth_chosen_sp = synth_current_sp;
382 return synth_chosen_sp;
386 m_categories_map.ForEach(callback);
387 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
388 for (
const auto &entry : m_language_categories_map) {
389 if (
auto category_sp = entry.second->GetCategory()) {
390 if (!callback(category_sp))
396 lldb::TypeCategoryImplSP
397 FormatManager::GetCategory(
ConstString category_name,
bool can_create) {
399 return GetCategory(m_default_category_name);
400 lldb::TypeCategoryImplSP category;
401 if (m_categories_map.Get(category_name, category))
405 return lldb::TypeCategoryImplSP();
407 m_categories_map.Add(
410 return GetCategory(category_name);
414 switch (vector_format) {
444 !valobj.
GetTargetSP()->GetDebugger().GetAutoOneLineSummaries())
469 size_t total_children_name_len = 0;
472 bool is_synth_val =
false;
479 CompilerType child_compiler_type(child_sp->GetCompilerType());
480 if (child_compiler_type.
IsValid()) {
494 if (child_sp->GetSyntheticChildren().get() !=
nullptr) {
495 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
500 if (!synth_sp->MightHaveChildren() &&
501 synth_sp->DoesProvideSyntheticValue())
507 total_children_name_len += child_sp->GetName().GetLength();
512 if (total_children_name_len > 50)
516 if (child_sp->GetSummaryFormat()) {
518 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
523 if (child_sp->GetNumChildren()) {
529 if (!child_sp->GetSummaryFormat() && !is_synth_val)
543 if (valobj_sp && valobj_sp->GetCompilerType().IsValid()) {
544 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
545 return valobj_sp->GetQualifiedTypeName();
550 std::vector<lldb::LanguageType>
565 llvm_unreachable(
"Fully covered switch");
570 std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
571 auto iter = m_language_categories_map.find(lang_type),
572 end = m_language_categories_map.end();
574 return iter->second.get();
576 m_language_categories_map[lang_type] =
578 return lang_category;
581 template <
typename ImplSP>
586 if (lang_category->GetHardcoded(*
this, match_data, retval_sp))
593 template <
typename ImplSP>
597 if (ImplSP retval_sp = GetCached<ImplSP>(match_data))
600 Log *log =
GetLog(LLDBLog::DataFormatters);
602 LLDB_LOGF(log,
"[%s] Search failed. Giving language a chance.", __FUNCTION__);
606 if (lang_category->Get(match_data, retval_sp))
608 LLDB_LOGF(log,
"[%s] Language search success. Returning.",
615 LLDB_LOGF(log,
"[%s] Search failed. Giving hardcoded a chance.",
617 return GetHardcoded<ImplSP>(match_data);
620 template <
typename ImplSP>
623 Log *log =
GetLog(LLDBLog::DataFormatters);
625 LLDB_LOGF(log,
"\n\n[%s] Looking into cache for type %s", __FUNCTION__,
629 LLDB_LOGF(log,
"[%s] Cache search success. Returning.", __FUNCTION__);
630 LLDB_LOGV(log,
"Cache hits: {0} - Cache Misses: {1}",
631 m_format_cache.GetCacheHits(),
632 m_format_cache.GetCacheMisses());
636 LLDB_LOGF(log,
"[%s] Cache search failed. Going normal route",
640 m_categories_map.Get(match_data, retval_sp);
641 if (match_data.
GetTypeForCache() && (!retval_sp || !retval_sp->NonCacheable())) {
642 LLDB_LOGF(log,
"[%s] Caching %p for type %s", __FUNCTION__,
643 static_cast<void *
>(retval_sp.get()),
647 LLDB_LOGV(log,
"Cache hits: {0} - Cache Misses: {1}",
648 m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
652 lldb::TypeFormatImplSP
655 return Get<lldb::TypeFormatImplSP>(valobj, use_dynamic);
658 lldb::TypeSummaryImplSP
661 return Get<lldb::TypeSummaryImplSP>(valobj, use_dynamic);
664 lldb::SyntheticChildrenSP
667 return Get<lldb::SyntheticChildrenSP>(valobj, use_dynamic);
670 FormatManager::FormatManager()
671 : m_last_revision(0), m_format_cache(), m_language_categories_mutex(),
672 m_language_categories_map(), m_named_summaries_map(this),
673 m_categories_map(this), m_default_category_name(
ConstString(
"default")),
675 m_vectortypes_category_name(
ConstString(
"VectorTypes")) {
704 lldb::TypeSummaryImplSP string_format(
707 lldb::TypeSummaryImplSP string_array_format(
715 sys_category_sp->GetRegexTypeSummariesContainer()->Add(
718 sys_category_sp->GetRegexTypeSummariesContainer()->Add(
719 std::move(any_size_char_arr), string_array_format);
721 lldb::TypeSummaryImplSP ostype_summary(
724 .SetSkipPointers(
true)
725 .SetSkipReferences(
true)
726 .SetDontShowChildren(
true)
727 .SetDontShowValue(
false)
728 .SetShowMembersOneLiner(
false)
729 .SetHideItemNames(
false),
732 sys_category_sp->GetTypeSummariesContainer()->Add(
ConstString(
"OSType"),