Simplify linespec.c:collect_info

Message ID 20260102194909.3805345-1-tom@tromey.com
State New
Headers
Series Simplify linespec.c:collect_info |

Commit Message

Tom Tromey Jan. 2, 2026, 7:49 p.m. UTC
  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

Andrew Burgess Jan. 6, 2026, 2:15 p.m. UTC | #1
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
  

Patch

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);
 	}