binutils-gdb/gdb/expanded-symbol.c
Simon Marchi ea4bacd354 gdb: introduce iteration_status enum, use it for search callbacks
There are a bunch of iteration functions that take a callback returning
true or false to indicate whether to continue or stop iterating.  These
functions then return the same value, indicate whether the iteration was
done until the end of interrupted.  I think this is confusing and
error-prone, as I never know which value means what.  It is especially
confusing when two opposite conventions collide, such as in
objfile::map_symtabs_matching_filename.

I propose to make that more obvious by introducing a new
iteration_status enum with self-documenting values.

I started to change the callback type
compunit_symtab_iteration_callback, taken by
quick_symbol_functions::search, and then followed that path to update a
bunch of other functions.

I chose the name to be kind of generic, so that it can be used for other
similar iteration patterns.  I also put it in gdbsupport, in case we
want to use it in gdbserver too.

Change-Id: I55d84d0c1af8ac0b82cc9f49ccf0d6b60e1769e0
Approved-By: Andrew Burgess <aburgess@redhat.com>
2026-04-17 15:30:29 -04:00

117 lines
3.2 KiB
C

/* An implementation of "quick" symbol functions for already expanded
symbol tables.
Copyright (C) 2026-2026 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "objfiles.h"
#include "symtab.h"
#include "source.h"
#include "expanded-symbol.h"
/* See expanded-symbol.h. */
symtab *
expanded_symbols_functions::find_last_source_symtab (objfile *objfile)
{
if (m_compunit_symtabs.empty ())
return nullptr;
else
return m_compunit_symtabs.back ()->primary_filetab ();
}
/* See expanded-symbol.h. */
enum language
expanded_symbols_functions::lookup_global_symbol_language
(objfile *objfile, const char *name, domain_search_flags domain,
bool *symbol_found_p)
{
*symbol_found_p = false;
return language_unknown;
}
/* See expanded-symbol.h. */
iteration_status
expanded_symbols_functions::search
(objfile *objfile,
search_symtabs_file_matcher file_matcher,
const lookup_name_info *lookup_name,
search_symtabs_symbol_matcher symbol_matcher,
compunit_symtab_iteration_callback compunit_callback,
block_search_flags search_flags,
domain_search_flags domain,
search_symtabs_lang_matcher lang_matcher)
{
/* This invariant is documented in quick-functions.h. */
gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
for (compunit_symtab *cu : m_compunit_symtabs)
{
if (lang_matcher != nullptr && !lang_matcher (cu->language ()))
continue;
if (file_matcher != nullptr)
{
bool matched = false;
for (auto st : cu->filetabs ())
{
if (file_matcher (st->filename (), false))
{
matched = true;
break;
}
if ((basenames_may_differ
|| file_matcher (lbasename (st->filename ()), true))
&& file_matcher (symtab_to_fullname (st), false))
{
matched = true;
break;
}
}
if (!matched)
continue;
}
/* Here we simply call the callback (if any) without bothering to
consult lookup_name and symbol_matcher (if any). This should be
okay since i) all symtabs are already expanded and ii) callbacks
iterate over matching symbols themselves. */
if (compunit_callback != nullptr
&& compunit_callback (cu) == iteration_status::stop)
return iteration_status::stop;
}
return iteration_status::keep_going;
}
/* See expanded-symbol.h. */
symbol *
expanded_symbols_functions::find_symbol_by_address (objfile *objfile,
CORE_ADDR address)
{
for (compunit_symtab *symtab : m_compunit_symtabs)
{
symbol *sym = symtab->symbol_at_address (address);
if (sym != nullptr)
return sym;
}
return nullptr;
}