void FormatManager::GetPossibleMatches( ValueObject &valobj, CompilerType compiler_type, uint32_t reason, lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries, bool did_strip_ptr, bool did_strip_ref, bool did_strip_typedef, bool root_level) { compiler_type = compiler_type.GetTypeForFormatters(); ConstString type_name(compiler_type.GetConstTypeName()); if (valobj.GetBitfieldBitSize() > 0) { StreamString sstring; sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize()); ConstString bitfieldname(sstring.GetString()); entries.push_back( {bitfieldname, 0, did_strip_ptr, did_strip_ref, did_strip_typedef}); reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField; } if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) { entries.push_back( {type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef}); ConstString display_type_name(compiler_type.GetDisplayTypeName()); if (display_type_name != type_name) entries.push_back({display_type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef}); } for (bool is_rvalue_ref = true, j = true; j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false) { CompilerType non_ref_type = compiler_type.GetNonReferenceType(); GetPossibleMatches( valobj, non_ref_type, reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference, use_dynamic, entries, did_strip_ptr, true, did_strip_typedef); if (non_ref_type.IsTypedefType()) { CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType(); deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType(); GetPossibleMatches( valobj, deffed_referenced_type, reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, true); // this is not exactly the usual meaning of stripping typedefs } } if (compiler_type.IsPointerType()) { CompilerType non_ptr_type = compiler_type.GetPointeeType(); GetPossibleMatches( valobj, non_ptr_type, reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference, use_dynamic, entries, true, did_strip_ref, did_strip_typedef); if (non_ptr_type.IsTypedefType()) { CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType(); GetPossibleMatches( valobj, deffed_pointed_type, reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, true); // this is not exactly the usual meaning of stripping typedefs } } for (lldb::LanguageType language_type : GetCandidateLanguages(valobj)) { if (Language *language = Language::FindPlugin(language_type)) { for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic)) { entries.push_back( {candidate, reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin, did_strip_ptr, did_strip_ref, did_strip_typedef}); } } } // try to strip typedef chains if (compiler_type.IsTypedefType()) { CompilerType deffed_type = compiler_type.GetTypedefedType(); GetPossibleMatches( valobj, deffed_type, reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, true); } if (root_level) { do { if (!compiler_type.IsValid()) break; CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType(); if (!unqual_compiler_ast_type.IsValid()) break; if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType()) GetPossibleMatches(valobj, unqual_compiler_ast_type, reason, use_dynamic, entries, did_strip_ptr, did_strip_ref, did_strip_typedef); } while (false); // if all else fails, go to static type if (valobj.IsDynamic()) { lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue()); if (static_value_sp) GetPossibleMatches( *static_value_sp.get(), static_value_sp->GetCompilerType(), reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue, use_dynamic, entries, did_strip_ptr, did_strip_ref, did_strip_typedef, true); } } }