[PATCH v2 08/28] Entries from anon-struct.exp not in cooked index

Tom Tromey
2025-04-02T23:54:53Z

g++ will sometimes use a typedef to give a name to an otherwise
anonymous type for linkage purposes. gdb tries to handle this odd
scenario, which is enforced by anon-struct.exp.

It's difficult to detect this problem in the current tree, but the
cooked index does not include an entry for these DIEs.

This patch changes gdb to add these to the index. This is needed by
subsequent changes in this series.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32519
---
gdb/dwarf2/cooked-index-shard.h | 7 +++++++
gdb/dwarf2/cooked-index-worker.h | 7 +++++++
gdb/dwarf2/cooked-indexer.c | 26 ++++++++++++++++++++++++++
3 files changed, 40 insertions(+)

diff --git a/gdb/dwarf2/cooked-index-shard.h b/gdb/dwarf2/cooked-index-shard.h
index eb809264cbb80612c864bcf4c04c68ff5d4e99fb..14f5c588c15b6a7ac6d558caabfd9a84b071895f 100644
--- a/gdb/dwarf2/cooked-index-shard.h
+++ b/gdb/dwarf2/cooked-index-shard.h
@@ -48,6 +48,13 @@ class cooked_index_shard
cooked_index_entry_ref parent_entry,
dwarf2_per_cu *per_cu);

+ /* Add a copy of NAME to the index. Return a pointer to the
+ copy. */
+ const char *add (std::string_view name)
+ {
+ return m_names.insert (name);
+ }
+
/* Install a new fixed addrmap from the given mutable addrmap. */
void install_addrmap (addrmap_mutable *map)
{
diff --git a/gdb/dwarf2/cooked-index-worker.h b/gdb/dwarf2/cooked-index-worker.h
index df5c31d572dfe89c067c1118d34e7d07e8a084aa..c6e005c14dea1bb891680969c17172d494a7de46 100644
--- a/gdb/dwarf2/cooked-index-worker.h
+++ b/gdb/dwarf2/cooked-index-worker.h
@@ -85,6 +85,13 @@ class cooked_index_worker_result
name, parent_entry, per_cu);
}

+ /* Add a copy of NAME to the index. Return a pointer to the
+ copy. */
+ const char *add (std::string_view name)
+ {
+ return m_shard->add (name);
+ }
+
/* Install the current addrmap into the shard being constructed,
then transfer ownership of the index to the caller. */
cooked_index_shard_up release_shard ()
diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c
index bf9f1384781c54e067cb7e8441a5900613207a20..473dd451a704541668c91a26ad709daae1aa5343 100644
--- a/gdb/dwarf2/cooked-indexer.c
+++ b/gdb/dwarf2/cooked-indexer.c
@@ -21,6 +21,8 @@
#include "dwarf2/cooked-index-worker.h"
#include "dwarf2/error.h"
#include "dwarf2/read.h"
+#include "cp-support.h"
+#include "demangle.h"

/* See cooked-indexer.h. */

@@ -569,6 +571,30 @@ cooked_indexer::index_dies (cutu_reader *reader,
name = nullptr;
}

+ /* An otherwise anonymous type might be given a name (via
+ typedef) for linkage purposes, and gdb tries to handle this
+ case. See anon-struct.exp. In this case, GCC will emit a
+ funny thing: a linkage name for the type, but in "type" form.
+ That is, it will not start with _Z. */
+ if ((abbrev->tag == DW_TAG_class_type
+ || abbrev->tag == DW_TAG_structure_type
+ || abbrev->tag == DW_TAG_union_type)
+ && m_language == language_cplus
+ && name == nullptr
+ && linkage_name != nullptr)
+ {
+ gdb::unique_xmalloc_ptr<char> dem
+ = gdb_demangle (linkage_name, DMGL_GNU_V3 | DMGL_TYPES);
+ if (dem != nullptr)
+ {
+ /* We're only interested in the last component. */
+ std::vector<std::string_view> split
+ = split_name (dem.get (), split_style::CXX);
+ name = m_index_storage->add (split.back ());
+ linkage_name = nullptr;
+ }
+ }
+
cooked_index_entry *this_entry = nullptr;
if (name != nullptr)
{

--
2.46.1