]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Fix parent of enumerator
authorTom de Vries <tdevries@suse.de>
Tue, 8 Oct 2024 10:27:20 +0000 (12:27 +0200)
committerTom de Vries <tdevries@suse.de>
Tue, 8 Oct 2024 10:27:20 +0000 (12:27 +0200)
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.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/dwarf2/read.c
gdb/testsuite/gdb.dwarf2/enum-type.exp

index bf9eeef3820bc582f97e32adc2b7ef2f817e8c47..95e7d6aee31a6bc288d738db335d0ae01cea2e65 100644 (file)
@@ -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.
@@ -4530,7 +4531,7 @@ private:
                                 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
@@ -4538,7 +4539,8 @@ private:
      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
@@ -4568,7 +4570,8 @@ private:
      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.  */
@@ -16466,10 +16469,16 @@ 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 (!std::holds_alternative<const cooked_index_entry *> (parent))
+    return info_ptr;
+  const cooked_index_entry *parent_entry
+    = std::get<const cooked_index_entry *> (parent);
 
   if (parent_entry != nullptr)
     {
@@ -16490,7 +16499,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
@@ -16517,15 +16527,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 (std::holds_alternative<parent_map::addr_type> (parent))
+       defer = std::get<parent_map::addr_type> (parent);
       cooked_index_flag flags = IS_STATIC;
       sect_offset sibling {};
+      const cooked_index_entry *parent_entry = nullptr;
+      if (std::holds_alternative<const cooked_index_entry *> (parent))
+       parent_entry = std::get<const cooked_index_entry *> (parent);
       const cooked_index_entry *this_parent_entry = parent_entry;
       bool is_enum_class = false;
 
@@ -16609,9 +16624,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:
index b2b3dc6c8287d0fc47eb5b0df1d1a44953a7eaeb..ec12db57c8cc240c02ad0cc91533acabef442a9c 100644 (file)
@@ -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" \
+        ".*"]