diff options
author | Zequan Wu <zequanwu@google.com> | 2025-05-28 13:04:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-28 16:04:24 -0400 |
commit | 02916a432ca6465e2e45f67be94f1c89c9cd425d (patch) | |
tree | 60ff8ca17dcc87eabb23ae21d1dc1ec90d4eb063 /lldb/source/DataFormatters/FormatManager.cpp | |
parent | cb7f4ff03cc20b04360d75f78e2255214a617d5f (diff) | |
download | llvm-02916a432ca6465e2e45f67be94f1c89c9cd425d.zip llvm-02916a432ca6465e2e45f67be94f1c89c9cd425d.tar.gz llvm-02916a432ca6465e2e45f67be94f1c89c9cd425d.tar.bz2 |
[lldb][Formatters] Add --pointer-match-depth option to `type summary add` command. (#138209)
Currently, the type `T`'s summary formatter will be matched for `T`,
`T*`, `T**` and so on. This is unexpected in many data formatters. Such
unhandled cases could cause the data formatter to crash. An example
would be the lldb's built-in data formatter for `std::optional`:
```
$ cat main.cpp
#include <optional>
int main() {
std::optional<int> o_null;
auto po_null = &o_null;
auto ppo_null = &po_null;
auto pppo_null = &ppo_null;
return 0;
}
$ clang++ -g main.cpp && lldb -o "b 8" -o "r" -o "v pppo_null"
[lldb crash]
```
This change adds an options `--pointer-match-depth` to `type summary
add` command to allow users to specify how many layer of pointers can be
dereferenced at most when matching a summary formatter of type `T`, as
Jim suggested
[here](https://github.com/llvm/llvm-project/pull/124048/#issuecomment-2611164133).
By default, this option has value 1 which means summary formatter for
`T` could also be used for `T*` but not `T**` nor beyond. This option is
no-op when `--skip-pointers` is set as well.
I didn't add such option for `type synthetic add`, `type format add`,
`type filter add`, because it useful for those command. Instead, they
all have the pointer match depth of 1. When printing a type `T*`, lldb
never print the children of `T` even if there is a synthetic formatter
registered for `T`.
Diffstat (limited to 'lldb/source/DataFormatters/FormatManager.cpp')
-rw-r--r-- | lldb/source/DataFormatters/FormatManager.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index 3b891ce..122f230 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -174,7 +174,8 @@ void FormatManager::DisableAllCategories() { void FormatManager::GetPossibleMatches( ValueObject &valobj, CompilerType compiler_type, lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries, - FormattersMatchCandidate::Flags current_flags, bool root_level) { + FormattersMatchCandidate::Flags current_flags, bool root_level, + uint32_t ptr_stripped_depth) { compiler_type = compiler_type.GetTypeForFormatters(); ConstString type_name(compiler_type.GetTypeName()); // A ValueObject that couldn't be made correctly won't necessarily have a @@ -190,46 +191,51 @@ void FormatManager::GetPossibleMatches( sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize()); ConstString bitfieldname(sstring.GetString()); entries.push_back({bitfieldname, script_interpreter, - TypeImpl(compiler_type), current_flags}); + TypeImpl(compiler_type), current_flags, + ptr_stripped_depth}); } if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) { entries.push_back({type_name, script_interpreter, TypeImpl(compiler_type), - current_flags}); + current_flags, ptr_stripped_depth}); ConstString display_type_name(compiler_type.GetTypeName()); if (display_type_name != type_name) entries.push_back({display_type_name, script_interpreter, - TypeImpl(compiler_type), current_flags}); + TypeImpl(compiler_type), current_flags, + ptr_stripped_depth}); } 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, use_dynamic, entries, - current_flags.WithStrippedReference()); + current_flags.WithStrippedReference(), root_level, + ptr_stripped_depth); 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(); // this is not exactly the usual meaning of stripping typedefs - GetPossibleMatches( - valobj, deffed_referenced_type, - use_dynamic, entries, current_flags.WithStrippedTypedef()); + GetPossibleMatches(valobj, deffed_referenced_type, use_dynamic, entries, + current_flags.WithStrippedTypedef(), root_level, + ptr_stripped_depth); } } if (compiler_type.IsPointerType()) { CompilerType non_ptr_type = compiler_type.GetPointeeType(); GetPossibleMatches(valobj, non_ptr_type, use_dynamic, entries, - current_flags.WithStrippedPointer()); + current_flags.WithStrippedPointer(), root_level, + ptr_stripped_depth + 1); if (non_ptr_type.IsTypedefType()) { CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType(); // this is not exactly the usual meaning of stripping typedefs GetPossibleMatches(valobj, deffed_pointed_type, use_dynamic, entries, - current_flags.WithStrippedTypedef()); + current_flags.WithStrippedTypedef(), root_level, + ptr_stripped_depth + 1); } } @@ -246,9 +252,9 @@ void FormatManager::GetPossibleMatches( CompilerType deffed_array_type = element_type.GetTypedefedType().GetArrayType(array_size); // this is not exactly the usual meaning of stripping typedefs - GetPossibleMatches( - valobj, deffed_array_type, - use_dynamic, entries, current_flags.WithStrippedTypedef()); + GetPossibleMatches(valobj, deffed_array_type, use_dynamic, entries, + current_flags.WithStrippedTypedef(), root_level, + ptr_stripped_depth); } } @@ -266,7 +272,8 @@ void FormatManager::GetPossibleMatches( if (compiler_type.IsTypedefType()) { CompilerType deffed_type = compiler_type.GetTypedefedType(); GetPossibleMatches(valobj, deffed_type, use_dynamic, entries, - current_flags.WithStrippedTypedef()); + current_flags.WithStrippedTypedef(), root_level, + ptr_stripped_depth); } if (root_level) { @@ -281,7 +288,8 @@ void FormatManager::GetPossibleMatches( if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType()) GetPossibleMatches(valobj, unqual_compiler_ast_type, use_dynamic, - entries, current_flags); + entries, current_flags, root_level, + ptr_stripped_depth); } while (false); // if all else fails, go to static type @@ -290,7 +298,7 @@ void FormatManager::GetPossibleMatches( if (static_value_sp) GetPossibleMatches(*static_value_sp.get(), static_value_sp->GetCompilerType(), use_dynamic, - entries, current_flags, true); + entries, current_flags, true, ptr_stripped_depth); } } } |