[v2,1/2,gdb/symtab] Fix parent of enumerator
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
As mentioned in commit 489b82720f5 ('[gdb/symtab] Revert "Change handling of
DW_TAG_enumeration_type in DWARF scanner"'), when doing "maint print objfiles" in
test-case gdb.dwarf2/enum-type.exp, for val1 we get an entry without parent:
...
[27] ((cooked_index_entry *) 0x7fbbb4002ef0)
name: val1
canonical: val1
qualified: val1
DWARF tag: DW_TAG_enumerator
flags: 0x0 []
DIE offset: 0x124
parent: ((cooked_index_entry *) 0)
...
This happens here in cooked_indexer::index_dies:
...
info_ptr = recurse (reader, info_ptr,
is_enum_class ? this_entry : parent_entry,
fully);
...
when we're passing down a nullptr parent_entry, while the parent of this_entry
is deferred.
Fix this in cooked_indexer::index_dies by passing down a deffered parent
instead, such that we get:
...
[27] ((cooked_index_entry *) 0x7ff0e4002ef0)^M
name: val1^M
canonical: val1^M
qualified: ns::val1^M
DWARF tag: DW_TAG_enumerator^M
flags: 0x0 []^M
DIE offset: 0x124^M
parent: ((cooked_index_entry *) 0x7ff0e4002f20) [ns]^M
...
Tested on x86_64-linux.
---
gdb/dwarf2/read.c | 46 ++++++++++++++++++++------
gdb/testsuite/gdb.dwarf2/enum-type.exp | 15 +++++++++
2 files changed, 51 insertions(+), 10 deletions(-)
base-commit: 174e5e38b92c2cd381feffa644de2b12ce0980a8
Comments
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
Tom> + if (parent.index () != 0)
Tom> + return info_ptr;
Tom> + const cooked_index_entry *parent_entry = std::get<0> (parent);
I think these spots would be nicer if checking was done with
std::holds_alternative and fetching was done with the type-based
std::get (e.g. std::get<const cooked_index_entry *>)
thanks,
Tom
On 9/27/24 20:24, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
>
> Tom> + if (parent.index () != 0)
> Tom> + return info_ptr;
> Tom> + const cooked_index_entry *parent_entry = std::get<0> (parent);
>
> I think these spots would be nicer if checking was done with
> std::holds_alternative and fetching was done with the type-based
> std::get (e.g. std::get<const cooked_index_entry *>)
Hi Tom,
thanks for the reviews.
I'll fix this and push the series after I come back from my vacation in
a week.
Can I add an approved-by/reviewed-by tag from you, or did you have other
comments?
Thanks,
- Tom
Tom> Can I add an approved-by/reviewed-by tag from you, or did you have
Tom> other comments?
Yeah, that's fine, sorry I didn't do it the first time around. Thanks.
Tom
@@ -96,6 +96,7 @@
#include "run-on-main-thread.h"
#include "dwarf2/parent-map.h"
#include "dwarf2/error.h"
+#include <variant>
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
@@ -4486,7 +4487,7 @@ class cooked_indexer
bool is_dwz,
bool for_scanning);
- /* Index DIEs in the READER starting at INFO_PTR. PARENT_ENTRY is
+ /* Index DIEs in the READER starting at INFO_PTR. PARENT is
the entry for the enclosing scope (nullptr at top level). FULLY
is true when a full scan must be done -- in some languages,
function scopes must be fully explored in order to find nested
@@ -4494,7 +4495,8 @@ class cooked_indexer
reading stopped. */
const gdb_byte *index_dies (cutu_reader *reader,
const gdb_byte *info_ptr,
- const cooked_index_entry *parent_entry,
+ std::variant<const cooked_index_entry *,
+ parent_map::addr_type> parent,
bool fully);
/* Scan the attributes for a given DIE and update the out
@@ -4524,7 +4526,8 @@ class cooked_indexer
m_die_range_map and then calling index_dies. */
const gdb_byte *recurse (cutu_reader *reader,
const gdb_byte *info_ptr,
- const cooked_index_entry *parent_entry,
+ std::variant<const cooked_index_entry *,
+ parent_map::addr_type> parent_entry,
bool fully);
/* The storage object, where the results are kept. */
@@ -16417,10 +16420,15 @@ cooked_indexer::index_imported_unit (cutu_reader *reader,
const gdb_byte *
cooked_indexer::recurse (cutu_reader *reader,
const gdb_byte *info_ptr,
- const cooked_index_entry *parent_entry,
+ std::variant<const cooked_index_entry *,
+ parent_map::addr_type> parent,
bool fully)
{
- info_ptr = index_dies (reader, info_ptr, parent_entry, fully);
+ info_ptr = index_dies (reader, info_ptr, parent, fully);
+
+ if (parent.index () != 0)
+ return info_ptr;
+ const cooked_index_entry *parent_entry = std::get<0> (parent);
if (parent_entry != nullptr)
{
@@ -16441,7 +16449,8 @@ cooked_indexer::recurse (cutu_reader *reader,
const gdb_byte *
cooked_indexer::index_dies (cutu_reader *reader,
const gdb_byte *info_ptr,
- const cooked_index_entry *parent_entry,
+ std::variant<const cooked_index_entry *,
+ parent_map::addr_type> parent,
bool fully)
{
const gdb_byte *end_ptr = (reader->buffer
@@ -16468,15 +16477,20 @@ cooked_indexer::index_dies (cutu_reader *reader,
{
info_ptr = skip_one_die (reader, info_ptr, abbrev, !fully);
if (fully && abbrev->has_children)
- info_ptr = index_dies (reader, info_ptr, parent_entry, fully);
+ info_ptr = index_dies (reader, info_ptr, parent, fully);
continue;
}
const char *name = nullptr;
const char *linkage_name = nullptr;
parent_map::addr_type defer {};
+ if (parent.index () == 1)
+ defer = std::get<1> (parent);
cooked_index_flag flags = IS_STATIC;
sect_offset sibling {};
+ const cooked_index_entry *parent_entry = nullptr;
+ if (parent.index () == 0)
+ parent_entry = std::get<0> (parent);
const cooked_index_entry *this_parent_entry = parent_entry;
bool is_enum_class = false;
@@ -16560,9 +16574,21 @@ cooked_indexer::index_dies (cutu_reader *reader,
the enum itself as the parent, yielding names like
"enum_class::enumerator"; otherwise we inject the
names into our own parent scope. */
- info_ptr = recurse (reader, info_ptr,
- is_enum_class ? this_entry : parent_entry,
- fully);
+ {
+ std::variant<const cooked_index_entry *,
+ parent_map::addr_type> recurse_parent;
+ if (is_enum_class)
+ {
+ gdb_assert (this_entry != nullptr);
+ recurse_parent = this_entry;
+ }
+ else if (defer != 0)
+ recurse_parent = defer;
+ else
+ recurse_parent = parent_entry;
+
+ info_ptr = recurse (reader, info_ptr, recurse_parent, fully);
+ }
continue;
case DW_TAG_module:
@@ -114,3 +114,18 @@ gdb_test "ptype enum EU" "type = enum EU {TWO = 2}" \
gdb_test_no_output "set lang c++"
gdb_test "ptype enum EU" "type = enum EU : unsigned int {TWO = 2}" \
"ptype EU in C++"
+
+gdb_test "p ns::val1" \
+ " = ns::val1"
+
+require !readnow
+require {string equal [have_index $binfile] ""}
+
+set re_ws "\[ \t\]"
+
+gdb_test_lines "maint print objfiles" \
+ "val1 has a parent" \
+ [multi_line \
+ "" \
+ "$re_ws+qualified:$re_ws+ns::val1" \
+ ".*"]