@@ -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. */
@@ -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.
@@ -2366,44 +2366,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