Simplify linespec.c:collect_info
Commit Message
I noticed that linespec has a subclass of collect_info that would be
easily replaced by a boolean. This patch cleans up this area by
removing the subclass, adding a constructor to collect_info, and
removing an unnecessary structure type used by it.
Regression tested on x86-64 Fedora 40.
---
gdb/linespec.c | 98 ++++++++++++++++++++------------------------------
1 file changed, 39 insertions(+), 59 deletions(-)
Comments
Tom Tromey <tom@tromey.com> writes:
> I noticed that linespec has a subclass of collect_info that would be
> easily replaced by a boolean. This patch cleans up this area by
> removing the subclass, adding a constructor to collect_info, and
> removing an unnecessary structure type used by it.
LGTM.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> Regression tested on x86-64 Fedora 40.
> ---
> gdb/linespec.c | 98 ++++++++++++++++++++------------------------------
> 1 file changed, 39 insertions(+), 59 deletions(-)
>
> diff --git a/gdb/linespec.c b/gdb/linespec.c
> index 2cbfe2fcc20..edd5f917f3a 100644
> --- a/gdb/linespec.c
> +++ b/gdb/linespec.c
> @@ -1,6 +1,6 @@
> /* Parser for linespec for the GNU debugger, GDB.
>
> - Copyright (C) 1986-2025 Free Software Foundation, Inc.
> + Copyright (C) 1986-2026 Free Software Foundation, Inc.
>
> This file is part of GDB.
>
> @@ -207,50 +207,48 @@ struct linespec_state
>
> struct collect_info
> {
> + collect_info (linespec_state *state,
> + const std::vector<symtab *> &file_symtabs,
> + std::vector<block_symbol> *symbols,
> + std::vector<bound_minimal_symbol> *minimal_symbols,
> + bool force_record_all = false)
> + : state (state),
> + /* In list mode, add all matching symbols, regardless of class.
> + This allows the user to type "list a_global_variable". */
> + record_all (force_record_all || state->list_mode),
> + file_symtabs (file_symtabs),
> + symbols (symbols),
> + minimal_symbols (minimal_symbols)
> + {
> + }
> +
> /* The linespec object in use. */
> struct linespec_state *state;
>
> + /* True if all symbols should be recorded. */
> + bool record_all;
> +
> /* A list of symtabs to which to restrict matches. */
> - const std::vector<symtab *> *file_symtabs;
> + const std::vector<symtab *> &file_symtabs;
>
> - /* The result being accumulated. */
> - struct
> - {
> - std::vector<block_symbol> *symbols;
> - std::vector<bound_minimal_symbol> *minimal_symbols;
> - } result;
> + /* The results being accumulated. */
> + std::vector<block_symbol> *symbols;
> + std::vector<bound_minimal_symbol> *minimal_symbols;
>
> /* Possibly add a symbol to the results. */
> - virtual bool add_symbol (block_symbol *bsym);
> + bool add_symbol (block_symbol *bsym);
> };
>
> bool
> collect_info::add_symbol (block_symbol *bsym)
> {
> - /* In list mode, add all matching symbols, regardless of class.
> - This allows the user to type "list a_global_variable". */
> - if (bsym->symbol->loc_class () == LOC_BLOCK || this->state->list_mode)
> - this->result.symbols->push_back (*bsym);
> + if (record_all || bsym->symbol->loc_class () == LOC_BLOCK)
> + this->symbols->push_back (*bsym);
>
> /* Continue iterating. */
> return true;
> }
>
> -/* Custom collect_info for symbol_searcher. */
> -
> -struct symbol_searcher_collect_info
> - : collect_info
> -{
> - bool add_symbol (block_symbol *bsym) override
> - {
> - /* Add everything. */
> - this->result.symbols->push_back (*bsym);
> -
> - /* Continue iterating. */
> - return true;
> - }
> -};
> -
> /* Token types */
>
> enum linespec_token_type
> @@ -3271,20 +3269,15 @@ linespec_expression_to_pc (const char **exp_ptr)
> static std::vector<symtab_and_line>
> decode_objc (struct linespec_state *self, linespec *ls, const char *arg)
> {
> - struct collect_info info;
> - std::vector<const char *> symbol_names;
> - const char *new_argptr;
> -
> - info.state = self;
> std::vector<symtab *> symtabs;
> symtabs.push_back (nullptr);
>
> - info.file_symtabs = &symtabs;
> -
> std::vector<block_symbol> symbols;
> - info.result.symbols = &symbols;
> std::vector<bound_minimal_symbol> minimal_symbols;
> - info.result.minimal_symbols = &minimal_symbols;
> +
> + collect_info info (self, symtabs, &symbols, &minimal_symbols);
> + std::vector<const char *> symbol_names;
> + const char *new_argptr;
>
> new_argptr = find_imps (arg, &symbol_names);
> if (symbol_names.empty ())
> @@ -3538,18 +3531,13 @@ find_method (struct linespec_state *self,
> size_t last_result_len;
> std::vector<struct type *> superclass_vec;
> std::vector<const char *> result_names;
> - struct collect_info info;
> + collect_info info (self, file_symtabs, symbols, minsyms);
>
> /* Sort symbols so that symbols with the same program space are next
> to each other. */
> std::sort (sym_classes->begin (), sym_classes->end (),
> compare_symbols);
>
> - info.state = self;
> - info.file_symtabs = &file_symtabs;
> - info.result.symbols = symbols;
> - info.result.minimal_symbols = minsyms;
> -
> /* Iterate over all the types, looking for the names of existing
> methods matching METHOD_NAME. If we cannot find a direct method in a
> given program space, then we consider inherited methods; this is
> @@ -3682,20 +3670,17 @@ symbol_searcher::find_all_symbols (const std::string &name,
> std::vector<symtab *> *search_symtabs,
> struct program_space *search_pspace)
> {
> - symbol_searcher_collect_info info;
> linespec_state state (language, current_program_space);
>
> - info.state = &state;
> -
> - info.result.symbols = &m_symbols;
> - info.result.minimal_symbols = &m_minimal_symbols;
> std::vector<symtab *> all_symtabs;
> if (search_symtabs == nullptr)
> {
> all_symtabs.push_back (nullptr);
> search_symtabs = &all_symtabs;
> }
> - info.file_symtabs = search_symtabs;
> +
> + collect_info info (&state, *search_symtabs, &m_symbols,
> + &m_minimal_symbols, true);
>
> add_matching_symbols_to_info (name.c_str (), symbol_name_match_type::WILD,
> domain_search_flags, &info, search_pspace);
> @@ -3712,14 +3697,9 @@ find_function_symbols (struct linespec_state *state,
> std::vector<block_symbol> *symbols,
> std::vector<bound_minimal_symbol> *minsyms)
> {
> - struct collect_info info;
> + collect_info info (state, file_symtabs, symbols, minsyms);
> std::vector<const char *> symbol_names;
>
> - info.state = state;
> - info.result.symbols = symbols;
> - info.result.minimal_symbols = minsyms;
> - info.file_symtabs = &file_symtabs;
> -
> /* Try NAME as an Objective-C selector. */
> find_imps (name, &symbol_names);
>
> @@ -4252,7 +4232,7 @@ search_minsyms_for_name (struct collect_info *info,
> }
>
> if (!skip)
> - info->result.minimal_symbols->push_back (item);
> + info->minimal_symbols->push_back (item);
> }
> }
>
> @@ -4274,7 +4254,7 @@ add_matching_symbols_to_info (const char *name,
> return info->add_symbol (bsym);
> };
>
> - for (const auto &elt : *info->file_symtabs)
> + for (const auto &elt : info->file_symtabs)
> {
> if (elt == nullptr)
> {
> @@ -4286,7 +4266,7 @@ add_matching_symbols_to_info (const char *name,
> }
> else if (pspace == NULL || pspace == elt->compunit ()->objfile ()->pspace ())
> {
> - int prev_len = info->result.symbols->size ();
> + int prev_len = info->symbols->size ();
>
> /* Program spaces that are executing startup should have
> been filtered out earlier. */
> @@ -4299,7 +4279,7 @@ add_matching_symbols_to_info (const char *name,
> is in assembler, we might actually be looking for a label for
> which we don't have debug info. Check for a minimal symbol in
> this case. */
> - if (prev_len == info->result.symbols->size ()
> + if (prev_len == info->symbols->size ()
> && elt->language () == language_asm)
> search_minsyms_for_name (info, lookup_name, pspace, elt);
> }
> --
> 2.49.0
@@ -1,6 +1,6 @@
/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2025 Free Software Foundation, Inc.
+ Copyright (C) 1986-2026 Free Software Foundation, Inc.
This file is part of GDB.
@@ -207,50 +207,48 @@ struct linespec_state
struct collect_info
{
+ collect_info (linespec_state *state,
+ const std::vector<symtab *> &file_symtabs,
+ std::vector<block_symbol> *symbols,
+ std::vector<bound_minimal_symbol> *minimal_symbols,
+ bool force_record_all = false)
+ : state (state),
+ /* In list mode, add all matching symbols, regardless of class.
+ This allows the user to type "list a_global_variable". */
+ record_all (force_record_all || state->list_mode),
+ file_symtabs (file_symtabs),
+ symbols (symbols),
+ minimal_symbols (minimal_symbols)
+ {
+ }
+
/* The linespec object in use. */
struct linespec_state *state;
+ /* True if all symbols should be recorded. */
+ bool record_all;
+
/* A list of symtabs to which to restrict matches. */
- const std::vector<symtab *> *file_symtabs;
+ const std::vector<symtab *> &file_symtabs;
- /* The result being accumulated. */
- struct
- {
- std::vector<block_symbol> *symbols;
- std::vector<bound_minimal_symbol> *minimal_symbols;
- } result;
+ /* The results being accumulated. */
+ std::vector<block_symbol> *symbols;
+ std::vector<bound_minimal_symbol> *minimal_symbols;
/* Possibly add a symbol to the results. */
- virtual bool add_symbol (block_symbol *bsym);
+ bool add_symbol (block_symbol *bsym);
};
bool
collect_info::add_symbol (block_symbol *bsym)
{
- /* In list mode, add all matching symbols, regardless of class.
- This allows the user to type "list a_global_variable". */
- if (bsym->symbol->loc_class () == LOC_BLOCK || this->state->list_mode)
- this->result.symbols->push_back (*bsym);
+ if (record_all || bsym->symbol->loc_class () == LOC_BLOCK)
+ this->symbols->push_back (*bsym);
/* Continue iterating. */
return true;
}
-/* Custom collect_info for symbol_searcher. */
-
-struct symbol_searcher_collect_info
- : collect_info
-{
- bool add_symbol (block_symbol *bsym) override
- {
- /* Add everything. */
- this->result.symbols->push_back (*bsym);
-
- /* Continue iterating. */
- return true;
- }
-};
-
/* Token types */
enum linespec_token_type
@@ -3271,20 +3269,15 @@ linespec_expression_to_pc (const char **exp_ptr)
static std::vector<symtab_and_line>
decode_objc (struct linespec_state *self, linespec *ls, const char *arg)
{
- struct collect_info info;
- std::vector<const char *> symbol_names;
- const char *new_argptr;
-
- info.state = self;
std::vector<symtab *> symtabs;
symtabs.push_back (nullptr);
- info.file_symtabs = &symtabs;
-
std::vector<block_symbol> symbols;
- info.result.symbols = &symbols;
std::vector<bound_minimal_symbol> minimal_symbols;
- info.result.minimal_symbols = &minimal_symbols;
+
+ collect_info info (self, symtabs, &symbols, &minimal_symbols);
+ std::vector<const char *> symbol_names;
+ const char *new_argptr;
new_argptr = find_imps (arg, &symbol_names);
if (symbol_names.empty ())
@@ -3538,18 +3531,13 @@ find_method (struct linespec_state *self,
size_t last_result_len;
std::vector<struct type *> superclass_vec;
std::vector<const char *> result_names;
- struct collect_info info;
+ collect_info info (self, file_symtabs, symbols, minsyms);
/* Sort symbols so that symbols with the same program space are next
to each other. */
std::sort (sym_classes->begin (), sym_classes->end (),
compare_symbols);
- info.state = self;
- info.file_symtabs = &file_symtabs;
- info.result.symbols = symbols;
- info.result.minimal_symbols = minsyms;
-
/* Iterate over all the types, looking for the names of existing
methods matching METHOD_NAME. If we cannot find a direct method in a
given program space, then we consider inherited methods; this is
@@ -3682,20 +3670,17 @@ symbol_searcher::find_all_symbols (const std::string &name,
std::vector<symtab *> *search_symtabs,
struct program_space *search_pspace)
{
- symbol_searcher_collect_info info;
linespec_state state (language, current_program_space);
- info.state = &state;
-
- info.result.symbols = &m_symbols;
- info.result.minimal_symbols = &m_minimal_symbols;
std::vector<symtab *> all_symtabs;
if (search_symtabs == nullptr)
{
all_symtabs.push_back (nullptr);
search_symtabs = &all_symtabs;
}
- info.file_symtabs = search_symtabs;
+
+ collect_info info (&state, *search_symtabs, &m_symbols,
+ &m_minimal_symbols, true);
add_matching_symbols_to_info (name.c_str (), symbol_name_match_type::WILD,
domain_search_flags, &info, search_pspace);
@@ -3712,14 +3697,9 @@ find_function_symbols (struct linespec_state *state,
std::vector<block_symbol> *symbols,
std::vector<bound_minimal_symbol> *minsyms)
{
- struct collect_info info;
+ collect_info info (state, file_symtabs, symbols, minsyms);
std::vector<const char *> symbol_names;
- info.state = state;
- info.result.symbols = symbols;
- info.result.minimal_symbols = minsyms;
- info.file_symtabs = &file_symtabs;
-
/* Try NAME as an Objective-C selector. */
find_imps (name, &symbol_names);
@@ -4252,7 +4232,7 @@ search_minsyms_for_name (struct collect_info *info,
}
if (!skip)
- info->result.minimal_symbols->push_back (item);
+ info->minimal_symbols->push_back (item);
}
}
@@ -4274,7 +4254,7 @@ add_matching_symbols_to_info (const char *name,
return info->add_symbol (bsym);
};
- for (const auto &elt : *info->file_symtabs)
+ for (const auto &elt : info->file_symtabs)
{
if (elt == nullptr)
{
@@ -4286,7 +4266,7 @@ add_matching_symbols_to_info (const char *name,
}
else if (pspace == NULL || pspace == elt->compunit ()->objfile ()->pspace ())
{
- int prev_len = info->result.symbols->size ();
+ int prev_len = info->symbols->size ();
/* Program spaces that are executing startup should have
been filtered out earlier. */
@@ -4299,7 +4279,7 @@ add_matching_symbols_to_info (const char *name,
is in assembler, we might actually be looking for a label for
which we don't have debug info. Check for a minimal symbol in
this case. */
- if (prev_len == info->result.symbols->size ()
+ if (prev_len == info->symbols->size ()
&& elt->language () == language_asm)
search_minsyms_for_name (info, lookup_name, pspace, elt);
}