]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add best_symbol_tracker
authorTom Tromey <tom@tromey.com>
Thu, 2 Jan 2025 22:21:46 +0000 (15:21 -0700)
committerTom Tromey <tom@tromey.com>
Wed, 10 Sep 2025 22:07:57 +0000 (16:07 -0600)
This adds a new best_symbol_tracker struct.  This is used to implement
the "best symbol" logic that is used sometimes in symtab.c.  This
approach makes it simpler and more efficient to track the "best"
symbol when searching across multiple blocks.

Acked-By: Simon Marchi <simon.marchi@efficios.com>
gdb/block.c
gdb/block.h
gdb/symtab.c

index 483da5b0925563764cf947615d5b745b9d4475b3..2450ebd9be951a970b80acb2b17786e490894a11 100644 (file)
@@ -669,7 +669,11 @@ block_lookup_symbol (const struct block *block, const lookup_name_info &name,
                     const domain_search_flags domain)
 {
   if (!block->function ())
-    return block_lookup_symbol_primary (block, name, domain);
+    {
+      best_symbol_tracker tracker;
+      tracker.search (nullptr, block, name, domain);
+      return tracker.currently_best.symbol;
+    }
   else
     {
       /* Note that parameter symbols do not always show up last in the
@@ -700,12 +704,12 @@ block_lookup_symbol (const struct block *block, const lookup_name_info &name,
 
 /* See block.h.  */
 
-struct symbol *
-block_lookup_symbol_primary (const struct block *block,
+bool
+best_symbol_tracker::search (compunit_symtab *symtab,
+                            const struct block *block,
                             const lookup_name_info &name,
                             const domain_search_flags domain)
 {
-  symbol *other = nullptr;
   for (symbol *sym : block_iterator_range (block, &name))
     {
       /* With the fix for PR gcc/debug/91507, we get for:
@@ -736,17 +740,28 @@ block_lookup_symbol_primary (const struct block *block,
         the only option to make this work is improve the fallback to use the
         size of the minimal symbol.  Filed as PR exp/24989.  */
       if (best_symbol (sym, domain))
-       return sym;
+       {
+         best_symtab = symtab;
+         currently_best = { sym, block };
+         return true;
+       }
 
       /* This is a bit of a hack, but 'matches' might ignore
         STRUCT vs VAR domain symbols.  So if a matching symbol is found,
         make sure there is no "better" matching symbol, i.e., one with
         exactly the same domain.  PR 16253.  */
       if (sym->matches (domain))
-       other = better_symbol (other, sym, domain);
+       {
+         symbol *better = better_symbol (sym, currently_best.symbol, domain);
+         if (better != currently_best.symbol)
+           {
+             best_symtab = symtab;
+             currently_best = { better, block };
+           }
+       }
     }
 
-  return other;
+  return false;
 }
 
 /* See block.h.  */
index f8cd41441bf1e9d0ffb1b5245701f46113601cf7..4ea5294877c5690d61923a5d01e9b2c523e1c885 100644 (file)
@@ -630,14 +630,27 @@ extern struct symbol *block_lookup_symbol (const struct block *block,
                                           const lookup_name_info &name,
                                           const domain_search_flags domain);
 
-/* Search BLOCK for symbol NAME in DOMAIN but only in primary symbol table of
-   BLOCK.  BLOCK must be STATIC_BLOCK or GLOBAL_BLOCK.  Function is useful if
-   one iterates all global/static blocks of an objfile.  */
+/* When searching for a symbol, the "best" symbol is preferred over
+   one that is merely acceptable.  See 'best_symbol'.  This class
+   keeps track of this distinction while searching.  */
 
-extern struct symbol *block_lookup_symbol_primary
-     (const struct block *block,
-      const lookup_name_info &name,
-      const domain_search_flags domain);
+struct best_symbol_tracker
+{
+  /* The symtab in which the currently best symbol appears.  */
+  compunit_symtab *best_symtab = nullptr;
+
+  /* The currently best (really "better") symbol.  */
+  block_symbol currently_best {};
+
+  /* Search BLOCK (which must have come from SYMTAB) for a symbol
+     matching NAME and DOMAIN.  When a symbol is found, update
+     'currently_best'.  If a best symbol is found, return true.
+     Otherwise, return false.  SYMTAB can be nullptr if the caller
+     does not care about this tracking.  */
+  bool search (compunit_symtab *symtab,
+              const block *block, const lookup_name_info &name,
+              domain_search_flags domain);
+};
 
 /* Find symbol NAME in BLOCK and in DOMAIN.  This will return a
    matching symbol whose type is not a "opaque", see TYPE_IS_OPAQUE.
index d9356cea141c1fff24d0d4fdd6c5076a38c1f8bb..847f644bdb31a55a7611692858965c87d4339d66 100644 (file)
@@ -2357,44 +2357,25 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
      name, domain_name (domain).c_str ());
 
   lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-  struct block_symbol other;
-  other.symbol = NULL;
+  best_symbol_tracker accum;
   for (compunit_symtab *cust : objfile->compunits ())
     {
       const struct blockvector *bv;
       const struct block *block;
-      struct block_symbol result;
 
       bv = cust->blockvector ();
       block = bv->block (block_index);
-      result.symbol = block_lookup_symbol_primary (block, lookup_name, domain);
-      result.block = block;
-      if (result.symbol == NULL)
-       continue;
-      if (best_symbol (result.symbol, domain))
-       {
-         other = result;
-         break;
-       }
-      if (result.symbol->matches (domain))
-       {
-         struct symbol *better
-           = better_symbol (other.symbol, result.symbol, domain);
-         if (better != other.symbol)
-           {
-             other.symbol = better;
-             other.block = block;
-           }
-       }
+      if (accum.search (cust, block, lookup_name, domain))
+       break;
     }
 
-  if (other.symbol != NULL)
+  if (accum.currently_best.symbol != nullptr)
     {
       symbol_lookup_debug_printf_v
        ("lookup_symbol_in_objfile_symtabs (...) = %s (block %s)",
-        host_address_to_string (other.symbol),
-        host_address_to_string (other.block));
-      return other;
+        host_address_to_string (accum.currently_best.symbol),
+        host_address_to_string (accum.currently_best.block));
+      return accum.currently_best;
     }
 
   symbol_lookup_debug_printf_v