aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/DataFormatters/FormatManager.cpp
diff options
context:
space:
mode:
authorZequan Wu <zequanwu@google.com>2025-05-28 13:04:24 -0700
committerGitHub <noreply@github.com>2025-05-28 16:04:24 -0400
commit02916a432ca6465e2e45f67be94f1c89c9cd425d (patch)
tree60ff8ca17dcc87eabb23ae21d1dc1ec90d4eb063 /lldb/source/DataFormatters/FormatManager.cpp
parentcb7f4ff03cc20b04360d75f78e2255214a617d5f (diff)
downloadllvm-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.cpp40
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);
}
}
}