Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 00/11] Readability improvements of some iteration functions
@ 2026-04-16 20:16 Simon Marchi
  2026-04-16 20:16 ` [PATCH 01/11] gdb/dwarf: remove unused file_match parameter from dwarf2_base_index_functions::search_one Simon Marchi
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This series contains a few readability improvements that I came up with
as I was reading the DWARF index and symbol lookup code.

The first significant change is the introduction of the
`iteration_status` enum, since I was confused with the meaning of
true/false to mean "stop" vs "keep iterating", for some iteration
functions that use a callback.  I think that an enum will make that
clearer.  This enum is used for method quick_symbol_functions::search
and everything around it.

I looked at using the enum for the various "iterate_over_*" functions
that have this "stop iteration early" capability, but for them I
concluded that the code would be clearer if we split them in two:

 - A "for each" function that doesn't have the capability of stopping
   iteration early
 - A "find" function that returns the first element for which the
   callback returns true.  For this use case, I think it's fine for the
   callback to return a bool.

That's mostly it, there are other small changes, but the patches should
be clear on their own.

Simon Marchi (11):
  gdb/dwarf: remove unused file_match parameter from
    dwarf2_base_index_functions::search_one
  gdb: rename search_symtabs_expansion_listener ->
    compunit_symtab_iteration_callback
  gdb: introduce iteration_status enum, use it for search callbacks
  gdb, gdbserver: make iterate_over_lwps_ftype a function_view
  gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp
  gdb: split iterate_over_threads in for_each_thread and find_thread
  gdb: split iterate_over_minimal_symbols in for_each_minimal_symbol and
    find_minimal_symbol
  gdb: split iterate_over_symtabs in for_each_symtab and find_symtab
  gdb: change objfile::map_symtabs_matching_filename to
    find_symtab_matching_filename
  gdb: make symbol_found_callback_ftype a function_view
  gdb: make iterate_over_symbols return void, rename to for_each_symbol

 gdb/ada-lang.c                     |  32 ++--
 gdb/aix-thread.c                   |   2 +-
 gdb/arm-linux-nat.c                |  38 ++--
 gdb/breakpoint.c                   |   3 +-
 gdb/cp-support.c                   |   2 +-
 gdb/dwarf2/cooked-index-entry.c    |   2 +-
 gdb/dwarf2/cooked-index-entry.h    |  10 +-
 gdb/dwarf2/cooked-index.h          |   4 +-
 gdb/dwarf2/index-write.c           |   4 +-
 gdb/dwarf2/read.c                  |  78 ++++----
 gdb/dwarf2/read.h                  |  26 +--
 gdb/expanded-symbol.c              |  16 +-
 gdb/expanded-symbol.h              |  15 +-
 gdb/fbsd-tdep.c                    |   2 +-
 gdb/gdbthread.h                    |  21 ++-
 gdb/infcmd.c                       |   9 +-
 gdb/infrun.c                       |   4 +-
 gdb/language.h                     |  13 +-
 gdb/linespec.c                     |  80 ++++-----
 gdb/linux-nat.c                    | 277 +++++++++++++++--------------
 gdb/mi/mi-main.c                   |  15 +-
 gdb/minsyms.c                      |  25 ++-
 gdb/minsyms.h                      |  37 +++-
 gdb/nat/aarch64-linux-hw-point.c   |  17 +-
 gdb/nat/linux-nat.h                |  17 +-
 gdb/nat/loongarch-linux-hw-point.c |  18 +-
 gdb/nat/x86-linux-dregs.c          |  15 +-
 gdb/objfiles.h                     |  31 ++--
 gdb/ppc-linux-nat.c                |  22 +--
 gdb/procfs.c                       |   6 +-
 gdb/python/py-symbol.c             |  18 +-
 gdb/quick-symbol.h                 |  25 +--
 gdb/s390-linux-nat.c               |  22 +--
 gdb/sol-thread.c                   |   4 +-
 gdb/symfile-debug.c                | 114 ++++++------
 gdb/symtab.c                       |  97 +++++-----
 gdb/symtab.h                       |  41 ++---
 gdb/thread.c                       |  27 ++-
 gdbserver/linux-low.cc             |  21 +--
 gdbsupport/iteration-status.h      |  48 +++++
 40 files changed, 659 insertions(+), 599 deletions(-)
 create mode 100644 gdbsupport/iteration-status.h


base-commit: cc9d69394628641235da1483788c0d938c9b6661
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/11] gdb/dwarf: remove unused file_match parameter from dwarf2_base_index_functions::search_one
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 02/11] gdb: rename search_symtabs_expansion_listener -> compunit_symtab_iteration_callback Simon Marchi
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The `file_matcher` parameter is unused.

The information from `file_matcher` is actually encoded in
`cus_to_skip`.  All callers to this:

    auto_bool_vector cus_to_skip;
    dw_search_file_matcher (per_objfile, cus_to_skip, file_matcher);

... which populates `cus_to_skip` with all the CUs that do not match
`file_matcher`.

Change-Id: I7fd642f84d72ad2595c1e6de38db3869cc555ce9
---
 gdb/dwarf2/read.c | 13 ++++++-------
 gdb/dwarf2/read.h |  6 +++---
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4035bba6e45b..02e6c00dfef5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1480,8 +1480,8 @@ struct readnow_functions : public dwarf2_base_index_functions
 	    || per_cu->unit_type (false) == 0
 	    || per_objfile->get_compunit_symtab (per_cu.get ()) == nullptr)
 	  continue;
-	if (!search_one (per_cu.get (), per_objfile, cus_to_skip, file_matcher,
-			 listener, lang_matcher))
+	if (!search_one (per_cu.get (), per_objfile, cus_to_skip, listener,
+			 lang_matcher))
 	  return false;
       }
     return true;
@@ -1923,7 +1923,6 @@ dwarf2_base_index_functions::search_one
   (dwarf2_per_cu *per_cu,
    dwarf2_per_objfile *per_objfile,
    auto_bool_vector &cus_to_skip,
-   search_symtabs_file_matcher file_matcher,
    search_symtabs_expansion_listener listener,
    search_symtabs_lang_matcher lang_matcher)
 {
@@ -14056,8 +14055,8 @@ cooked_index_functions::search
 	{
 	  QUIT;
 
-	  if (!search_one (per_cu, per_objfile, cus_to_skip, file_matcher,
-			   listener, lang_matcher))
+	  if (!search_one (per_cu, per_objfile, cus_to_skip, listener,
+			   lang_matcher))
 	    return false;
 	}
       return true;
@@ -14224,8 +14223,8 @@ cooked_index_functions::search
 
 	  bool check = entry->visit_defining_cus ([&] (dwarf2_per_cu *per_cu)
 	    {
-	      return search_one (per_cu, per_objfile, cus_to_skip,
-				 file_matcher, listener, nullptr);
+	      return search_one (per_cu, per_objfile, cus_to_skip, listener,
+				 nullptr);
 	    });
 	  if (!check)
 	    return false;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 1150c3cfdcad..fddaaa7d9e5c 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -1318,11 +1318,11 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
 			     bool need_fullname) override;
 
 protected:
-  /* If FILE_MATCHER is NULL and if CUS_TO_SKIP does not include the CU's index,
-     expand the CU and call LISTENER on it.  */
+  /* If CUS_TO_SKIP does not include the CU's index and the CU's language
+     matches LANG_MATCHER, expand the CU and call LISTENER (if provided) on
+     it.  */
   bool search_one (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
 		   auto_bool_vector &cus_to_skip,
-		   search_symtabs_file_matcher file_matcher,
 		   search_symtabs_expansion_listener listener,
 		   search_symtabs_lang_matcher lang_matcher);
 };
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 02/11] gdb: rename search_symtabs_expansion_listener -> compunit_symtab_iteration_callback
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
  2026-04-16 20:16 ` [PATCH 01/11] gdb/dwarf: remove unused file_match parameter from dwarf2_base_index_functions::search_one Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 03/11] gdb: introduce iteration_status enum, use it for search callbacks Simon Marchi
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

I think that the name search_symtabs_expansion_listener function type
no longer makes sense for the following reasons:

 - Since we have both `symtab` and `compunit_symtab` structs, I like
   when we are specific about which one we're talking about.  In this
   case, the callback takes a `compunit_symtab`.

 - Following series "Search symbols via quick API" [1] last year (I
   believe commit f88f9f42db8 ("Have expand_symtabs_matching work for
   already-expanded CUs")), the callback gets called for all matching
   compunit_symtabs, not just those that get expanded.

I therefore propose to rename it to compunit_symtab_iteration_callback.
I chose "callback" over "listener", because I think that listener
implies that there is some event happening, that we listen for.  That
made sense before where we would listen for the "expansion" event.  But
now since it just gets called back for all matching CUs, I think that
"callback" makes more sense.

I renamed the parameters accordingly.

[1] https://inbox.sourceware.org/gdb-patches/20250909-search-in-psyms-v4-0-e7ef9e3b6479@tromey.com/

Change-Id: Ia5a662e6d37caf8e0272424ddbbd82f05bdb5ebe
---
 gdb/dwarf2/cooked-index.h |  2 +-
 gdb/dwarf2/read.c         | 21 +++++++++++----------
 gdb/dwarf2/read.h         |  6 +++---
 gdb/expanded-symbol.c     |  8 ++++----
 gdb/expanded-symbol.h     |  2 +-
 gdb/objfiles.h            |  2 +-
 gdb/quick-symbol.h        | 21 +++++++++++----------
 gdb/symfile-debug.c       | 10 +++++-----
 8 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index d265e86e67d8..00a15661677b 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -242,7 +242,7 @@ struct cooked_index_functions : public dwarf2_base_index_functions
      search_symtabs_file_matcher file_matcher,
      const lookup_name_info *lookup_name,
      search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
+     compunit_symtab_iteration_callback compunit_callback,
      block_search_flags search_flags,
      domain_search_flags domain,
      search_symtabs_lang_matcher lang_matcher) override;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 02e6c00dfef5..6146ff78b678 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1457,7 +1457,7 @@ struct readnow_functions : public dwarf2_base_index_functions
 	       search_symtabs_file_matcher file_matcher,
 	       const lookup_name_info *lookup_name,
 	       search_symtabs_symbol_matcher symbol_matcher,
-	       search_symtabs_expansion_listener listener,
+	       compunit_symtab_iteration_callback compunit_callback,
 	       block_search_flags search_flags,
 	       domain_search_flags domain,
 	       search_symtabs_lang_matcher lang_matcher) override
@@ -1480,8 +1480,9 @@ struct readnow_functions : public dwarf2_base_index_functions
 	    || per_cu->unit_type (false) == 0
 	    || per_objfile->get_compunit_symtab (per_cu.get ()) == nullptr)
 	  continue;
-	if (!search_one (per_cu.get (), per_objfile, cus_to_skip, listener,
-			 lang_matcher))
+
+	if (!search_one (per_cu.get (), per_objfile, cus_to_skip,
+			 compunit_callback, lang_matcher))
 	  return false;
       }
     return true;
@@ -1923,7 +1924,7 @@ dwarf2_base_index_functions::search_one
   (dwarf2_per_cu *per_cu,
    dwarf2_per_objfile *per_objfile,
    auto_bool_vector &cus_to_skip,
-   search_symtabs_expansion_listener listener,
+   compunit_symtab_iteration_callback compunit_callback,
    search_symtabs_lang_matcher lang_matcher)
 {
   /* Already visited, or intentionally skipped.  */
@@ -1943,10 +1944,10 @@ dwarf2_base_index_functions::search_one
     = dw2_instantiate_symtab (per_cu, per_objfile, false);
   gdb_assert (symtab != nullptr);
 
-  if (listener != nullptr)
+  if (compunit_callback != nullptr)
     {
       cus_to_skip.set (per_cu->index, true);
-      return listener (symtab);
+      return compunit_callback (symtab);
     }
 
   return true;
@@ -14035,7 +14036,7 @@ cooked_index_functions::search
    search_symtabs_file_matcher file_matcher,
    const lookup_name_info *lookup_name,
    search_symtabs_symbol_matcher symbol_matcher,
-   search_symtabs_expansion_listener listener,
+   compunit_symtab_iteration_callback compunit_callback,
    block_search_flags search_flags,
    domain_search_flags domain,
    search_symtabs_lang_matcher lang_matcher)
@@ -14055,7 +14056,7 @@ cooked_index_functions::search
 	{
 	  QUIT;
 
-	  if (!search_one (per_cu, per_objfile, cus_to_skip, listener,
+	  if (!search_one (per_cu, per_objfile, cus_to_skip, compunit_callback,
 			   lang_matcher))
 	    return false;
 	}
@@ -14223,8 +14224,8 @@ cooked_index_functions::search
 
 	  bool check = entry->visit_defining_cus ([&] (dwarf2_per_cu *per_cu)
 	    {
-	      return search_one (per_cu, per_objfile, cus_to_skip, listener,
-				 nullptr);
+	      return search_one (per_cu, per_objfile, cus_to_skip,
+				 compunit_callback, nullptr);
 	    });
 	  if (!check)
 	    return false;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index fddaaa7d9e5c..40b55a33bc8d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -1319,11 +1319,11 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
 
 protected:
   /* If CUS_TO_SKIP does not include the CU's index and the CU's language
-     matches LANG_MATCHER, expand the CU and call LISTENER (if provided) on
-     it.  */
+     matches LANG_MATCHER, expand the CU and call COMPUNIT_CALLBACK (if
+     provided) on it.  */
   bool search_one (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
 		   auto_bool_vector &cus_to_skip,
-		   search_symtabs_expansion_listener listener,
+		   compunit_symtab_iteration_callback compunit_callback,
 		   search_symtabs_lang_matcher lang_matcher);
 };
 
diff --git a/gdb/expanded-symbol.c b/gdb/expanded-symbol.c
index d885fe33fa84..fee55cd23db3 100644
--- a/gdb/expanded-symbol.c
+++ b/gdb/expanded-symbol.c
@@ -53,7 +53,7 @@ expanded_symbols_functions::search
       search_symtabs_file_matcher file_matcher,
       const lookup_name_info *lookup_name,
       search_symtabs_symbol_matcher symbol_matcher,
-      search_symtabs_expansion_listener listener,
+      compunit_symtab_iteration_callback compunit_callback,
       block_search_flags search_flags,
       domain_search_flags domain,
       search_symtabs_lang_matcher lang_matcher)
@@ -88,11 +88,11 @@ expanded_symbols_functions::search
 	    continue;
 	}
 
-      /* Here we simply call the listener (if any) without bothering to
+      /* 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) listeners
+	 okay since i) all symtabs are already expanded and ii) callbacks
 	 iterate over matching symbols themselves.  */
-      if (listener != nullptr && !listener (cu))
+      if (compunit_callback != nullptr && !compunit_callback (cu))
 	return false;
     }
   return true;
diff --git a/gdb/expanded-symbol.h b/gdb/expanded-symbol.h
index 885390ccb124..fc42938d9d3d 100644
--- a/gdb/expanded-symbol.h
+++ b/gdb/expanded-symbol.h
@@ -70,7 +70,7 @@ struct expanded_symbols_functions : public quick_symbol_functions
 	       search_symtabs_file_matcher file_matcher,
 	       const lookup_name_info *lookup_name,
 	       search_symtabs_symbol_matcher symbol_matcher,
-	       search_symtabs_expansion_listener listener,
+	       compunit_symtab_iteration_callback compunit_callback,
 	       block_search_flags search_flags, domain_search_flags domain,
 	       search_symtabs_lang_matcher lang_matcher) override;
 
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 89ac559ce813..aafac6ac93c6 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -622,7 +622,7 @@ struct objfile : intrusive_list_node<objfile>
     (search_symtabs_file_matcher file_matcher,
      const lookup_name_info *lookup_name,
      search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
+     compunit_symtab_iteration_callback compunit_callback,
      block_search_flags search_flags,
      domain_search_flags domain,
      search_symtabs_lang_matcher lang_matcher = nullptr);
diff --git a/gdb/quick-symbol.h b/gdb/quick-symbol.h
index a0b00b455020..9cecc1bf52c1 100644
--- a/gdb/quick-symbol.h
+++ b/gdb/quick-symbol.h
@@ -55,11 +55,12 @@ using search_symtabs_symbol_matcher
 using search_symtabs_lang_matcher
   = gdb::function_view<bool (enum language lang)>;
 
-/* Callback for quick_symbol_functions::search to be called when
-   symtab matches (perhaps expanding it first).  If this returns true,
-   more symtabs are checked; if it returns false, iteration stops.  */
+/* Callback for quick_symbol_functions::search to be called when a
+   compunit_symtab matches (perhaps expanding it first).  If this
+   returns true, more compunit_symtabs are checked; if it returns false,
+   iteration stops.  */
 
-using search_symtabs_expansion_listener
+using compunit_symtab_iteration_callback
   = gdb::function_view<bool (compunit_symtab *symtab)>;
 
 /* The "quick" symbol functions exist so that symbol readers can
@@ -151,17 +152,17 @@ struct quick_symbol_functions
      Otherwise, the symbol's symbol table is expanded if needed.
 
      Then (regardless of whether the symbol table was already
-     expanded, or just expanded in response to this search), LISTENER
-     is called.  If LISTENER returns false, execution stops and this
-     method returns false.  Otherwise, more files are considered.
-     This method returns true if all calls to LISTENER return
-     true.  */
+     expanded, or just expanded in response to this search),
+     COMPUNIT_CALLBACK is called.  If COMPUNIT_CALLBACK returns false,
+     execution stops and this method returns false.  Otherwise, more
+     files are considered.  This method returns true if all calls to
+     COMPUNIT_CALLBACK return true.  */
   virtual bool search
     (struct objfile *objfile,
      search_symtabs_file_matcher file_matcher,
      const lookup_name_info *lookup_name,
      search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
+     compunit_symtab_iteration_callback compunit_callback,
      block_search_flags search_flags,
      domain_search_flags domain,
      search_symtabs_lang_matcher lang_matcher = nullptr) = 0;
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 2c9deba20ae4..d26662e20656 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -255,7 +255,7 @@ objfile::map_symtabs_matching_filename
     return false;
   };
 
-  auto listener = [&] (compunit_symtab *symtab)
+  auto compunit_callback = [&] (compunit_symtab *symtab)
   {
     /* Skip included compunits, as they are searched by
        iterate_over_one_compunit_symtab.  */
@@ -271,7 +271,7 @@ objfile::map_symtabs_matching_filename
   for (const auto &iter : qf)
     {
       if (!iter->search (this, match_one_filename, nullptr, nullptr,
-			 listener,
+			 compunit_callback,
 			 SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
 			 SEARCH_ALL_DOMAINS))
 	{
@@ -401,7 +401,7 @@ bool
 objfile::search (search_symtabs_file_matcher file_matcher,
 		 const lookup_name_info *lookup_name,
 		 search_symtabs_symbol_matcher symbol_matcher,
-		 search_symtabs_expansion_listener listener,
+		 compunit_symtab_iteration_callback compunit_callback,
 		 block_search_flags search_flags,
 		 domain_search_flags domain,
 		 search_symtabs_lang_matcher lang_matcher)
@@ -415,12 +415,12 @@ objfile::search (search_symtabs_file_matcher file_matcher,
 		objfile_debug_name (this),
 		host_address_to_string (&file_matcher),
 		host_address_to_string (&symbol_matcher),
-		host_address_to_string (&listener),
+		host_address_to_string (&compunit_callback),
 		domain_name (domain).c_str ());
 
   for (const auto &iter : qf)
     if (!iter->search (this, file_matcher, lookup_name, symbol_matcher,
-		       listener, search_flags, domain, lang_matcher))
+		       compunit_callback, search_flags, domain, lang_matcher))
       return false;
   return true;
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 03/11] gdb: introduce iteration_status enum, use it for search callbacks
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
  2026-04-16 20:16 ` [PATCH 01/11] gdb/dwarf: remove unused file_match parameter from dwarf2_base_index_functions::search_one Simon Marchi
  2026-04-16 20:16 ` [PATCH 02/11] gdb: rename search_symtabs_expansion_listener -> compunit_symtab_iteration_callback Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 04/11] gdb, gdbserver: make iterate_over_lwps_ftype a function_view Simon Marchi
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

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
---
 gdb/ada-lang.c                  |  6 +--
 gdb/cp-support.c                |  2 +-
 gdb/dwarf2/cooked-index-entry.c |  2 +-
 gdb/dwarf2/cooked-index-entry.h | 10 ++--
 gdb/dwarf2/cooked-index.h       |  2 +-
 gdb/dwarf2/index-write.c        |  4 +-
 gdb/dwarf2/read.c               | 66 +++++++++++++----------
 gdb/dwarf2/read.h               | 20 ++++---
 gdb/expanded-symbol.c           | 10 ++--
 gdb/expanded-symbol.h           | 15 +++---
 gdb/linespec.c                  |  4 +-
 gdb/objfiles.h                  | 19 ++++---
 gdb/python/py-symbol.c          | 18 ++++---
 gdb/quick-symbol.h              | 18 +++----
 gdb/symfile-debug.c             | 95 ++++++++++++++++++---------------
 gdb/symtab.c                    | 19 ++++---
 gdb/symtab.h                    |  6 ++-
 gdbsupport/iteration-status.h   | 48 +++++++++++++++++
 18 files changed, 224 insertions(+), 140 deletions(-)
 create mode 100644 gdbsupport/iteration-status.h

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 805999e18eea..f8ed4cc5e102 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -5568,7 +5568,7 @@ map_matching_symbols (struct objfile *objfile,
       bool result = iterate_over_symbols (block, lookup_name, domain, data);
       gdb_assert (result);
       data.finish (block);
-      return true;
+      return iteration_status::keep_going;
     };
 
   objfile->search (nullptr, &lookup_name, nullptr, callback,
@@ -13207,7 +13207,7 @@ ada_add_global_exceptions (compiled_regex *preg,
 		  }
 	    }
 
-	  return true;
+	  return iteration_status::keep_going;
 	};
 
       /* In Ada, the symbol "search name" is a linkage name, whereas
@@ -13883,7 +13883,7 @@ class ada_language : public language_defn
 		  }
 	      }
 
-	    return true;
+	    return iteration_status::keep_going;
 	  };
 
 	objfile.search
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index d321986f72da..d040ad79469a 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1490,7 +1490,7 @@ add_symbol_overload_list_qualified (const char *func_name,
 	     /* Don't do this block twice.  */
 	     if (b != surrounding_static_block)
 	       add_symbol_overload_list_block (func_name, b, overload_list);
-	     return true;
+	     return iteration_status::keep_going;
 	   };
 
 	 /* Look through the partial symtabs for all symbols which
diff --git a/gdb/dwarf2/cooked-index-entry.c b/gdb/dwarf2/cooked-index-entry.c
index 2f61e5c4c57b..21e25e946158 100644
--- a/gdb/dwarf2/cooked-index-entry.c
+++ b/gdb/dwarf2/cooked-index-entry.c
@@ -253,7 +253,7 @@ cooked_index_entry::force_set_language () const
 
 /* See cooked-index-entry.h.  */
 
-bool
+iteration_status
 cooked_index_entry::visit_defining_cus (per_cu_callback callback) const
 {
   if ((flags & IS_INLINED) == 0)
diff --git a/gdb/dwarf2/cooked-index-entry.h b/gdb/dwarf2/cooked-index-entry.h
index 9eed2ca9c46c..9f7a7c42de4f 100644
--- a/gdb/dwarf2/cooked-index-entry.h
+++ b/gdb/dwarf2/cooked-index-entry.h
@@ -232,12 +232,14 @@ struct cooked_index_entry : public allocate_on_obstack<cooked_index_entry>
   void force_set_language () const;
 
   /* Type of callback used when visiting defining CUs.  */
-  using per_cu_callback = gdb::function_view<bool (dwarf2_per_cu *)>;
+  using per_cu_callback
+    = gdb::function_view<iteration_status (dwarf2_per_cu *)>;
 
   /* Calls CALLBACK for each CU that "defines" this entry.
 
-     If any call to CALLBACK returns false, this immediately returns
-     false (skipping the remaining calls); otherwise returns true.
+     If any call to CALLBACK returns iteration_status::stop, this
+     immediately returns iteration_status::stop (skipping the remaining
+     calls); otherwise returns iteration_status::keep_going.
 
      For most entries, there is a single defining CU, which is the
      canonical outermost includer of the CU holding the entry.  In the
@@ -248,7 +250,7 @@ struct cooked_index_entry : public allocate_on_obstack<cooked_index_entry>
      such outermost includer -- if a subroutine is inlined in many
      places, and then "dwz" is run, the IS_INLINED subroutine may be
      defined in some CU that is included by many other CUs.  */
-  bool visit_defining_cus (per_cu_callback callback) const;
+  iteration_status visit_defining_cus (per_cu_callback callback) const;
 
   /* The name as it appears in DWARF.  This always points into one of
      the mapped DWARF sections.  Note that this may be the name or the
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 00a15661677b..2e177cb62dd2 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -237,7 +237,7 @@ struct cooked_index_functions : public dwarf2_base_index_functions
     dwarf2_base_index_functions::expand_all_symtabs (objfile);
   }
 
-  bool search
+  iteration_status search
     (struct objfile *objfile,
      search_symtabs_file_matcher file_matcher,
      const lookup_name_info *lookup_name,
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 0f940920862f..6f8e41ff96fa 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -721,7 +721,7 @@ class debug_names
 	    entry->visit_defining_cus ([&] (dwarf2_per_cu *one_cu)
 	      {
 		per_cus.push_back (one_cu);
-		return true;
+		return iteration_status::keep_going;
 	      });
 	    /* Make sure the output is stable.  */
 	    std::sort (per_cus.begin (), per_cus.end (),
@@ -1317,7 +1317,7 @@ write_cooked_index (cooked_index *table,
 	  gdb_assert (it != cu_index_htab.cend ());
 	  symtab->add_index_entry (name, (entry->flags & IS_STATIC) != 0,
 				   kind, it->second);
-	  return true;
+	  return iteration_status::keep_going;
 	});
     }
 }
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6146ff78b678..48e89d10eac7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1453,14 +1453,14 @@ struct readnow_functions : public dwarf2_base_index_functions
   {
   }
 
-  bool search (struct 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) override
+  iteration_status search (struct 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) override
   {
     dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
     auto_bool_vector cus_to_skip;
@@ -1481,11 +1481,13 @@ struct readnow_functions : public dwarf2_base_index_functions
 	    || per_objfile->get_compunit_symtab (per_cu.get ()) == nullptr)
 	  continue;
 
-	if (!search_one (per_cu.get (), per_objfile, cus_to_skip,
-			 compunit_callback, lang_matcher))
-	  return false;
+	if (search_one (per_cu.get (), per_objfile, cus_to_skip,
+			compunit_callback, lang_matcher)
+	    == iteration_status::stop)
+	  return iteration_status::stop;
       }
-    return true;
+
+    return iteration_status::keep_going;
   }
 
   struct symbol *find_symbol_by_address (struct objfile *objfile,
@@ -1919,7 +1921,7 @@ dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
 
 /* See read.h.  */
 
-bool
+iteration_status
 dwarf2_base_index_functions::search_one
   (dwarf2_per_cu *per_cu,
    dwarf2_per_objfile *per_objfile,
@@ -1929,7 +1931,7 @@ dwarf2_base_index_functions::search_one
 {
   /* Already visited, or intentionally skipped.  */
   if (cus_to_skip.is_set (per_cu->index))
-    return true;
+    return iteration_status::keep_going;
 
   if (lang_matcher != nullptr)
     {
@@ -1937,7 +1939,7 @@ dwarf2_base_index_functions::search_one
       per_cu->ensure_lang (per_objfile);
       if (!per_cu->maybe_multi_language ()
 	  && !lang_matcher (per_cu->lang ()))
-	return true;
+	return iteration_status::keep_going;
     }
 
   compunit_symtab *symtab
@@ -1950,7 +1952,7 @@ dwarf2_base_index_functions::search_one
       return compunit_callback (symtab);
     }
 
-  return true;
+  return iteration_status::keep_going;
 }
 
 /* If FILE_MATCHER is non-NULL, update CUS_TO_SKIP as appropriate
@@ -14030,7 +14032,7 @@ cooked_index_functions::find_symbol_by_address
   return cu->symbol_at_address (address);
 }
 
-bool
+iteration_status
 cooked_index_functions::search
   (objfile *objfile,
    search_symtabs_file_matcher file_matcher,
@@ -14056,11 +14058,13 @@ cooked_index_functions::search
 	{
 	  QUIT;
 
-	  if (!search_one (per_cu, per_objfile, cus_to_skip, compunit_callback,
-			   lang_matcher))
-	    return false;
+	  if (search_one (per_cu, per_objfile, cus_to_skip, compunit_callback,
+			  lang_matcher)
+	      == iteration_status::stop)
+	    return iteration_status::stop;
 	}
-      return true;
+
+      return iteration_status::keep_going;
     }
 
   lookup_name_info lookup_name_without_params
@@ -14222,17 +14226,19 @@ cooked_index_functions::search
 	  else if (!symbol_matcher (full_name))
 	    continue;
 
-	  bool check = entry->visit_defining_cus ([&] (dwarf2_per_cu *per_cu)
+	  iteration_status status
+	    = entry->visit_defining_cus ([&] (dwarf2_per_cu *per_cu)
 	    {
 	      return search_one (per_cu, per_objfile, cus_to_skip,
 				 compunit_callback, nullptr);
 	    });
-	  if (!check)
-	    return false;
+
+	  if (status == iteration_status::stop)
+	    return iteration_status::stop;
 	}
     }
 
-  return true;
+  return iteration_status::keep_going;
 }
 
 /* Start reading .debug_info using the indexer.  */
@@ -17989,15 +17995,17 @@ dwarf2_per_cu::ensure_lang (dwarf2_per_objfile *per_objfile)
 
 /* See read.h.  */
 
-bool
+iteration_status
 dwarf2_per_cu::recursively_visit_cus (per_cu_callback callback)
 {
   if (including_cus.empty ())
     return callback (this);
+
   for (dwarf2_per_cu *iter : including_cus)
-    if (!iter->recursively_visit_cus (callback))
-      return false;
-  return true;
+    if (iter->recursively_visit_cus (callback) == iteration_status::stop)
+      return iteration_status::stop;
+
+  return iteration_status::keep_going;
 }
 
 /* See read.h.  */
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 40b55a33bc8d..c65ee7f86990 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -32,6 +32,7 @@
 #include "gdbsupport/cxx-thread.h"
 #include "gdbsupport/gdb_obstack.h"
 #include "gdbsupport/function-view.h"
+#include "gdbsupport/iteration-status.h"
 #include "gdbsupport/packed.h"
 
 /* Hold 'maintenance (set|show) dwarf' commands.  */
@@ -429,13 +430,15 @@ struct dwarf2_per_cu
   }
 
   /* Type of callback used when visiting defining CUs.  */
-  using per_cu_callback = gdb::function_view<bool (dwarf2_per_cu *)>;
+  using per_cu_callback
+    = gdb::function_view<iteration_status (dwarf2_per_cu *)>;
 
   /* Calls CALLBACK for each CU that is the outermost includer of
      ONE_CU.  If ONE_CU has no includers, it calls CALLBACK on ONE_CU.
-     If any call to CALLBACK returns false, this immediately returns
-     false (skipping the remaining calls); otherwise returns true.  */
-  bool recursively_visit_cus (per_cu_callback callback);
+     If any call to CALLBACK returns iteration_status::stop, this
+     immediately returns iteration_status::stop (skipping the remaining
+     calls); otherwise returns iteration_status::keep_going.  */
+  iteration_status recursively_visit_cus (per_cu_callback callback);
 
   /* Return a canonical outermost CU corresponding to this CU.  If
      this CU is standalone (not included by other CUs), then this
@@ -1321,10 +1324,11 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
   /* If CUS_TO_SKIP does not include the CU's index and the CU's language
      matches LANG_MATCHER, expand the CU and call COMPUNIT_CALLBACK (if
      provided) on it.  */
-  bool search_one (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
-		   auto_bool_vector &cus_to_skip,
-		   compunit_symtab_iteration_callback compunit_callback,
-		   search_symtabs_lang_matcher lang_matcher);
+  iteration_status search_one
+    (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
+     auto_bool_vector &cus_to_skip,
+     compunit_symtab_iteration_callback compunit_callback,
+     search_symtabs_lang_matcher lang_matcher);
 };
 
 /* Return pointer to string at .debug_str offset STR_OFFSET.  */
diff --git a/gdb/expanded-symbol.c b/gdb/expanded-symbol.c
index fee55cd23db3..6dcb4047e3fe 100644
--- a/gdb/expanded-symbol.c
+++ b/gdb/expanded-symbol.c
@@ -47,7 +47,7 @@ expanded_symbols_functions::lookup_global_symbol_language
 
 /* See expanded-symbol.h.  */
 
-bool
+iteration_status
 expanded_symbols_functions::search
      (objfile *objfile,
       search_symtabs_file_matcher file_matcher,
@@ -92,10 +92,12 @@ expanded_symbols_functions::search
 	 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))
-	return false;
+      if (compunit_callback != nullptr
+	  && compunit_callback (cu) == iteration_status::stop)
+	return iteration_status::stop;
     }
-  return true;
+
+  return iteration_status::keep_going;
 }
 
 /* See expanded-symbol.h.  */
diff --git a/gdb/expanded-symbol.h b/gdb/expanded-symbol.h
index fc42938d9d3d..68f5532e6b8c 100644
--- a/gdb/expanded-symbol.h
+++ b/gdb/expanded-symbol.h
@@ -66,13 +66,14 @@ struct expanded_symbols_functions : public quick_symbol_functions
   {
   }
 
-  bool 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) override;
+  iteration_status 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) override;
 
   compunit_symtab *find_pc_sect_compunit_symtab
     (objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc,
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 981bd5faa4fc..4ea6d597a093 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1169,7 +1169,7 @@ iterate_over_all_matching_symtabs
 		    }
 		}
 
-	      return true;
+	      return iteration_status::keep_going;
 	    };
 
 	  objfile.search (nullptr, &lookup_name, nullptr, expand_callback,
@@ -3613,7 +3613,7 @@ collect_symtabs_from_filename (const char *file,
     {
       if (symtab_table.insert (symtab).second)
 	symtabs.push_back (symtab);
-      return false;
+      return iteration_status::keep_going;
     };
 
   /* Find that file's data.  */
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index aafac6ac93c6..8ae54b37bb79 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -583,9 +583,9 @@ struct objfile : intrusive_list_node<objfile>
      Then, this calls iterate_over_some_symtabs (or equivalent) over
      all newly-created symbol tables, passing CALLBACK to it.
      The result of this call is returned.  */
-  bool map_symtabs_matching_filename
+  iteration_status map_symtabs_matching_filename
     (const char *name, const char *real_path,
-     gdb::function_view<bool (symtab *)> callback);
+     gdb::function_view<iteration_status (symtab *)> callback);
 
   /* Check to see if the symbol is defined in a "partial" symbol table
      of this objfile.  BLOCK_INDEX should be either GLOBAL_BLOCK or
@@ -618,14 +618,13 @@ struct objfile : intrusive_list_node<objfile>
   void expand_symtabs_with_fullname (const char *fullname);
 
   /* See quick_symbol_functions.  */
-  bool search
-    (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 = nullptr);
+  iteration_status search (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 = nullptr);
 
   /* See quick_symbol_functions.  */
   struct compunit_symtab *
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index e74c8e4b3680..6293b658ea1d 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -599,7 +599,7 @@ gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
 	      /* Skip included compunits to prevent including compunits from
 		 being searched twice.  */
 	      if (cust->user != nullptr)
-		return true;
+		return iteration_status::keep_going;
 
 	      const struct blockvector *bv = cust->blockvector ();
 	      const struct block *block = bv->static_block ();
@@ -615,16 +615,22 @@ gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
 		      if (sym_obj == nullptr
 			  || PyList_Append (return_list.get (),
 					    sym_obj.get ()) == -1)
-			return false;
+			return iteration_status::stop;
 		    }
 		}
 
-	      return true;
+	      return iteration_status::keep_going;
 	    };
 
-	  if (!objfile.search (nullptr, &lookup_name, nullptr, callback,
-			       SEARCH_STATIC_BLOCK, flags))
-	    return nullptr;
+	  /* The only reason why the iteration would stop is if an error was
+	     encountered during the callback execution.  */
+	  if (objfile.search (nullptr, &lookup_name, nullptr, callback,
+			      SEARCH_STATIC_BLOCK, flags)
+	      == iteration_status::stop)
+	    {
+	      gdb_assert (PyErr_Occurred ());
+	      return nullptr;
+	    }
 	}
     }
   catch (const gdb_exception &except)
diff --git a/gdb/quick-symbol.h b/gdb/quick-symbol.h
index 9cecc1bf52c1..2d1ca78293dd 100644
--- a/gdb/quick-symbol.h
+++ b/gdb/quick-symbol.h
@@ -21,6 +21,7 @@
 #define GDB_QUICK_SYMBOL_H
 
 #include "symtab.h"
+#include "gdbsupport/iteration-status.h"
 
 /* Like block_enum, but used as flags to pass to lookup functions.  */
 
@@ -56,12 +57,10 @@ using search_symtabs_lang_matcher
   = gdb::function_view<bool (enum language lang)>;
 
 /* Callback for quick_symbol_functions::search to be called when a
-   compunit_symtab matches (perhaps expanding it first).  If this
-   returns true, more compunit_symtabs are checked; if it returns false,
-   iteration stops.  */
+   compunit_symtab matches (perhaps expanding it first).  */
 
 using compunit_symtab_iteration_callback
-  = gdb::function_view<bool (compunit_symtab *symtab)>;
+  = gdb::function_view<iteration_status (compunit_symtab *symtab)>;
 
 /* The "quick" symbol functions exist so that symbol readers can
    avoiding an initial read of all the symbols.  For example, symbol
@@ -153,11 +152,12 @@ struct quick_symbol_functions
 
      Then (regardless of whether the symbol table was already
      expanded, or just expanded in response to this search),
-     COMPUNIT_CALLBACK is called.  If COMPUNIT_CALLBACK returns false,
-     execution stops and this method returns false.  Otherwise, more
-     files are considered.  This method returns true if all calls to
-     COMPUNIT_CALLBACK return true.  */
-  virtual bool search
+     COMPUNIT_CALLBACK is called.  If COMPUNIT_CALLBACK returns
+     iteration_status::stop, execution stops and this method returns
+     iteration_status::stop.  Otherwise, more files are considered.  This
+     method returns iteration_status::keep_going if all calls to
+     COMPUNIT_CALLBACK return iteration_status::keep_going.  */
+  virtual iteration_status search
     (struct objfile *objfile,
      search_symtabs_file_matcher file_matcher,
      const lookup_name_info *lookup_name,
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index d26662e20656..8e4892649508 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -170,19 +170,18 @@ objfile::forget_cached_source_info ()
    CUST indicates which compunit symtab to search.  Each symtab within
    the specified compunit symtab is also searched.  */
 
-static bool
-iterate_over_one_compunit_symtab (const char *base_name,
-				  const char *name,
-				  const char *real_path,
-				  compunit_symtab *cust,
-				  gdb::function_view<bool (symtab *)> callback)
+static iteration_status
+iterate_over_one_compunit_symtab
+  (const char *base_name, const char *name, const char *real_path,
+   compunit_symtab *cust,
+   gdb::function_view<iteration_status (symtab *)> callback)
 {
   for (symtab *s : cust->filetabs ())
     {
       if (compare_filenames_for_search (s->filename (), name))
 	{
-	  if (callback (s))
-	    return true;
+	  if (callback (s) == iteration_status::stop)
+	    return iteration_status::stop;
 	  continue;
 	}
 
@@ -194,8 +193,8 @@ iterate_over_one_compunit_symtab (const char *base_name,
 
       if (compare_filenames_for_search (symtab_to_fullname (s), name))
 	{
-	  if (callback (s))
-	    return true;
+	  if (callback (s) == iteration_status::stop)
+	    return iteration_status::stop;
 	  continue;
 	}
 
@@ -212,25 +211,26 @@ iterate_over_one_compunit_symtab (const char *base_name,
 	  fullname = fullname_real_path.get ();
 	  if (FILENAME_CMP (real_path, fullname) == 0)
 	    {
-	      if (callback (s))
-		return true;
+	      if (callback (s) == iteration_status::stop)
+		return iteration_status::stop;
 	      continue;
 	    }
 	}
     }
 
   for (compunit_symtab *iter : cust->includes)
-    if (iterate_over_one_compunit_symtab (base_name, name, real_path,
-					  iter, callback))
-      return true;
+    if (iterate_over_one_compunit_symtab (base_name, name, real_path, iter,
+					  callback)
+	== iteration_status::stop)
+      return iteration_status::stop;
 
-  return false;
+  return iteration_status::keep_going;
 }
 
-bool
+iteration_status
 objfile::map_symtabs_matching_filename
   (const char *name, const char *real_path,
-   gdb::function_view<bool (symtab *)> callback)
+   gdb::function_view<iteration_status (symtab *)> callback)
 {
   if (debug_symfile)
     gdb_printf (gdb_stdlog,
@@ -240,7 +240,6 @@ objfile::map_symtabs_matching_filename
 		real_path ? real_path : NULL,
 		host_address_to_string (&callback));
 
-  bool retval = false;
   const char *name_basename = lbasename (name);
 
   auto match_one_filename = [&] (const char *filename, bool basenames)
@@ -260,30 +259,37 @@ objfile::map_symtabs_matching_filename
     /* Skip included compunits, as they are searched by
        iterate_over_one_compunit_symtab.  */
     if (symtab->user != nullptr)
-      return true;
+      return iteration_status::keep_going;
 
-    /* CALLBACK returns false to keep going and true to continue, so
-       we have to invert the result here, for search.  */
-    return !iterate_over_one_compunit_symtab (name_basename, name, real_path,
-					      symtab, callback);
+    /* iterate_over_one_compunit_symtab returns true to stop,
+       convert to iteration_status.  */
+    if (iterate_over_one_compunit_symtab (name_basename, name, real_path,
+					  symtab, callback)
+	== iteration_status::stop)
+      return iteration_status::stop;
+
+    return iteration_status::keep_going;
   };
 
+  iteration_status retval = iteration_status::keep_going;
+
   for (const auto &iter : qf)
     {
-      if (!iter->search (this, match_one_filename, nullptr, nullptr,
-			 compunit_callback,
-			 SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
-			 SEARCH_ALL_DOMAINS))
+      if (iter->search (this, match_one_filename, nullptr, nullptr,
+			compunit_callback,
+			SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
+			SEARCH_ALL_DOMAINS)
+	  == iteration_status::stop)
 	{
-	  retval = true;
+	  retval = iteration_status::stop;
 	  break;
 	}
     }
 
   if (debug_symfile)
     gdb_printf (gdb_stdlog,
-		"qf->map_symtabs_matching_filename (...) = %d\n",
-		retval);
+		"qf->map_symtabs_matching_filename (...) = %s\n",
+		iteration_status_str (retval));
 
   return retval;
 }
@@ -316,22 +322,23 @@ objfile::lookup_symbol (block_enum kind, const lookup_name_info &name,
       {
 	retval = stab;
 	/* Found it.  */
-	return false;
+	return iteration_status::stop;
       }
     if (with_opaque != nullptr)
       retval = stab;
 
     /* Keep looking through other psymtabs.  */
-    return true;
+    return iteration_status::keep_going;
   };
 
   for (const auto &iter : qf)
     {
-      if (!iter->search (this, nullptr, &name, nullptr, search_one_symtab,
-			 kind == GLOBAL_BLOCK
-			 ? SEARCH_GLOBAL_BLOCK
-			 : SEARCH_STATIC_BLOCK,
-			 domain))
+      if (iter->search (this, nullptr, &name, nullptr, search_one_symtab,
+			kind == GLOBAL_BLOCK
+			? SEARCH_GLOBAL_BLOCK
+			: SEARCH_STATIC_BLOCK,
+			domain)
+	  == iteration_status::stop)
 	break;
     }
 
@@ -397,7 +404,7 @@ objfile::expand_symtabs_with_fullname (const char *fullname)
 		  SEARCH_ALL_DOMAINS);
 }
 
-bool
+iteration_status
 objfile::search (search_symtabs_file_matcher file_matcher,
 		 const lookup_name_info *lookup_name,
 		 search_symtabs_symbol_matcher symbol_matcher,
@@ -419,10 +426,12 @@ objfile::search (search_symtabs_file_matcher file_matcher,
 		domain_name (domain).c_str ());
 
   for (const auto &iter : qf)
-    if (!iter->search (this, file_matcher, lookup_name, symbol_matcher,
-		       compunit_callback, search_flags, domain, lang_matcher))
-      return false;
-  return true;
+    if (iter->search (this, file_matcher, lookup_name, symbol_matcher,
+		      compunit_callback, search_flags, domain, lang_matcher)
+	== iteration_status::stop)
+      return iteration_status::stop;
+
+  return iteration_status::keep_going;
 }
 
 struct compunit_symtab *
diff --git a/gdb/symtab.c b/gdb/symtab.c
index a6b145e5331b..d22dd81a246a 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -633,7 +633,7 @@ compare_filenames_for_search (const char *filename, const char *search_name)
 
 void
 iterate_over_symtabs (program_space *pspace, const char *name,
-		      gdb::function_view<bool (symtab *)> callback)
+		      gdb::function_view<iteration_status (symtab *)> callback)
 {
   gdb::unique_xmalloc_ptr<char> real_path;
 
@@ -647,7 +647,8 @@ iterate_over_symtabs (program_space *pspace, const char *name,
 
   for (objfile &objfile : pspace->objfiles ())
     if (objfile.map_symtabs_matching_filename (name, real_path.get (),
-					       callback))
+					       callback)
+	== iteration_status::stop)
       return;
 }
 
@@ -661,7 +662,7 @@ lookup_symtab (program_space *pspace, const char *name)
   iterate_over_symtabs (pspace, name, [&] (symtab *symtab)
     {
       result = symtab;
-      return true;
+      return iteration_status::stop;
     });
 
   return result;
@@ -2381,9 +2382,11 @@ lookup_symbol_via_quick_fns (struct objfile *objfile,
     {
       const struct blockvector *bv = symtab->blockvector ();
       const struct block *block = bv->block (block_index);
-      /* If the accumulator finds a best symbol, end the search by
-	 returning false; otherwise keep going by returning true.  */
-      return !accum.search (symtab, block, lookup_name, domain);
+      /* End the search if the accumulator finds a best symbol.  */
+      if (accum.search (symtab, block, lookup_name, domain))
+	return iteration_status::stop;
+
+      return iteration_status::keep_going;
     };
 
   objfile->search (nullptr, &lookup_name, nullptr, searcher,
@@ -5952,7 +5955,7 @@ default_collect_symbol_completion_matches_break_on
 	     add_symtab_completions (symtab,
 				     tracker, mode, lookup_name,
 				     sym_text, word, code);
-	     return true;
+	     return iteration_status::keep_going;
 	   },
 	 SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
 	 SEARCH_ALL_DOMAINS);
@@ -6142,7 +6145,7 @@ collect_file_symbol_completion_matches (completion_tracker &tracker,
       add_symtab_completions (s->compunit (),
 			      tracker, mode, lookup_name,
 			      sym_text, word, TYPE_CODE_UNDEF);
-      return false;
+      return iteration_status::keep_going;
     });
 }
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 0db85bcf5baa..9e45f087adda 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -30,6 +30,7 @@
 #include "gdbsupport/gdb_regex.h"
 #include "gdbsupport/enum-flags.h"
 #include "gdbsupport/function-view.h"
+#include "gdbsupport/iteration-status.h"
 #include <optional>
 #include <string_view>
 #include "gdbsupport/next-iterator.h"
@@ -2795,8 +2796,9 @@ bool compare_filenames_for_search (const char *filename,
    Call CALLBACK with each symtab that is found.  If CALLBACK returns
    true, the search stops.  */
 
-void iterate_over_symtabs (program_space *pspace, const char *name,
-			   gdb::function_view<bool (symtab *)> callback);
+void iterate_over_symtabs
+  (program_space *pspace, const char *name,
+   gdb::function_view<iteration_status (symtab *)> callback);
 
 std::vector<const linetable_entry *> find_linetable_entries_for_symtab_line
     (struct symtab *symtab, int line, const linetable_entry **best_entry);
diff --git a/gdbsupport/iteration-status.h b/gdbsupport/iteration-status.h
new file mode 100644
index 000000000000..c4c17fea4fb5
--- /dev/null
+++ b/gdbsupport/iteration-status.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 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/>.  */
+
+#ifndef GDBSUPPORT_ITERATION_STATUS_H
+#define GDBSUPPORT_ITERATION_STATUS_H
+
+/* Return type for iteration callbacks.
+
+   Using an enum makes it clear at each call site whether the callback wants to
+   stop or continue, unlike a plain bool where the convention can change between
+   APIs.  */
+
+enum class iteration_status
+{
+  keep_going,
+  stop,
+};
+
+constexpr const char *
+iteration_status_str (iteration_status status)
+{
+  switch (status)
+    {
+    case iteration_status::keep_going:
+      return "keep_going";
+
+    case iteration_status::stop:
+      return "stop";
+    }
+
+  gdb_assert_not_reached ("invalid iteration_status value");
+}
+
+#endif /* GDBSUPPORT_ITERATION_STATUS_H */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 04/11] gdb, gdbserver: make iterate_over_lwps_ftype a function_view
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (2 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 03/11] gdb: introduce iteration_status enum, use it for search callbacks Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 05/11] gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp Simon Marchi
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

All users of iterate_over_lwps_ftype use it within a function_view
template.  Integrate function_view to the type alias.

Change-Id: I3eb23aa3dbc1889072a5d4654e861b00942d6c3f
---
 gdb/linux-nat.c        | 5 ++---
 gdb/nat/linux-nat.h    | 7 +++----
 gdbserver/linux-low.cc | 5 ++---
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index f141ba19ea44..362ef5f1cb75 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -928,9 +928,8 @@ find_lwp_pid (ptid_t ptid)
 
 /* See nat/linux-nat.h.  */
 
-struct lwp_info *
-iterate_over_lwps (ptid_t filter,
-		   gdb::function_view<iterate_over_lwps_ftype> callback)
+lwp_info *
+iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback)
 {
   for (lwp_info &lp : all_lwps_safe ())
     {
diff --git a/gdb/nat/linux-nat.h b/gdb/nat/linux-nat.h
index 708990acc4d9..42c0467191fe 100644
--- a/gdb/nat/linux-nat.h
+++ b/gdb/nat/linux-nat.h
@@ -47,7 +47,7 @@ extern tribool have_ptrace_getregset;
 extern ptid_t current_lwp_ptid (void);
 
 /* Function type for the CALLBACK argument of iterate_over_lwps.  */
-typedef int (iterate_over_lwps_ftype) (struct lwp_info *lwp);
+using iterate_over_lwps_ftype = gdb::function_view<int (lwp_info *lwp)>;
 
 /* Iterate over all LWPs.  Calls CALLBACK with its second argument set
    to DATA for every LWP in the list.  If CALLBACK returns nonzero for
@@ -55,9 +55,8 @@ typedef int (iterate_over_lwps_ftype) (struct lwp_info *lwp);
    LWP immediately.  Otherwise return NULL.  This function must be
    provided by the client.  */
 
-extern struct lwp_info *iterate_over_lwps
-    (ptid_t filter,
-     gdb::function_view<iterate_over_lwps_ftype> callback);
+extern lwp_info *iterate_over_lwps (ptid_t filter,
+				    iterate_over_lwps_ftype callback);
 
 /* Return the ptid of LWP.  */
 
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 0246217db86c..022e8415fda8 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -1768,9 +1768,8 @@ num_lwps (process_info *process)
 
 /* See nat/linux-nat.h.  */
 
-struct lwp_info *
-iterate_over_lwps (ptid_t filter,
-		   gdb::function_view<iterate_over_lwps_ftype> callback)
+lwp_info *
+iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback)
 {
   thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
     {
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 05/11] gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (3 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 04/11] gdb, gdbserver: make iterate_over_lwps_ftype a function_view Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 06/11] gdb: split iterate_over_threads in for_each_thread and find_thread Simon Marchi
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Even though it works, I have always been mildly annoyed by
iterate_over_lwps being used for both iterating over all lwps and
finding one lwp matching a criterion.  I think it would be clearer to
have two functions for the two use cases.  Then it would be 100% clear
at the call site what the intention is.  It would be clear that a
callback returning bool is meant to be a predicate for the find
function, while a callback returning void is meant to be a callback for
the "for each" function.

Therefore, split iterate_over_lwps in two:

 - find_lwp to find the first lwp matching a boolean predicate (and the
   given ptid filter)
 - for_each_lwp to apply a function on all lwps (optionally filtering by
   ptid or pid)

The callbacks given to for_each_lwp can now return void.

Introduce some overloads for for_each_lwp, for the various common use
cases:

 - filtering by ptid
 - filtering by pid
 - no ptid/pid filter

find_lwp and two overloads of for_each_lwp are actually only used in
gdb/linux-nat.c, so make them local to that file.  Only the pid variant
of for_each_lwp is used in shared code.

The pattern used in this patch serves as the basis for subsequent
patches that split other "iterate over" functions the same way.

Change-Id: I49d3af0916622300cc81e3c32d22e1aff13cf38f
---
 gdb/arm-linux-nat.c                |  38 ++--
 gdb/linux-nat.c                    | 276 +++++++++++++++--------------
 gdb/nat/aarch64-linux-hw-point.c   |  17 +-
 gdb/nat/linux-nat.h                |  16 +-
 gdb/nat/loongarch-linux-hw-point.c |  18 +-
 gdb/nat/x86-linux-dregs.c          |  15 +-
 gdb/ppc-linux-nat.c                |  22 +--
 gdb/s390-linux-nat.c               |  22 +--
 gdbserver/linux-low.cc             |  20 +--
 9 files changed, 208 insertions(+), 236 deletions(-)

diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 9d7bd6e09c97..b3d4ce1ec37a 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -960,7 +960,7 @@ arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1,
 /* Callback to mark a watch-/breakpoint to be updated in all threads of
    the current process.  */
 
-static int
+static void
 update_registers_callback (struct lwp_info *lwp, int watch, int index)
 {
   if (lwp->arch_private == NULL)
@@ -977,8 +977,6 @@ update_registers_callback (struct lwp_info *lwp, int watch, int index)
      we can update its breakpoint registers.  */
   if (!lwp->stopped)
     linux_stop_lwp (lwp);
-
-  return 0;
 }
 
 /* Insert the hardware breakpoint (WATCHPOINT = 0) or watchpoint (WATCHPOINT
@@ -987,14 +985,10 @@ static void
 arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt,
 				 int watchpoint)
 {
-  int pid;
-  ptid_t pid_ptid;
+  int pid = inferior_ptid.pid ();
   gdb_byte count, i;
   struct arm_linux_hw_breakpoint* bpts;
 
-  pid = inferior_ptid.pid ();
-  pid_ptid = ptid_t (pid);
-
   if (watchpoint)
     {
       count = arm_linux_get_hw_watchpoint_count ();
@@ -1010,12 +1004,11 @@ arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt,
     if (!arm_hwbp_control_is_enabled (bpts[i].control))
       {
 	bpts[i] = *bpt;
-	iterate_over_lwps (pid_ptid,
-			   [=] (struct lwp_info *info)
-			   {
-			     return update_registers_callback (info, watchpoint,
-							       i);
-			   });
+	for_each_lwp (pid,
+		      [=] (struct lwp_info *info)
+		      {
+			update_registers_callback (info, watchpoint, i);
+		      });
 	break;
       }
 
@@ -1028,14 +1021,10 @@ static void
 arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt,
 				 int watchpoint)
 {
-  int pid;
+  int pid = inferior_ptid.pid ();
   gdb_byte count, i;
-  ptid_t pid_ptid;
   struct arm_linux_hw_breakpoint* bpts;
 
-  pid = inferior_ptid.pid ();
-  pid_ptid = ptid_t (pid);
-
   if (watchpoint)
     {
       count = arm_linux_get_hw_watchpoint_count ();
@@ -1051,12 +1040,11 @@ arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt,
     if (arm_linux_hw_breakpoint_equal (bpt, bpts + i))
       {
 	bpts[i].control = arm_hwbp_control_disable (bpts[i].control);
-	iterate_over_lwps (pid_ptid,
-			   [=] (struct lwp_info *info)
-			   {
-			     return update_registers_callback (info, watchpoint,
-							       i);
-			   });
+	for_each_lwp (pid,
+		      [=] (struct lwp_info *info)
+		      {
+			update_registers_callback (info, watchpoint, i);
+		      });
 	break;
       }
 
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 362ef5f1cb75..15fca3f6d35e 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -278,7 +278,7 @@ static bool report_thread_events;
 
 static int kill_lwp (int lwpid, int signo);
 
-static int stop_callback (struct lwp_info *lp);
+static void stop_callback (struct lwp_info *lp);
 
 static void block_child_signals (sigset_t *prev_mask);
 static void restore_child_signals_mask (sigset_t *prev_mask);
@@ -795,8 +795,9 @@ linux_nat_target::pass_signals
 \f
 
 /* Prototypes for local functions.  */
-static int stop_wait_callback (struct lwp_info *lp);
-static int resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid);
+static void stop_wait_callback (struct lwp_info *lp);
+static void resume_stopped_resumed_lwps (struct lwp_info *lp,
+					 const ptid_t wait_ptid);
 static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 
 \f
@@ -928,19 +929,51 @@ find_lwp_pid (ptid_t ptid)
 
 /* See nat/linux-nat.h.  */
 
-lwp_info *
-iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback)
+void
+for_each_lwp (int pid, for_each_lwp_ftype callback)
 {
   for (lwp_info &lp : all_lwps_safe ())
-    {
-      if (lp.ptid.matches (filter))
-	{
-	  if (callback (&lp) != 0)
-	    return &lp;
-	}
-    }
+    if (lp.ptid.pid () == pid)
+      callback (&lp);
+}
 
-  return NULL;
+/* Iterate over all LWPs, calling CALLBACK for every LWP.
+
+   Only consider the LWPs matching FILTER.  */
+
+static void
+for_each_lwp (ptid_t filter, for_each_lwp_ftype callback)
+{
+  for (lwp_info &lp : all_lwps_safe ())
+    if (lp.ptid.matches (filter))
+      callback (&lp);
+}
+
+/* Iterate over all LWPs, calling CALLBACK for every LWP.  */
+
+static void
+for_each_lwp (for_each_lwp_ftype callback)
+{
+  for (lwp_info &lp : all_lwps_safe ())
+    callback (&lp);
+}
+
+/* Function type for the CALLBACK argument of find_lwp.  */
+
+using find_lwp_ftype = gdb::function_view<bool (lwp_info *lwp)>;
+
+/* Find the first LWP matching FILTER and the criteria specified by CALLBACK.
+
+   Return nullptr if no matching LWP is found.  */
+
+static lwp_info *
+find_lwp (ptid_t filter, find_lwp_ftype callback)
+{
+  for (lwp_info &lp : all_lwps_safe ())
+    if (lp.ptid.matches (filter) && callback (&lp))
+      return &lp;
+
+  return nullptr;
 }
 
 /* Update our internal state when changing from one checkpoint to
@@ -1220,14 +1253,13 @@ linux_nat_target::attach (const char *args, int from_tty)
     {
       /* Failed to attach to some LWP.  Detach any we've already
 	 attached to.  */
-      iterate_over_lwps (ptid_t (ptid.pid ()),
-			 [] (struct lwp_info *lwp) -> int
-			 {
-			   /* Ignore errors when detaching.  */
-			   ptrace (PTRACE_DETACH, lwp->ptid.lwp (), 0, 0);
-			   delete_lwp (lwp->ptid);
-			   return 0;
-			 });
+      for_each_lwp (ptid.pid (),
+		    [] (struct lwp_info *lwp)
+		      {
+			/* Ignore errors when detaching.  */
+			ptrace (PTRACE_DETACH, lwp->ptid.lwp (), 0, 0);
+			delete_lwp (lwp->ptid);
+		      });
 
       target_terminal::ours ();
       target_mourn_inferior (inferior_ptid);
@@ -1236,18 +1268,17 @@ linux_nat_target::attach (const char *args, int from_tty)
     }
 
   /* Add all the LWPs to gdb's thread list.  */
-  iterate_over_lwps (ptid_t (ptid.pid ()),
-		     [] (struct lwp_info *lwp) -> int
-		     {
-		       if (lwp->ptid.pid () != lwp->ptid.lwp ())
-			 {
-			   add_thread (linux_target, lwp->ptid);
-			   set_state (linux_target, lwp->ptid, THREAD_RUNNING);
-			   set_internal_state (linux_target, lwp->ptid,
-					       THREAD_INT_RUNNING);
-			 }
-		       return 0;
-		     });
+  for_each_lwp (ptid.pid (),
+		[] (struct lwp_info *lwp)
+		  {
+		    if (lwp->ptid.pid () != lwp->ptid.lwp ())
+		      {
+			add_thread (linux_target, lwp->ptid);
+			set_state (linux_target, lwp->ptid, THREAD_RUNNING);
+			set_internal_state (linux_target, lwp->ptid,
+					    THREAD_INT_RUNNING);
+		      }
+		  });
 }
 
 /* Ptrace-detach the thread with pid PID.  */
@@ -1513,7 +1544,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
   delete_lwp (lp->ptid);
 }
 
-static int
+static void
 detach_callback (struct lwp_info *lp)
 {
   /* We don't actually detach from the thread group leader just yet.
@@ -1521,7 +1552,6 @@ detach_callback (struct lwp_info *lp)
      before we're able to reap the leader.  */
   if (lp->ptid.lwp () != lp->ptid.pid ())
     detach_one_lwp (lp, NULL);
-  return 0;
 }
 
 void
@@ -1537,17 +1567,17 @@ linux_nat_target::detach (inferior *inf, int from_tty)
 
   /* Stop all threads before detaching.  ptrace requires that the
      thread is stopped to successfully detach.  */
-  iterate_over_lwps (ptid_t (pid), stop_callback);
+  for_each_lwp (pid, stop_callback);
   /* ... and wait until all of them have reported back that
      they're no longer running.  */
-  iterate_over_lwps (ptid_t (pid), stop_wait_callback);
+  for_each_lwp (pid, stop_wait_callback);
 
   /* We can now safely remove breakpoints.  We don't this in earlier
      in common code because this target doesn't currently support
      writing memory while the inferior is running.  */
   remove_breakpoints_inf (current_inferior ());
 
-  iterate_over_lwps (ptid_t (pid), detach_callback);
+  for_each_lwp (pid, detach_callback);
 
   /* We have detached from everything except the main thread now, so
      should only have one thread left.  However, in non-stop mode the
@@ -1708,16 +1738,16 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
 			    lp->ptid.to_string ().c_str ());
 }
 
-/* Callback for iterate_over_lwps.  If LWP is EXCEPT, do nothing.
-   Resume LWP with the last stop signal, if it is in pass state.  */
+/* Callback for for_each_lwp.  If LP is EXCEPT, do nothing.
+   Resume LP with the last stop signal, if it is in pass state.  */
 
-static int
+static void
 linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
 {
   enum gdb_signal signo = GDB_SIGNAL_0;
 
   if (lp == except)
-    return 0;
+    return;
 
   if (lp->stopped)
     {
@@ -1732,23 +1762,20 @@ linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
     }
 
   resume_lwp (lp, 0, signo);
-  return 0;
 }
 
-static int
+static void
 resume_clear_callback (struct lwp_info *lp)
 {
   lp->resumed = 0;
   lp->last_resume_kind = resume_stop;
-  return 0;
 }
 
-static int
+static void
 resume_set_callback (struct lwp_info *lp)
 {
   lp->resumed = 1;
   lp->last_resume_kind = resume_continue;
-  return 0;
 }
 
 void
@@ -1765,7 +1792,7 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
 
   /* Mark the lwps we're resuming as resumed and update their
      last_resume_kind to resume_continue.  */
-  iterate_over_lwps (scope_ptid, resume_set_callback);
+  for_each_lwp (scope_ptid, resume_set_callback);
 
   lp = find_lwp_pid (inferior_ptid);
   gdb_assert (lp != NULL);
@@ -1818,9 +1845,9 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
 
   /* No use iterating unless we're resuming other threads.  */
   if (scope_ptid != lp->ptid)
-    iterate_over_lwps (scope_ptid, [=] (struct lwp_info *info)
+    for_each_lwp (scope_ptid, [=] (struct lwp_info *info)
       {
-	return linux_nat_resume_callback (info, lp);
+	linux_nat_resume_callback (info, lp);
       });
 
   linux_nat_debug_printf ("%s %s, %s (resume event thread)",
@@ -2367,7 +2394,7 @@ wait_lwp (struct lwp_info *lp)
 
 /* Send a SIGSTOP to LP.  */
 
-static int
+static void
 stop_callback (struct lwp_info *lp)
 {
   if (!lp->stopped && !lp->signalled)
@@ -2385,8 +2412,6 @@ stop_callback (struct lwp_info *lp)
       lp->signalled = 1;
       gdb_assert (lp->status == 0);
     }
-
-  return 0;
 }
 
 /* Request a stop on LWP.  */
@@ -2403,11 +2428,11 @@ void
 linux_stop_and_wait_all_lwps (void)
 {
   /* Stop all LWP's ...  */
-  iterate_over_lwps (minus_one_ptid, stop_callback);
+  for_each_lwp (stop_callback);
 
   /* ... and wait until all of them have reported back that
      they're no longer running.  */
-  iterate_over_lwps (minus_one_ptid, stop_wait_callback);
+  for_each_lwp (stop_wait_callback);
 }
 
 /* See linux-nat.h  */
@@ -2415,11 +2440,10 @@ linux_stop_and_wait_all_lwps (void)
 void
 linux_unstop_all_lwps (void)
 {
-  iterate_over_lwps (minus_one_ptid,
-		     [] (struct lwp_info *info)
-		     {
-		       return resume_stopped_resumed_lwps (info, minus_one_ptid);
-		     });
+  for_each_lwp ([] (struct lwp_info *info)
+		{
+		  resume_stopped_resumed_lwps (info, minus_one_ptid);
+		});
 }
 
 /* Return non-zero if LWP PID has a pending SIGINT.  */
@@ -2440,7 +2464,7 @@ linux_nat_has_pending_sigint (int pid)
 
 /* Set a flag in LP indicating that we should ignore its next SIGINT.  */
 
-static int
+static void
 set_ignore_sigint (struct lwp_info *lp)
 {
   /* If a thread has a pending SIGINT, consume it; otherwise, set a
@@ -2450,8 +2474,6 @@ set_ignore_sigint (struct lwp_info *lp)
     lp->status = 0;
   else
     lp->ignore_sigint = 1;
-
-  return 0;
 }
 
 /* If LP does not have a SIGINT pending, then clear the ignore_sigint flag.
@@ -2540,7 +2562,7 @@ linux_nat_target::low_status_is_event (int status)
 
 /* Wait until LP is stopped.  */
 
-static int
+static void
 stop_wait_callback (struct lwp_info *lp)
 {
   inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
@@ -2548,7 +2570,7 @@ stop_wait_callback (struct lwp_info *lp)
   /* If this is a vfork parent, bail out, it is not going to report
      any SIGSTOP until the vfork is done with.  */
   if (inf->vfork_child != NULL)
-    return 0;
+    return;
 
   if (!lp->stopped)
     {
@@ -2556,7 +2578,7 @@ stop_wait_callback (struct lwp_info *lp)
 
       status = wait_lwp (lp);
       if (status == 0)
-	return 0;
+	return;
 
       if (lp->ignore_sigint && WIFSTOPPED (status)
 	  && WSTOPSIG (status) == SIGINT)
@@ -2608,8 +2630,6 @@ stop_wait_callback (struct lwp_info *lp)
 	    }
 	}
     }
-
-  return 0;
 }
 
 /* Get the inferior associated to LWP.  Must be called with an LWP that has
@@ -2623,20 +2643,20 @@ lwp_inferior (const lwp_info *lwp)
   return inf;
 }
 
-/* Return non-zero if LP has a wait status pending.  Discard the
+/* Return true if LP has a wait status pending.  Discard the
    pending event and resume the LWP if the event that originally
    caused the stop became uninteresting.  */
 
-static int
+static bool
 status_callback (struct lwp_info *lp)
 {
   /* Only report a pending wait status if we pretend that this has
      indeed been resumed.  */
   if (!lp->resumed)
-    return 0;
+    return false;
 
   if (!lwp_status_pending_p (lp))
-    return 0;
+    return false;
 
   if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
       || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
@@ -2664,16 +2684,16 @@ status_callback (struct lwp_info *lp)
 
 	  lp->status = 0;
 	  linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
-	  return 0;
+	  return false;
 	}
     }
 
-  return 1;
+  return true;
 }
 
 /* Count the LWP's that have had events.  */
 
-static int
+static void
 count_events_callback (struct lwp_info *lp, int *count)
 {
   gdb_assert (count != NULL);
@@ -2681,20 +2701,14 @@ count_events_callback (struct lwp_info *lp, int *count)
   /* Select only resumed LWPs that have an event pending.  */
   if (lp->resumed && lwp_status_pending_p (lp))
     (*count)++;
-
-  return 0;
 }
 
 /* Select the LWP (if any) that is currently being single-stepped.  */
 
-static int
+static bool
 select_singlestep_lwp_callback (struct lwp_info *lp)
 {
-  if (lp->last_resume_kind == resume_step
-      && lp->status != 0)
-    return 1;
-  else
-    return 0;
+  return lp->last_resume_kind == resume_step && lp->status != 0;
 }
 
 /* Returns true if LP has a status pending.  */
@@ -2710,7 +2724,7 @@ lwp_status_pending_p (struct lwp_info *lp)
 
 /* Select the Nth LWP that has had an event.  */
 
-static int
+static bool
 select_event_lwp_callback (struct lwp_info *lp, int *selector)
 {
   gdb_assert (selector != NULL);
@@ -2718,9 +2732,9 @@ select_event_lwp_callback (struct lwp_info *lp, int *selector)
   /* Select only resumed LWPs that have an event pending.  */
   if (lp->resumed && lwp_status_pending_p (lp))
     if ((*selector)-- == 0)
-      return 1;
+      return true;
 
-  return 0;
+  return false;
 }
 
 /* Called when the LWP stopped for a signal/trap.  If it stopped for a
@@ -2888,7 +2902,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
      signal.  */
   if (!target_is_non_stop_p ())
     {
-      event_lp = iterate_over_lwps (filter, select_singlestep_lwp_callback);
+      event_lp = find_lwp (filter, select_singlestep_lwp_callback);
       if (event_lp != NULL)
 	{
 	  linux_nat_debug_printf ("Select single-step %s",
@@ -2901,11 +2915,11 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
       /* Pick one at random, out of those which have had events.  */
 
       /* First see how many events we have.  */
-      iterate_over_lwps (filter,
-			 [&] (struct lwp_info *info)
-			 {
-			   return count_events_callback (info, &num_events);
-			 });
+      for_each_lwp (filter,
+		    [&] (struct lwp_info *info)
+		    {
+		      count_events_callback (info, &num_events);
+		    });
       gdb_assert (num_events > 0);
 
       /* Now randomly pick a LWP out of those that have had
@@ -2918,13 +2932,12 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
 				num_events, random_selector);
 
       event_lp
-	= (iterate_over_lwps
-	   (filter,
-	    [&] (struct lwp_info *info)
+	= find_lwp (filter,
+	   [&] (struct lwp_info *info)
 	    {
 	      return select_event_lwp_callback (info,
 						&random_selector);
-	    }));
+	    });
     }
 
   if (event_lp != NULL)
@@ -2940,7 +2953,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
 
 /* Return non-zero if LP has been resumed.  */
 
-static int
+static bool
 resumed_callback (struct lwp_info *lp)
 {
   return lp->resumed;
@@ -3156,7 +3169,7 @@ linux_nat_filter_event (int lwpid, int status)
 		 will receive it - unless they're using CLONE_THREAD to
 		 share signals.  Since we only want to report it once, we
 		 mark it as ignored for all LWPs except this one.  */
-	      iterate_over_lwps (ptid_t (lp->ptid.pid ()), set_ignore_sigint);
+	      for_each_lwp (lp->ptid.pid (), set_ignore_sigint);
 	      lp->ignore_sigint = 0;
 	    }
 	  else
@@ -3335,7 +3348,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
   block_child_signals (&prev_mask);
 
   /* First check if there is a LWP with a wait status pending.  */
-  lp = iterate_over_lwps (ptid, status_callback);
+  lp = find_lwp (ptid, status_callback);
   if (lp != NULL)
     {
       linux_nat_debug_printf ("Using pending wait status %s for %s.",
@@ -3385,15 +3398,14 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 
       /* Now that we've pulled all events out of the kernel, resume
 	 LWPs that don't have an interesting event to report.  */
-      iterate_over_lwps (minus_one_ptid,
-			 [] (struct lwp_info *info)
-			 {
-			   return resume_stopped_resumed_lwps (info, minus_one_ptid);
-			 });
+      for_each_lwp ([] (struct lwp_info *info)
+		    {
+		      resume_stopped_resumed_lwps (info, minus_one_ptid);
+		    });
 
       /* ... and find an LWP with a status to report to the core, if
 	 any.  */
-      lp = iterate_over_lwps (ptid, status_callback);
+      lp = find_lwp (ptid, status_callback);
       if (lp != NULL)
 	break;
 
@@ -3403,7 +3415,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 
       /* If there are no resumed children left, bail.  We'd be stuck
 	 forever in the sigsuspend call below otherwise.  */
-      if (iterate_over_lwps (ptid, resumed_callback) == NULL)
+      if (find_lwp (ptid, resumed_callback) == NULL)
 	{
 	  linux_nat_debug_printf ("exit (no resumed LWP)");
 
@@ -3440,11 +3452,11 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
   if (!target_is_non_stop_p ())
     {
       /* Now stop all other LWP's ...  */
-      iterate_over_lwps (minus_one_ptid, stop_callback);
+      for_each_lwp (stop_callback);
 
       /* ... and wait until all of them have reported back that
 	 they're no longer running.  */
-      iterate_over_lwps (minus_one_ptid, stop_wait_callback);
+      for_each_lwp (stop_wait_callback);
     }
 
   /* If we're not waiting for a specific LWP, choose an event LWP from
@@ -3464,7 +3476,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
     {
       /* In all-stop, from the core's perspective, all LWPs are now
 	 stopped until a new resume action is sent over.  */
-      iterate_over_lwps (minus_one_ptid, resume_clear_callback);
+      for_each_lwp (resume_clear_callback);
     }
   else
     {
@@ -3511,7 +3523,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 /* Resume LWPs that are currently stopped without any pending status
    to report, but are resumed from the core's perspective.  */
 
-static int
+static void
 resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
 {
   inferior *inf = lwp_inferior (lp);
@@ -3570,8 +3582,6 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
 	    throw;
 	}
     }
-
-  return 0;
 }
 
 ptid_t
@@ -3597,11 +3607,10 @@ linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
      meanwhile the event became uninteresting.  Don't bother resuming
      LWPs we're not going to wait for if they'd stop immediately.  */
   if (target_is_non_stop_p ())
-    iterate_over_lwps (minus_one_ptid,
-		       [=] (struct lwp_info *info)
-		       {
-			 return resume_stopped_resumed_lwps (info, ptid);
-		       });
+    for_each_lwp ([=] (struct lwp_info *info)
+		  {
+		    resume_stopped_resumed_lwps (info, ptid);
+		  });
 
   event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options);
 
@@ -3680,27 +3689,25 @@ kill_wait_one_lwp (pid_t pid)
   gdb_assert (res == -1 && errno == ECHILD);
 }
 
-/* Callback for iterate_over_lwps.  */
+/* Callback for for_each_lwp.  */
 
-static int
+static void
 kill_callback (struct lwp_info *lp)
 {
   kill_one_lwp (lp->ptid.lwp ());
-  return 0;
 }
 
-/* Callback for iterate_over_lwps.  */
+/* Callback for for_each_lwp.  */
 
-static int
+static void
 kill_wait_callback (struct lwp_info *lp)
 {
   kill_wait_one_lwp (lp->ptid.lwp ());
-  return 0;
 }
 
 /* Kill the fork/clone child of LP if it has an unfollowed child.  */
 
-static int
+static void
 kill_unfollowed_child_callback (lwp_info *lp)
 {
   std::optional<target_waitstatus> ws = get_pending_child_status (lp);
@@ -3718,19 +3725,17 @@ kill_unfollowed_child_callback (lwp_info *lp)
       if (ws->kind () != TARGET_WAITKIND_THREAD_CLONED)
 	linux_target->low_forget_process (child_pid);
     }
-
-  return 0;
 }
 
 void
 linux_nat_target::kill ()
 {
-  ptid_t pid_ptid (inferior_ptid.pid ());
+  int pid = inferior_ptid.pid ();
 
   /* If we're stopped while forking/cloning and we haven't followed
      yet, kill the child task.  We need to do this first because the
      parent will be sleeping if this is a vfork.  */
-  iterate_over_lwps (pid_ptid, kill_unfollowed_child_callback);
+  for_each_lwp (pid, kill_unfollowed_child_callback);
 
   if (forks_exist_p (current_inferior ()))
     linux_fork_killall (current_inferior ());
@@ -3738,16 +3743,16 @@ linux_nat_target::kill ()
     {
       /* Stop all threads before killing them, since ptrace requires
 	 that the thread is stopped to successfully PTRACE_KILL.  */
-      iterate_over_lwps (pid_ptid, stop_callback);
+      for_each_lwp (pid, stop_callback);
       /* ... and wait until all of them have reported back that
 	 they're no longer running.  */
-      iterate_over_lwps (pid_ptid, stop_wait_callback);
+      for_each_lwp (pid, stop_wait_callback);
 
       /* Kill all LWP's ...  */
-      iterate_over_lwps (pid_ptid, kill_callback);
+      for_each_lwp (pid, kill_callback);
 
       /* ... and wait until we've flushed all events.  */
-      iterate_over_lwps (pid_ptid, kill_wait_callback);
+      for_each_lwp (pid, kill_wait_callback);
     }
 
   target_mourn_inferior (inferior_ptid);
@@ -4486,7 +4491,7 @@ linux_nat_target::async (bool enable)
 /* Stop an LWP, and push a GDB_SIGNAL_0 stop status if no other
    event came out.  */
 
-static int
+static void
 linux_nat_stop_lwp (struct lwp_info *lwp)
 {
   if (!lwp->stopped)
@@ -4499,7 +4504,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
 	{
 	  linux_nat_debug_printf ("already stopping LWP %ld at GDB's request",
 				  lwp->ptid.lwp ());
-	  return 0;
+	  return;
 	}
 
       stop_callback (lwp);
@@ -4519,14 +4524,13 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
 				    lwp->ptid.to_string ().c_str ());
 	}
     }
-  return 0;
 }
 
 void
 linux_nat_target::stop (ptid_t ptid)
 {
   LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT;
-  iterate_over_lwps (ptid, linux_nat_stop_lwp);
+  for_each_lwp (ptid, linux_nat_stop_lwp);
 }
 
 /* Return the cached value of the processor core for thread PTID.  */
diff --git a/gdb/nat/aarch64-linux-hw-point.c b/gdb/nat/aarch64-linux-hw-point.c
index 1e11d28e9066..b4d74ab8dc2b 100644
--- a/gdb/nat/aarch64-linux-hw-point.c
+++ b/gdb/nat/aarch64-linux-hw-point.c
@@ -43,7 +43,7 @@ bool kernel_supports_any_contiguous_range = true;
    N.B.  The actual updating of hardware debug registers is not
    carried out until the moment the thread is resumed.  */
 
-static int
+static void
 debug_reg_change_callback (struct lwp_info *lwp, int is_watchpoint,
 			   unsigned int idx)
 {
@@ -92,8 +92,6 @@ debug_reg_change_callback (struct lwp_info *lwp, int is_watchpoint,
 		    phex (info->dr_changed_bp, 8),
 		    phex (info->dr_changed_wp, 8));
     }
-
-  return 0;
 }
 
 /* Notify each thread that their IDXth breakpoint/watchpoint register
@@ -105,14 +103,11 @@ void
 aarch64_notify_debug_reg_change (ptid_t ptid,
 				 int is_watchpoint, unsigned int idx)
 {
-  ptid_t pid_ptid = ptid_t (ptid.pid ());
-
-  iterate_over_lwps (pid_ptid, [=] (struct lwp_info *info)
-			       {
-				 return debug_reg_change_callback (info,
-								   is_watchpoint,
-								   idx);
-			       });
+  for_each_lwp (ptid.pid (), [=] (struct lwp_info *info)
+			     {
+			       debug_reg_change_callback (info, is_watchpoint,
+							  idx);
+			     });
 }
 
 /* Reconfigure STATE to be compatible with Linux kernels with the PR
diff --git a/gdb/nat/linux-nat.h b/gdb/nat/linux-nat.h
index 42c0467191fe..4414749b93de 100644
--- a/gdb/nat/linux-nat.h
+++ b/gdb/nat/linux-nat.h
@@ -46,17 +46,15 @@ extern tribool have_ptrace_getregset;
 
 extern ptid_t current_lwp_ptid (void);
 
-/* Function type for the CALLBACK argument of iterate_over_lwps.  */
-using iterate_over_lwps_ftype = gdb::function_view<int (lwp_info *lwp)>;
+/* Function type for the CALLBACK argument of for_each_lwp.  */
 
-/* Iterate over all LWPs.  Calls CALLBACK with its second argument set
-   to DATA for every LWP in the list.  If CALLBACK returns nonzero for
-   a particular LWP, return a pointer to the structure describing that
-   LWP immediately.  Otherwise return NULL.  This function must be
-   provided by the client.  */
+using for_each_lwp_ftype = gdb::function_view<void (lwp_info *lwp)>;
 
-extern lwp_info *iterate_over_lwps (ptid_t filter,
-				    iterate_over_lwps_ftype callback);
+/* Iterate over all LWPs, calling CALLBACK for every LWP.
+
+   Only consider the LWPs with that pid.  */
+
+extern void for_each_lwp (int pid, for_each_lwp_ftype callback);
 
 /* Return the ptid of LWP.  */
 
diff --git a/gdb/nat/loongarch-linux-hw-point.c b/gdb/nat/loongarch-linux-hw-point.c
index 68eee8fb7754..be867e758edf 100644
--- a/gdb/nat/loongarch-linux-hw-point.c
+++ b/gdb/nat/loongarch-linux-hw-point.c
@@ -44,7 +44,7 @@
    N.B.  The actual updating of hardware debug registers is not
    carried out until the moment the thread is resumed.  */
 
-static int
+static void
 loongarch_dr_change_callback (struct lwp_info *lwp, int is_watchpoint,
 			      unsigned int idx)
 {
@@ -93,8 +93,6 @@ loongarch_dr_change_callback (struct lwp_info *lwp, int is_watchpoint,
 		    phex (info->dr_changed_bp, 8),
 		    phex (info->dr_changed_wp, 8));
     }
-
-  return 0;
 }
 
 /* Notify each thread that their IDXth breakpoint/watchpoint register
@@ -106,14 +104,12 @@ void
 loongarch_notify_debug_reg_change (ptid_t ptid,
 				 int is_watchpoint, unsigned int idx)
 {
-  ptid_t pid_ptid = ptid_t (ptid.pid ());
-
-  iterate_over_lwps (pid_ptid, [=] (struct lwp_info *info)
-			       {
-				 return loongarch_dr_change_callback (info,
-								      is_watchpoint,
-								      idx);
-			       });
+  for_each_lwp (ptid.pid (), [=] (struct lwp_info *info)
+			     {
+			       loongarch_dr_change_callback (info,
+							     is_watchpoint,
+							     idx);
+			     });
 }
 
 /* Call ptrace to set the thread TID's hardware breakpoint/watchpoint
diff --git a/gdb/nat/x86-linux-dregs.c b/gdb/nat/x86-linux-dregs.c
index abdfa50edb93..ea8de511d5c4 100644
--- a/gdb/nat/x86-linux-dregs.c
+++ b/gdb/nat/x86-linux-dregs.c
@@ -69,21 +69,18 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
     perror_with_name (_("Couldn't write debug register"));
 }
 
-/* Callback for iterate_over_lwps.  Mark that our local mirror of
+/* Callback for for_each_lwp.  Mark that our local mirror of
    LWP's debug registers has been changed, and cause LWP to stop if
    it isn't already.  Values are written from our local mirror to
    the actual debug registers immediately prior to LWP resuming.  */
 
-static int
+static void
 update_debug_registers_callback (struct lwp_info *lwp)
 {
   lwp_set_debug_registers_changed (lwp, 1);
 
   if (!lwp_is_stopped (lwp))
     linux_stop_lwp (lwp);
-
-  /* Continue the iteration.  */
-  return 0;
 }
 
 /* See nat/x86-linux-dregs.h.  */
@@ -101,11 +98,9 @@ x86_linux_dr_get_addr (int regnum)
 void
 x86_linux_dr_set_addr (int regnum, CORE_ADDR addr)
 {
-  ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
-
   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
 
-  iterate_over_lwps (pid_ptid, update_debug_registers_callback);
+  for_each_lwp (current_lwp_ptid ().pid (), update_debug_registers_callback);
 }
 
 /* See nat/x86-linux-dregs.h.  */
@@ -121,9 +116,7 @@ x86_linux_dr_get_control (void)
 void
 x86_linux_dr_set_control (unsigned long control)
 {
-  ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
-
-  iterate_over_lwps (pid_ptid, update_debug_registers_callback);
+  for_each_lwp (current_lwp_ptid ().pid (), update_debug_registers_callback);
 }
 
 /* See nat/x86-linux-dregs.h.  */
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index b077a1d0cf42..102a51c85090 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -3103,18 +3103,18 @@ ppc_linux_nat_target::mark_debug_registers_changed (pid_t pid)
   /* We do this in two passes to make sure all threads are marked even if
      we get an exception when stopping one of them.  */
 
-  iterate_over_lwps (ptid_t (pid),
-		     [this] (struct lwp_info *lp) -> int {
-		       this->mark_thread_stale (lp);
-		       return 0;
-		     });
+  for_each_lwp (pid,
+		[this] (struct lwp_info *lp)
+		{
+		  this->mark_thread_stale (lp);
+		});
 
-  iterate_over_lwps (ptid_t (pid),
-		     [] (struct lwp_info *lp) -> int {
-		       if (!lwp_is_stopped (lp))
-			 linux_stop_lwp (lp);
-		       return 0;
-		     });
+  for_each_lwp (pid,
+		[] (struct lwp_info *lp)
+		{
+		  if (!lwp_is_stopped (lp))
+		    linux_stop_lwp (lp);
+		});
 }
 
 /* Register a hardware breakpoint or watchpoint BP for the pid PID, then
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 5bee2b1e1128..6ef524a310cb 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -822,25 +822,21 @@ s390_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
 
 /* Iterator callback for s390_refresh_per_info.  */
 
-static int
+static void
 s390_refresh_per_info_cb (struct lwp_info *lp)
 {
   s390_mark_per_info_changed (lp);
 
   if (!lwp_is_stopped (lp))
     linux_stop_lwp (lp);
-  return 0;
 }
 
 /* Make sure that threads are stopped and mark PER info as changed.  */
 
-static int
+static void
 s390_refresh_per_info (void)
 {
-  ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
-
-  iterate_over_lwps (pid_ptid, s390_refresh_per_info_cb);
-  return 0;
+  for_each_lwp (current_lwp_ptid ().pid (), s390_refresh_per_info_cb);
 }
 
 int
@@ -856,7 +852,8 @@ s390_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
   area.hi_addr = addr + len - 1;
   state->watch_areas.push_back (area);
 
-  return s390_refresh_per_info ();
+  s390_refresh_per_info ();
+  return 0;
 }
 
 int
@@ -874,7 +871,8 @@ s390_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
       if (area.lo_addr == addr && area.hi_addr == addr + len - 1)
 	{
 	  unordered_remove (state->watch_areas, ix);
-	  return s390_refresh_per_info ();
+	  s390_refresh_per_info ();
+	  return 0;
 	}
     }
 
@@ -908,7 +906,8 @@ s390_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
   state = s390_get_debug_reg_state (inferior_ptid.pid ());
   state->break_areas.push_back (area);
 
-  return s390_refresh_per_info ();
+  s390_refresh_per_info ();
+  return 0;
 }
 
 /* Implement the "remove_hw_breakpoint" target_ops method.  */
@@ -927,7 +926,8 @@ s390_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
       if (area.lo_addr == bp_tgt->placed_address)
 	{
 	  unordered_remove (state->break_areas, ix);
-	  return s390_refresh_per_info ();
+	  s390_refresh_per_info ();
+	  return 0;
 	}
     }
 
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 022e8415fda8..b4ec524dbbff 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -1768,20 +1768,18 @@ num_lwps (process_info *process)
 
 /* See nat/linux-nat.h.  */
 
-lwp_info *
-iterate_over_lwps (ptid_t filter, iterate_over_lwps_ftype callback)
+void
+for_each_lwp (int pid, for_each_lwp_ftype callback)
 {
-  thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
+  process_info *process = find_process_pid (pid);
+
+  if (process == nullptr)
+    return;
+
+  process->for_each_thread ([&] (thread_info *thread)
     {
-      lwp_info *lwp = get_thread_lwp (thr_arg);
-
-      return callback (lwp);
+      callback (get_thread_lwp (thread));
     });
-
-  if (thread == NULL)
-    return NULL;
-
-  return get_thread_lwp (thread);
 }
 
 bool
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 06/11] gdb: split iterate_over_threads in for_each_thread and find_thread
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (4 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 05/11] gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 07/11] gdb: split iterate_over_minimal_symbols in for_each_minimal_symbol and find_minimal_symbol Simon Marchi
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Same rationale as the previous patch, I think the code would be clearer
and simpler with separate "for each" and "find" functions rather than
one that does both jobs.

No need for the callbacks of the "for each" function to return anything,
as none of them needs to interrupt the iteration.

Change-Id: I4b7bcc5e9a319369d75a22b11114e943951e546a
---
 gdb/aix-thread.c |  2 +-
 gdb/breakpoint.c |  3 +--
 gdb/fbsd-tdep.c  |  2 +-
 gdb/gdbthread.h  | 21 +++++++++++++++++----
 gdb/infcmd.c     |  9 ++++-----
 gdb/infrun.c     |  4 ++--
 gdb/mi/mi-main.c | 15 ++++++---------
 gdb/procfs.c     |  6 +++---
 gdb/sol-thread.c |  4 ++--
 gdb/thread.c     | 27 ++++++++++++---------------
 10 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 5469ddca4f79..675d8d5070cd 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -894,7 +894,7 @@ pd_update (pid_t pid)
 
   tid = get_signaled_thread (pid);
   if (tid != 0)
-    thread = iterate_over_threads ([&] (struct thread_info *thread)
+    thread = find_thread ([&] (thread_info *thread)
       {
 	return thread->ptid.lwp () == tid;
       });
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 99447b532306..101dc57ee6bb 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -12694,10 +12694,9 @@ delete_breakpoint (struct breakpoint *bpt)
      event-top.c won't do anything, and temporary breakpoints with
      commands won't work.  */
 
-  iterate_over_threads ([&] (struct thread_info *th)
+  for_each_thread ([&] (struct thread_info *th)
     {
       bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
-      return false;
     });
 
   /* Now that breakpoint is removed from breakpoint list, update the
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 4bbe0c120e6a..419f935ea72f 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -705,7 +705,7 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
     signalled_thr = curr_thr;
   else
     {
-      signalled_thr = iterate_over_threads (find_signalled_thread);
+      signalled_thr = find_thread (find_signalled_thread);
       if (signalled_thr == NULL)
 	signalled_thr = curr_thr;
     }
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index c56c4ce40366..729dcf5ab068 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -791,10 +791,23 @@ extern struct thread_info *any_live_thread_of_inferior (inferior *inf);
 void thread_change_ptid (process_stratum_target *targ,
 			 ptid_t old_ptid, ptid_t new_ptid);
 
-/* Iterator function to call a user-provided callback function
-   once for each known thread.  */
-typedef gdb::function_view<bool (struct thread_info *)> thread_callback_func;
-extern struct thread_info *iterate_over_threads (thread_callback_func);
+/* Callback function type for function for_each_thread.  */
+
+using for_each_thread_callback_ftype
+  = gdb::function_view<void (thread_info *)>;
+
+/* Call CALLBACK once for each known thread.  */
+
+extern void for_each_thread (for_each_thread_callback_ftype callback);
+
+/* Callback function type for function find_thread.  */
+
+using find_thread_callback_ftype = gdb::function_view<bool (thread_info *)>;
+
+/* Return the first thread for which CALLBACK returns true, or nullptr if
+   there is no such thread.  */
+
+extern struct thread_info *find_thread (find_thread_callback_ftype callback);
 
 /* Pull in the internals of the inferiors/threads ranges and
    iterators.  Must be done after struct thread_info is defined.  */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c6519b71abcb..4a907ea8ce86 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -685,7 +685,7 @@ starti_command (const char *args, int from_tty)
   run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN);
 }
 
-static bool
+static void
 proceed_thread_callback (struct thread_info *thread)
 {
   /* We go through all threads individually instead of compressing
@@ -698,15 +698,14 @@ proceed_thread_callback (struct thread_info *thread)
      way to tell the target `hold this thread stopped until I say
      otherwise', then we can optimize this.  */
   if (thread->state () != THREAD_STOPPED)
-    return false;
+    return;
 
   if (!thread->inf->has_execution ())
-    return false;
+    return;
 
   switch_to_thread (thread);
   clear_proceed_status (0);
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
-  return false;
 }
 
 static void
@@ -763,7 +762,7 @@ continue_1 (int all_threads)
       scoped_disable_commit_resumed disable_commit_resumed
 	("continue all threads in non-stop");
 
-      iterate_over_threads (proceed_thread_callback);
+      for_each_thread (proceed_thread_callback);
 
       if (current_ui->prompt_state == PROMPT_BLOCKED)
 	{
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 19836c4d89e7..b295956f8ea5 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -6695,7 +6695,7 @@ restart_threads (struct thread_info *event_thread, inferior *inf)
     }
 }
 
-/* Callback for iterate_over_threads.  Find a resumed thread that has
+/* Callback for find_thread.  Find a resumed thread that has
    a pending waitstatus.  */
 
 static bool
@@ -6777,7 +6777,7 @@ finish_step_over (struct execution_control_state *ecs)
       if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
        return 0;
 
-      pending = iterate_over_threads (resumed_thread_with_pending_status);
+      pending = find_thread (resumed_thread_with_pending_status);
       if (pending != nullptr)
 	{
 	  struct thread_info *tp = ecs->event_thread;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index bf08fe822b32..7e448947a2fe 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -278,10 +278,9 @@ exec_continue (const char *const *argv, int argc)
 	      pid = inf->pid;
 	    }
 
-	  iterate_over_threads ([&] (struct thread_info *thread)
+	  for_each_thread ([&] (struct thread_info *thread)
 	    {
 	      proceed_thread (thread, pid);
-	      return false;
 	    });
 	  disable_commit_resumed.reset_and_commit ();
 	}
@@ -364,16 +363,15 @@ mi_cmd_exec_interrupt (const char *command, const char *const *argv, int argc)
       scoped_disable_commit_resumed disable_commit_resumed
 	("interrupting all threads of thread group");
 
-      iterate_over_threads ([&] (struct thread_info *thread)
+      for_each_thread ([&] (struct thread_info *thread)
 	{
 	  if (thread->state () != THREAD_RUNNING)
-	    return false;
+	    return;
 
 	  if (thread->ptid.pid () != inf->pid)
-	    return false;
+	    return;
 
 	  target_stop (thread->ptid);
-	  return false;
 	});
     }
   else
@@ -505,7 +503,7 @@ mi_cmd_target_detach (const char *command, const char *const *argv, int argc)
 
       /* Pick any thread in the desired process.  Current
 	 target_detach detaches from the parent of inferior_ptid.  */
-      tp = iterate_over_threads ([&] (struct thread_info *ti)
+      tp = find_thread ([&] (struct thread_info *ti)
 	{
 	  return ti->ptid.pid () == pid && ti->state () != THREAD_EXITED;
 	});
@@ -604,7 +602,7 @@ print_one_inferior (struct inferior *inferior, bool recurse,
 
       if (inferior->pid != 0)
 	{
-	  iterate_over_threads ([&] (struct thread_info *ti)
+	  for_each_thread ([&] (struct thread_info *ti)
 	    {
 	      if (ti->ptid.pid () == inferior->pid)
 		{
@@ -613,7 +611,6 @@ print_one_inferior (struct inferior *inferior, bool recurse,
 		  if (core != -1)
 		    cores.insert (core);
 		}
-	      return false;
 	    });
 	}
 
diff --git a/gdb/procfs.c b/gdb/procfs.c
index cea9f823bbca..a208393da073 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -2395,8 +2395,8 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
    descriptors for the parent process, but discard any file
    descriptors we may have accumulated for the threads.
 
-   As this function is called by iterate_over_threads, it always
-   returns zero (so that iterate_over_threads will keep
+   As this function is called by proc_iterate_over_threads, it always
+   returns zero (so that proc_iterate_over_threads will keep
    iterating).  */
 
 static int
@@ -3541,7 +3541,7 @@ find_signalled_thread (struct thread_info *info)
 static enum gdb_signal
 find_stop_signal (void)
 {
-  struct thread_info *info = iterate_over_threads (find_signalled_thread);
+  struct thread_info *info = find_thread (find_signalled_thread);
 
   if (info)
     return info->stop_signal ();
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index c765a4205a04..b5a68b9e46c1 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -1119,14 +1119,14 @@ sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
        };
 
   struct thread_info *thread_info
-    = iterate_over_threads (thread_db_find_thread_from_tid);
+    = find_thread (thread_db_find_thread_from_tid);
 
   if (thread_info == NULL)
     {
       /* The list of threads is probably not up to date.  Find any
 	 thread that is missing from the list, and try again.  */
       update_thread_list ();
-      thread_info = iterate_over_threads (thread_db_find_thread_from_tid);
+      thread_info = find_thread (thread_db_find_thread_from_tid);
     }
 
   gdb_assert (thread_info != NULL);
diff --git a/gdb/thread.c b/gdb/thread.c
index a6ae2a751397..b47479b12e8e 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -597,28 +597,25 @@ find_thread_by_handle (gdb::array_view<const gdb_byte> handle,
 					      inf);
 }
 
-/*
- * Thread iterator function.
- *
- * Calls a callback function once for each thread, so long as
- * the callback function returns false.  If the callback function
- * returns true, the iteration will end and the current thread
- * will be returned.  This can be useful for implementing a
- * search for a thread with arbitrary attributes, or for applying
- * some operation to every thread.
- *
- * FIXME: some of the existing functionality, such as
- * "Thread apply all", might be rewritten using this functionality.
- */
+/* See gdbthread.h.  */
+
+void
+for_each_thread (for_each_thread_callback_ftype callback)
+{
+  for (thread_info &tp : all_threads_safe ())
+    callback (&tp);
+}
+
+/* See gdbthread.h.  */
 
 struct thread_info *
-iterate_over_threads (gdb::function_view<bool (struct thread_info *)> callback)
+find_thread (find_thread_callback_ftype callback)
 {
   for (thread_info &tp : all_threads_safe ())
     if (callback (&tp))
       return &tp;
 
-  return NULL;
+  return nullptr;
 }
 
 /* See gdbthread.h.  */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 07/11] gdb: split iterate_over_minimal_symbols in for_each_minimal_symbol and find_minimal_symbol
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (5 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 06/11] gdb: split iterate_over_threads in for_each_thread and find_thread Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 08/11] gdb: split iterate_over_symtabs in for_each_symtab and find_symtab Simon Marchi
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Based on the same rationale as the previous patches, split
iterate_over_minimal_symbols in two.

Implement for_each_minimal_symbol using find_minimal_symbol, since that
one is really not trivial.

Change-Id: Ie02e67278359454f7aa583200ec68d2f429f7ebe
---
 gdb/linespec.c | 35 ++++++++++++++++-------------------
 gdb/minsyms.c  | 25 ++++++++++++++++++++-----
 gdb/minsyms.h  | 37 +++++++++++++++++++++++++++++--------
 gdb/symtab.c   | 18 +++++++++---------
 4 files changed, 74 insertions(+), 41 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 4ea6d597a093..4170d4ecf2c4 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -4150,33 +4150,30 @@ search_minsyms_for_name (struct collect_info *info,
 	  set_current_program_space (pspace);
 
 	  for (objfile &objfile : pspace->objfiles ())
-	    {
-	      iterate_over_minimal_symbols (&objfile, name,
-					    [&] (struct minimal_symbol *msym)
-					    {
-					      add_minsym (msym, &objfile, nullptr,
-							  info->state->list_mode,
-							  &minsyms);
-					      return false;
-					    });
-	    }
+	    for_each_minimal_symbol (&objfile, name,
+				     [&] (minimal_symbol *msym)
+				       {
+					 add_minsym (msym, &objfile, nullptr,
+						     info->state->list_mode,
+						     &minsyms);
+				       });
 	}
     }
   else
     {
-      program_space *pspace = symtab->compunit ()->objfile ()->pspace ();
+      objfile &objfile = *symtab->compunit ()->objfile ();
+      program_space *pspace = objfile.pspace ();
 
       if (search_pspace == NULL || pspace == search_pspace)
 	{
 	  set_current_program_space (pspace);
-	  iterate_over_minimal_symbols
-	    (symtab->compunit ()->objfile (), name,
-	     [&] (struct minimal_symbol *msym)
-	       {
-		 add_minsym (msym, symtab->compunit ()->objfile (), symtab,
-			     info->state->list_mode, &minsyms);
-		 return false;
-	       });
+	  for_each_minimal_symbol (&objfile, name,
+				   [&] (minimal_symbol *msym)
+				     {
+				       add_minsym (msym, &objfile, symtab,
+						   info->state->list_mode,
+						   &minsyms);
+				     });
 	}
     }
 
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 0d6ea53aecf6..4eafc7890478 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -496,9 +496,22 @@ linkage_name_str (const lookup_name_info &lookup_name)
 /* See minsyms.h.  */
 
 void
-iterate_over_minimal_symbols
-    (struct objfile *objf, const lookup_name_info &lookup_name,
-     gdb::function_view<bool (struct minimal_symbol *)> callback)
+for_each_minimal_symbol (struct objfile *objf, const lookup_name_info &name,
+			 for_each_minimal_symbol_callback_ftype callback)
+{
+  find_minimal_symbol (objf, name,
+		       [&] (struct minimal_symbol *msym)
+			 {
+			   callback (msym);
+			   return false;
+			 });
+}
+
+/* See minsyms.h.  */
+
+minimal_symbol *
+find_minimal_symbol (struct objfile *objf, const lookup_name_info &lookup_name,
+		     find_minimal_symbol_callback_ftype callback)
 {
   /* The first pass is over the ordinary hash table.  */
     {
@@ -515,7 +528,7 @@ iterate_over_minimal_symbols
 	{
 	  if (mangled_cmp (iter->linkage_name (), name) == 0)
 	    if (callback (iter))
-	      return;
+	      return iter;
 	}
     }
 
@@ -539,8 +552,10 @@ iterate_over_minimal_symbols
 	   iter = iter->demangled_hash_next)
 	if (name_match (iter->search_name (), lookup_name, NULL))
 	  if (callback (iter))
-	    return;
+	    return iter;
     }
+
+  return nullptr;
 }
 
 /* See minsyms.h.  */
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index 8f38cc7137fc..c44d5b20aec8 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -20,6 +20,7 @@
 #ifndef GDB_MINSYMS_H
 #define GDB_MINSYMS_H
 
+#include "gdbsupport/function-view.h"
 #include <deque>
 
 struct program_space;
@@ -279,16 +280,36 @@ bound_minimal_symbol lookup_minimal_symbol_by_pc_section
 
 bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR);
 
-/* Iterate over all the minimal symbols in the objfile OBJF which
-   match NAME.  Both the ordinary and demangled names of each symbol
-   are considered.  The caller is responsible for canonicalizing NAME,
-   should that need to be done.
+/* Callback type for function for_each_minimal_symbol.  */
 
-   For each matching symbol, CALLBACK is called with the symbol.  */
+using for_each_minimal_symbol_callback_ftype
+  = gdb::function_view<void (struct minimal_symbol *)>;
 
-void iterate_over_minimal_symbols
-    (struct objfile *objf, const lookup_name_info &name,
-     gdb::function_view<bool (struct minimal_symbol *)> callback);
+/* Call CALLBACK for all minimal symbols in objfile OBJF which match NAME.
+
+   Both the ordinary and demangled names of each symbol are considered.  The
+   caller is responsible for canonicalizing NAME, should that need to be
+   done.  */
+
+void for_each_minimal_symbol (struct objfile *objf,
+			      const lookup_name_info &name,
+			      for_each_minimal_symbol_callback_ftype callback);
+
+/* Callback type for function find_minimal_symbol.  */
+
+using find_minimal_symbol_callback_ftype
+  = gdb::function_view<bool (struct minimal_symbol *)>;
+
+/* Find the first minimal symbol for objfile OBJF which matches NAME and for
+   which CALLBACK returns true.
+
+   Both the ordinary and demangled names of each symbol are considered.  The
+   caller is responsible for canonicalizing NAME, should that need to be
+   done.  */
+
+minimal_symbol *find_minimal_symbol
+  (struct objfile *objf, const lookup_name_info &name,
+   find_minimal_symbol_callback_ftype callback);
 
 /* Compute the upper bound of MINSYM.  The upper bound is the last
    address thought to be part of the symbol.  If the symbol has a
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d22dd81a246a..5a39081dfc54 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -5782,32 +5782,32 @@ find_gnu_ifunc (const symbol *sym)
   struct objfile *objfile = sym->objfile ();
 
   CORE_ADDR address = sym->value_block ()->entry_pc ();
-  minimal_symbol *ifunc = NULL;
-
-  iterate_over_minimal_symbols (objfile, lookup_name,
-				[&] (minimal_symbol *minsym)
+  minimal_symbol *ifunc
+    = find_minimal_symbol (objfile, lookup_name,
+			   [&] (minimal_symbol *minsym)
     {
       if (minsym->type () == mst_text_gnu_ifunc
 	  || minsym->type () == mst_data_gnu_ifunc)
 	{
 	  CORE_ADDR msym_addr = minsym->value_address (objfile);
+
 	  if (minsym->type () == mst_data_gnu_ifunc)
 	    {
 	      struct gdbarch *gdbarch = objfile->arch ();
 	      msym_addr = gdbarch_convert_from_func_ptr_addr
 		(gdbarch, msym_addr, current_inferior ()->top_target ());
 	    }
+
 	  if (msym_addr == address)
-	    {
-	      ifunc = minsym;
-	      return true;
-	    }
+	    return true;
 	}
+
       return false;
     });
 
-  if (ifunc != NULL)
+  if (ifunc != nullptr)
     return {ifunc, objfile};
+
   return {};
 }
 
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 08/11] gdb: split iterate_over_symtabs in for_each_symtab and find_symtab
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (6 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 07/11] gdb: split iterate_over_minimal_symbols in for_each_minimal_symbol and find_minimal_symbol Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 09/11] gdb: change objfile::map_symtabs_matching_filename to find_symtab_matching_filename Simon Marchi
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Same rationale as the previous patches.

For the moment, find_symtab is only needed internally in symtab.c, so
keep it static there.  Note that the interaction with
objfile.map_symtabs_matching_filename gets cleaner in a subsequent
patch.

for_each_symtab is implemented using find_symtab, because the iteration
behavior is not completely trivial.

find_symtab_callback_ftype is in the header file, because it is used
from another source file in the next patch.

Change-Id: I6ab8342151eb735327fc2e7935e7a65cede5e1dd
---
 gdb/linespec.c |  5 ++---
 gdb/symtab.c   | 55 ++++++++++++++++++++++++++++++++++----------------
 gdb/symtab.h   | 19 +++++++++--------
 3 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 4170d4ecf2c4..0afe0c619a13 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3613,7 +3613,6 @@ collect_symtabs_from_filename (const char *file,
     {
       if (symtab_table.insert (symtab).second)
 	symtabs.push_back (symtab);
-      return iteration_status::keep_going;
     };
 
   /* Find that file's data.  */
@@ -3624,11 +3623,11 @@ collect_symtabs_from_filename (const char *file,
 	  if (pspace->executing_startup)
 	    continue;
 
-	  iterate_over_symtabs (pspace, file, collector);
+	  for_each_symtab (pspace, file, collector);
 	}
     }
   else
-    iterate_over_symtabs (search_pspace, file, collector);
+    for_each_symtab (search_pspace, file, collector);
 
   /* It is tempting to use the unordered_dense 'extract' method here,
      and remove the separate vector -- but it's unclear if ordering
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 5a39081dfc54..6a5c8c7058e4 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -629,12 +629,16 @@ compare_filenames_for_search (const char *filename, const char *search_name)
 	      && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len]));
 }
 
-/* See symtab.h.  */
+/* Return the first symtab in PSPACE matching NAME.
 
-void
-iterate_over_symtabs (program_space *pspace, const char *name,
-		      gdb::function_view<iteration_status (symtab *)> callback)
+   See documentation for for_each_symtab for how exactly NAME is matched.  */
+
+static symtab *
+find_symtab (program_space *pspace, const char *name,
+	     find_symtab_callback_ftype callback)
 {
+  struct symtab *result = NULL;
+
   gdb::unique_xmalloc_ptr<char> real_path;
 
   /* Here we are interested in canonicalizing an absolute path, not
@@ -645,11 +649,37 @@ iterate_over_symtabs (program_space *pspace, const char *name,
       gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
     }
 
+  auto map_callback = [&] (symtab *symtab)
+    {
+      if (callback (symtab))
+	{
+	  result = symtab;
+	  return iteration_status::stop;
+	}
+
+      return iteration_status::keep_going;
+    };
+
   for (objfile &objfile : pspace->objfiles ())
     if (objfile.map_symtabs_matching_filename (name, real_path.get (),
-					       callback)
+					       map_callback)
 	== iteration_status::stop)
-      return;
+      return result;
+
+  return nullptr;
+}
+
+/* See symtab.h.  */
+
+void
+for_each_symtab (program_space *pspace, const char *name,
+		 for_each_symtab_callback_ftype callback)
+{
+  find_symtab (pspace, name, [&] (symtab *symtab)
+	       {
+		 callback (symtab);
+		 return false;
+	       });
 }
 
 /* See symtab.h.  */
@@ -657,15 +687,7 @@ iterate_over_symtabs (program_space *pspace, const char *name,
 symtab *
 lookup_symtab (program_space *pspace, const char *name)
 {
-  struct symtab *result = NULL;
-
-  iterate_over_symtabs (pspace, name, [&] (symtab *symtab)
-    {
-      result = symtab;
-      return iteration_status::stop;
-    });
-
-  return result;
+  return find_symtab (pspace, name, [&] (symtab *symtab) { return true; });
 }
 
 \f
@@ -6140,12 +6162,11 @@ collect_file_symbol_completion_matches (completion_tracker &tracker,
 
   /* Go through symtabs for SRCFILE and check the externs and statics
      for symbols which match.  */
-  iterate_over_symtabs (current_program_space, srcfile, [&] (symtab *s)
+  for_each_symtab (current_program_space, srcfile, [&] (symtab *s)
     {
       add_symtab_completions (s->compunit (),
 			      tracker, mode, lookup_name,
 			      sym_text, word, TYPE_CODE_UNDEF);
-      return iteration_status::keep_going;
     });
 }
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 9e45f087adda..3936052706f1 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2789,16 +2789,19 @@ extern bool basenames_may_differ;
 bool compare_filenames_for_search (const char *filename,
 				   const char *search_name);
 
-/* Check in PSPACE for a symtab of a specific name; first in symtabs, then in
-   psymtabs.  *If* there is no '/' in the name, a match after a '/' in the
-   symtab filename will also work.
+using for_each_symtab_callback_ftype = std::function<void (symtab *)>;
 
-   Call CALLBACK with each symtab that is found.  If CALLBACK returns
-   true, the search stops.  */
+/* Check in PSPACE for a symtab of a specific name.  *If* there is no '/' in
+   the name, a match after a '/' in the symtab filename will also work.
 
-void iterate_over_symtabs
-  (program_space *pspace, const char *name,
-   gdb::function_view<iteration_status (symtab *)> callback);
+   Call CALLBACK with each symtab that is found.  */
+
+void for_each_symtab (program_space *pspace, const char *name,
+		      for_each_symtab_callback_ftype callback);
+
+/* Callback type for function find_symtab.  */
+
+using find_symtab_callback_ftype = std::function<bool (symtab *)>;
 
 std::vector<const linetable_entry *> find_linetable_entries_for_symtab_line
     (struct symtab *symtab, int line, const linetable_entry **best_entry);
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 09/11] gdb: change objfile::map_symtabs_matching_filename to find_symtab_matching_filename
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (7 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 08/11] gdb: split iterate_over_symtabs in for_each_symtab and find_symtab Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 10/11] gdb: make symbol_found_callback_ftype a function_view Simon Marchi
  2026-04-16 20:16 ` [PATCH 11/11] gdb: make iterate_over_symbols return void, rename to for_each_symbol Simon Marchi
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The only user of objfile::map_symtabs_matching_filename uses that method
to find the first matching symtab.  It would therefore be more natural
for that method to be a "find" method, returning the first symtab
matching the predicate.

Change map_symtabs_matching_filename to be
find_symtab_in_compunit_symtab, and the internal
iterate_over_one_compunit_symtab to be find_symtab_in_compunit_symtab.

This makes function find_symtab simpler.

Change-Id: Id14a95498fad243495d6eab18810d0c4ab8dbf90
---
 gdb/objfiles.h      | 16 +++-----
 gdb/symfile-debug.c | 89 +++++++++++++++++++++------------------------
 gdb/symtab.c        | 20 ++--------
 3 files changed, 52 insertions(+), 73 deletions(-)

diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 8ae54b37bb79..76d6130f5048 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -571,21 +571,17 @@ struct objfile : intrusive_list_node<objfile>
   /* See quick_symbol_functions.  */
   void forget_cached_source_info ();
 
-  /* Expand and iterate over each "partial" symbol table in OBJFILE
-     where the source file is named NAME.
+  /* Find the first symtab where the source file matches NAME and REAL_PATH,
+     and for which CALLBACK returns true.
 
      If NAME is not absolute, a match after a '/' in the symbol table's
      file name will also work, REAL_PATH is NULL then.  If NAME is
      absolute then REAL_PATH is non-NULL absolute file name as resolved
-     via gdb_realpath from NAME.
+     via gdb_realpath from NAME.  */
 
-     If a match is found, the "partial" symbol table is expanded.
-     Then, this calls iterate_over_some_symtabs (or equivalent) over
-     all newly-created symbol tables, passing CALLBACK to it.
-     The result of this call is returned.  */
-  iteration_status map_symtabs_matching_filename
-    (const char *name, const char *real_path,
-     gdb::function_view<iteration_status (symtab *)> callback);
+  symtab *find_symtab_matching_filename (const char *name,
+					 const char *real_path,
+					 find_symtab_callback_ftype callback);
 
   /* Check to see if the symbol is defined in a "partial" symbol table
      of this objfile.  BLOCK_INDEX should be either GLOBAL_BLOCK or
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 8e4892649508..d90f400f379c 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -159,29 +159,30 @@ objfile::forget_cached_source_info ()
     iter->forget_cached_source_info (this);
 }
 
-/* Check for a symtab of a specific name by searching some symtabs.
+/* Find the first symtab of CUST matching BASE_NAME, NAME and REAL_PATH, for
+   which CALLBACK returns true.
 
    If NAME is not absolute, then REAL_PATH is NULL
    If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME.
 
    The return value, NAME, REAL_PATH and CALLBACK are identical to the
-   `map_symtabs_matching_filename' method of quick_symbol_functions.
+   `find_symtab_matching_filename' method of quick_symbol_functions.
 
    CUST indicates which compunit symtab to search.  Each symtab within
    the specified compunit symtab is also searched.  */
 
-static iteration_status
-iterate_over_one_compunit_symtab
-  (const char *base_name, const char *name, const char *real_path,
-   compunit_symtab *cust,
-   gdb::function_view<iteration_status (symtab *)> callback)
+static symtab *
+find_symtab_in_compunit_symtab (const char *base_name, const char *name,
+				const char *real_path, compunit_symtab *cust,
+				find_symtab_callback_ftype callback)
 {
   for (symtab *s : cust->filetabs ())
     {
       if (compare_filenames_for_search (s->filename (), name))
 	{
-	  if (callback (s) == iteration_status::stop)
-	    return iteration_status::stop;
+	  if (callback (s))
+	    return s;
+
 	  continue;
 	}
 
@@ -193,8 +194,9 @@ iterate_over_one_compunit_symtab
 
       if (compare_filenames_for_search (symtab_to_fullname (s), name))
 	{
-	  if (callback (s) == iteration_status::stop)
-	    return iteration_status::stop;
+	  if (callback (s))
+	    return s;
+
 	  continue;
 	}
 
@@ -211,30 +213,32 @@ iterate_over_one_compunit_symtab
 	  fullname = fullname_real_path.get ();
 	  if (FILENAME_CMP (real_path, fullname) == 0)
 	    {
-	      if (callback (s) == iteration_status::stop)
-		return iteration_status::stop;
+	      if (callback (s))
+		return s;
+
 	      continue;
 	    }
 	}
     }
 
   for (compunit_symtab *iter : cust->includes)
-    if (iterate_over_one_compunit_symtab (base_name, name, real_path, iter,
-					  callback)
-	== iteration_status::stop)
-      return iteration_status::stop;
+    if (symtab *result = find_symtab_in_compunit_symtab (base_name, name,
+							 real_path, iter,
+							 callback);
+	result != nullptr)
+      return result;
 
-  return iteration_status::keep_going;
+  return nullptr;
 }
 
-iteration_status
-objfile::map_symtabs_matching_filename
-  (const char *name, const char *real_path,
-   gdb::function_view<iteration_status (symtab *)> callback)
+symtab *
+objfile::find_symtab_matching_filename (const char *name,
+					const char *real_path,
+					find_symtab_callback_ftype callback)
 {
   if (debug_symfile)
     gdb_printf (gdb_stdlog,
-		"qf->map_symtabs_matching_filename (%s, \"%s\", "
+		"qf->find_symtab_matching_filename (%s, \"%s\", "
 		"\"%s\", %s)\n",
 		objfile_debug_name (this), name,
 		real_path ? real_path : NULL,
@@ -254,6 +258,7 @@ objfile::map_symtabs_matching_filename
     return false;
   };
 
+  symtab *result = nullptr;
   auto compunit_callback = [&] (compunit_symtab *symtab)
   {
     /* Skip included compunits, as they are searched by
@@ -261,37 +266,27 @@ objfile::map_symtabs_matching_filename
     if (symtab->user != nullptr)
       return iteration_status::keep_going;
 
-    /* iterate_over_one_compunit_symtab returns true to stop,
-       convert to iteration_status.  */
-    if (iterate_over_one_compunit_symtab (name_basename, name, real_path,
-					  symtab, callback)
-	== iteration_status::stop)
+    result = find_symtab_in_compunit_symtab (name_basename, name, real_path,
+					     symtab, callback);
+    if (result == nullptr)
+      return iteration_status::keep_going;
+    else
       return iteration_status::stop;
-
-    return iteration_status::keep_going;
   };
 
-  iteration_status retval = iteration_status::keep_going;
-
   for (const auto &iter : qf)
-    {
-      if (iter->search (this, match_one_filename, nullptr, nullptr,
-			compunit_callback,
-			SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
-			SEARCH_ALL_DOMAINS)
-	  == iteration_status::stop)
-	{
-	  retval = iteration_status::stop;
-	  break;
-	}
-    }
+    if (iter->search (this, match_one_filename, nullptr, nullptr,
+		      compunit_callback,
+		      SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
+		      SEARCH_ALL_DOMAINS)
+	== iteration_status::stop)
+      break;
 
   if (debug_symfile)
-    gdb_printf (gdb_stdlog,
-		"qf->map_symtabs_matching_filename (...) = %s\n",
-		iteration_status_str (retval));
+    gdb_printf (gdb_stdlog, "qf->find_symtab_matching_filename (...) = %p\n",
+		result);
 
-  return retval;
+  return result;
 }
 
 struct compunit_symtab *
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 6a5c8c7058e4..fd841318387e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -637,8 +637,6 @@ static symtab *
 find_symtab (program_space *pspace, const char *name,
 	     find_symtab_callback_ftype callback)
 {
-  struct symtab *result = NULL;
-
   gdb::unique_xmalloc_ptr<char> real_path;
 
   /* Here we are interested in canonicalizing an absolute path, not
@@ -649,21 +647,11 @@ find_symtab (program_space *pspace, const char *name,
       gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
     }
 
-  auto map_callback = [&] (symtab *symtab)
-    {
-      if (callback (symtab))
-	{
-	  result = symtab;
-	  return iteration_status::stop;
-	}
-
-      return iteration_status::keep_going;
-    };
-
   for (objfile &objfile : pspace->objfiles ())
-    if (objfile.map_symtabs_matching_filename (name, real_path.get (),
-					       map_callback)
-	== iteration_status::stop)
+    if (symtab *result
+	  = objfile.find_symtab_matching_filename (name, real_path.get (),
+						   callback);
+	result != nullptr)
       return result;
 
   return nullptr;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 10/11] gdb: make symbol_found_callback_ftype a function_view
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (8 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 09/11] gdb: change objfile::map_symtabs_matching_filename to find_symtab_matching_filename Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  2026-04-16 20:16 ` [PATCH 11/11] gdb: make iterate_over_symbols return void, rename to for_each_symbol Simon Marchi
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

All uses of symbol_found_callback_ftype use it within a function_view,
so factor out the function_view into the type alias.

Change-Id: I24a1d2fc233aa5d593c9c68581a9912bfee3a348
---
 gdb/ada-lang.c | 2 +-
 gdb/language.h | 2 +-
 gdb/linespec.c | 6 +++---
 gdb/symtab.c   | 2 +-
 gdb/symtab.h   | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index f8ed4cc5e102..d388a301fa1a 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -13705,7 +13705,7 @@ class ada_language : public language_defn
   bool iterate_over_symbols
 	(const struct block *block, const lookup_name_info &name,
 	 domain_search_flags domain,
-	 gdb::function_view<symbol_found_callback_ftype> callback) const override
+	 symbol_found_callback_ftype callback) const override
   {
     std::vector<struct block_symbol> results
       = ada_lookup_symbol_list_worker (name, block, domain, 0);
diff --git a/gdb/language.h b/gdb/language.h
index da903eb702d2..0cc075f8a295 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -362,7 +362,7 @@ struct language_defn
   virtual bool iterate_over_symbols
 	(const struct block *block, const lookup_name_info &name,
 	 domain_search_flags domain,
-	 gdb::function_view<symbol_found_callback_ftype> callback) const
+	 symbol_found_callback_ftype callback) const
   {
     return ::iterate_over_symbols (block, name, domain, callback);
   }
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 0afe0c619a13..bfdd075ac825 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -363,7 +363,7 @@ struct linespec_parser
 static void iterate_over_file_blocks
   (struct symtab *symtab, const lookup_name_info &name,
    domain_search_flags domain,
-   gdb::function_view<symbol_found_callback_ftype> callback);
+   symbol_found_callback_ftype callback);
 
 static void initialize_defaults (struct symtab **default_symtab,
 				 int *default_line);
@@ -1128,7 +1128,7 @@ iterate_over_all_matching_symtabs
    const lookup_name_info &lookup_name,
    const domain_search_flags domain,
    struct program_space *search_pspace, bool include_inline,
-   gdb::function_view<symbol_found_callback_ftype> callback)
+   symbol_found_callback_ftype callback)
 {
   for (struct program_space *pspace : program_spaces)
     {
@@ -1196,7 +1196,7 @@ static void
 iterate_over_file_blocks
   (struct symtab *symtab, const lookup_name_info &name,
    domain_search_flags domain,
-   gdb::function_view<symbol_found_callback_ftype> callback)
+   symbol_found_callback_ftype callback)
 {
   const struct block *block;
 
diff --git a/gdb/symtab.c b/gdb/symtab.c
index fd841318387e..62d9ecf0ee0a 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2700,7 +2700,7 @@ bool
 iterate_over_symbols (const struct block *block,
 		      const lookup_name_info &name,
 		      const domain_search_flags domain,
-		      gdb::function_view<symbol_found_callback_ftype> callback)
+		      symbol_found_callback_ftype callback)
 {
   for (struct symbol *sym : block_iterator_range (block, &name))
     {
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 3936052706f1..3217d00914ce 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2811,7 +2811,7 @@ std::vector<const linetable_entry *> find_linetable_entries_for_symtab_line
    true to indicate that LA_ITERATE_OVER_SYMBOLS should continue
    iterating, or false to indicate that the iteration should end.  */
 
-typedef bool (symbol_found_callback_ftype) (struct block_symbol *bsym);
+using symbol_found_callback_ftype = gdb::function_view<bool (block_symbol *)>;
 
 /* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK.
 
@@ -2825,7 +2825,7 @@ typedef bool (symbol_found_callback_ftype) (struct block_symbol *bsym);
 bool iterate_over_symbols (const struct block *block,
 			   const lookup_name_info &name,
 			   const domain_search_flags domain,
-			   gdb::function_view<symbol_found_callback_ftype> callback);
+			   symbol_found_callback_ftype callback);
 
 /* Storage type used by demangle_for_lookup.  demangle_for_lookup
    either returns a const char * pointer that points to either of the
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 11/11] gdb: make iterate_over_symbols return void, rename to for_each_symbol
  2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
                   ` (9 preceding siblings ...)
  2026-04-16 20:16 ` [PATCH 10/11] gdb: make symbol_found_callback_ftype a function_view Simon Marchi
@ 2026-04-16 20:16 ` Simon Marchi
  10 siblings, 0 replies; 12+ messages in thread
From: Simon Marchi @ 2026-04-16 20:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Nothing really uses the return value of iterate_over_symbols and
language::iterate_over_symbols.  Also, all provided callback always
return true, iterating on all matching symbols.  Simplify them to not
return a value and not have the "stop iterating" feature.

Rename to for_each_symbol, just to be consistent with previous patches.

Also rename symbol_found_callback_ftype to
for_each_symbol_callback_ftype for consistency.

Change-Id: I55ff3162098bb069dc1de1afca10dd9abfc05c34
---
 gdb/ada-lang.c | 26 ++++++++------------------
 gdb/language.h | 13 ++++---------
 gdb/linespec.c | 38 ++++++++++++++++----------------------
 gdb/symtab.c   | 23 +++++++++--------------
 gdb/symtab.h   | 22 +++++++---------------
 5 files changed, 44 insertions(+), 78 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d388a301fa1a..593f1eb63fa6 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -5427,7 +5427,7 @@ struct match_data
   }
   DISABLE_COPY_AND_ASSIGN (match_data);
 
-  bool operator() (struct block_symbol *bsym);
+  void operator() (struct block_symbol *bsym);
 
   void finish (const block *block);
 
@@ -5452,14 +5452,14 @@ match_data::finish (const block *block)
 /* A callback for add_nonlocal_symbols that adds symbol, found in
    BSYM, to a list of symbols.  */
 
-bool
+void
 match_data::operator() (struct block_symbol *bsym)
 {
   const struct block *block = bsym->block;
   struct symbol *sym = bsym->symbol;
 
   if (sym->loc_class () == LOC_UNRESOLVED)
-    return true;
+    return;
   else if (sym->is_argument ())
     arg_sym = sym;
   else
@@ -5467,8 +5467,6 @@ match_data::operator() (struct block_symbol *bsym)
       found_sym = true;
       add_defn_to_vec (*resultp, sym, block);
     }
-
-  return true;
 }
 
 /* Helper for add_nonlocal_symbols.  Find symbols in DOMAIN which are
@@ -5563,10 +5561,7 @@ map_matching_symbols (struct objfile *objfile,
     {
       const struct block *block
 	= symtab->blockvector ()->block (block_kind);
-      /* match_data::operator() always returns true; we ignore the
-	 result but assert just to be future-proof.  */
-      bool result = iterate_over_symbols (block, lookup_name, domain, data);
-      gdb_assert (result);
+      for_each_symbol (block, lookup_name, domain, data);
       data.finish (block);
       return iteration_status::keep_going;
     };
@@ -5665,7 +5660,7 @@ ada_add_all_symbols (std::vector<struct block_symbol> &result,
       else
 	{
 	  /* In the !full_search case we're are being called by
-	     iterate_over_symbols, and we don't want to search
+	     for_each_symbol, and we don't want to search
 	     superblocks.  */
 	  ada_add_block_symbols (result, block, lookup_name, domain, NULL);
 	}
@@ -13702,20 +13697,15 @@ class ada_language : public language_defn
 
   /* See language.h.  */
 
-  bool iterate_over_symbols
+  void for_each_symbol
 	(const struct block *block, const lookup_name_info &name,
 	 domain_search_flags domain,
-	 symbol_found_callback_ftype callback) const override
+	 for_each_symbol_callback_ftype callback) const override
   {
     std::vector<struct block_symbol> results
       = ada_lookup_symbol_list_worker (name, block, domain, 0);
     for (block_symbol &sym : results)
-      {
-	if (!callback (&sym))
-	  return false;
-      }
-
-    return true;
+      callback (&sym);
   }
 
   /* See language.h.  */
diff --git a/gdb/language.h b/gdb/language.h
index 0cc075f8a295..b43dae661071 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -353,18 +353,13 @@ struct language_defn
      The caller is responsible for iterating up through superblocks
      if desired.
 
-     For each one, call CALLBACK with the symbol.  If CALLBACK
-     returns false, the iteration ends at that point.
-
-     This field may not be NULL.  If the language does not need any
-     special processing here, 'iterate_over_symbols' should be
-     used as the definition.  */
-  virtual bool iterate_over_symbols
+     For each one, call CALLBACK with the symbol.  */
+  virtual void for_each_symbol
 	(const struct block *block, const lookup_name_info &name,
 	 domain_search_flags domain,
-	 symbol_found_callback_ftype callback) const
+	 for_each_symbol_callback_ftype callback) const
   {
-    return ::iterate_over_symbols (block, name, domain, callback);
+    ::for_each_symbol (block, name, domain, callback);
   }
 
   /* Return a pointer to the function that should be used to match a
diff --git a/gdb/linespec.c b/gdb/linespec.c
index bfdd075ac825..45e12e092725 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -237,17 +237,14 @@ struct collect_info
   std::vector<bound_minimal_symbol> *minimal_symbols;
 
   /* Possibly add a symbol to the results.  */
-  bool add_symbol (block_symbol *bsym);
+  void add_symbol (block_symbol *bsym);
 };
 
-bool
+void
 collect_info::add_symbol (block_symbol *bsym)
 {
   if (record_all || bsym->symbol->loc_class () == LOC_BLOCK)
     this->symbols->push_back (*bsym);
-
-  /* Continue iterating.  */
-  return true;
 }
 
 /* Token types  */
@@ -363,7 +360,7 @@ struct linespec_parser
 static void iterate_over_file_blocks
   (struct symtab *symtab, const lookup_name_info &name,
    domain_search_flags domain,
-   symbol_found_callback_ftype callback);
+   for_each_symbol_callback_ftype callback);
 
 static void initialize_defaults (struct symtab **default_symtab,
 				 int *default_line);
@@ -1128,7 +1125,7 @@ iterate_over_all_matching_symtabs
    const lookup_name_info &lookup_name,
    const domain_search_flags domain,
    struct program_space *search_pspace, bool include_inline,
-   symbol_found_callback_ftype callback)
+   for_each_symbol_callback_ftype callback)
 {
   for (struct program_space *pspace : program_spaces)
     {
@@ -1156,15 +1153,14 @@ iterate_over_all_matching_symtabs
 		  for (i = FIRST_LOCAL_BLOCK; i < bv->num_blocks (); i++)
 		    {
 		      block = bv->block (i);
-		      state->language->iterate_over_symbols
+		      state->language->for_each_symbol
 			(block, lookup_name, domain,
 			 [&] (block_symbol *bsym)
 			 {
 			   /* Restrict calls to CALLBACK to symbols
 			      representing inline symbols only.  */
 			   if (bsym->symbol->is_inlined ())
-			     return callback (bsym);
-			   return true;
+			     callback (bsym);
 			 });
 		    }
 		}
@@ -1196,14 +1192,14 @@ static void
 iterate_over_file_blocks
   (struct symtab *symtab, const lookup_name_info &name,
    domain_search_flags domain,
-   symbol_found_callback_ftype callback)
+   for_each_symbol_callback_ftype callback)
 {
   const struct block *block;
 
   for (block = symtab->compunit ()->blockvector ()->static_block ();
        block != NULL;
        block = block->superblock ())
-    current_language->iterate_over_symbols (block, name, domain, callback);
+    current_language->for_each_symbol (block, name, domain, callback);
 }
 
 /* A helper for find_method.  This finds all methods in type T of
@@ -3325,8 +3321,8 @@ decode_objc (struct linespec_state *self, linespec *ls, const char *arg)
 
 namespace {
 
-/* A function object that serves as symbol_found_callback_ftype
-   callback for iterate_over_symbols.  This is used by
+/* A function object that serves as for_each_symbol_callback_ftype
+   callback for for_each_symbol.  This is used by
    lookup_prefix_sym to collect type symbols.  */
 class decode_compound_collector
 {
@@ -3341,8 +3337,8 @@ class decode_compound_collector
     return std::move (m_symbols);
   }
 
-  /* Callable as a symbol_found_callback_ftype callback.  */
-  bool operator () (block_symbol *bsym);
+  /* Callable as a for_each_symbol_callback_ftype callback.  */
+  void operator () (block_symbol *bsym);
 
 private:
   /* A hash table of all symbols we found.  We use this to avoid
@@ -3353,26 +3349,24 @@ class decode_compound_collector
   std::vector<block_symbol>  m_symbols;
 };
 
-bool
+void
 decode_compound_collector::operator () (block_symbol *bsym)
 {
   struct type *t;
   struct symbol *sym = bsym->symbol;
 
   if (sym->loc_class () != LOC_TYPEDEF)
-    return true; /* Continue iterating.  */
+    return;
 
   t = sym->type ();
   t = check_typedef (t);
   if (t->code () != TYPE_CODE_STRUCT
       && t->code () != TYPE_CODE_UNION
       && t->code () != TYPE_CODE_NAMESPACE)
-    return true; /* Continue iterating.  */
+    return;
 
   if (m_unique_syms.insert (sym).second)
     m_symbols.push_back (*bsym);
-
-  return true; /* Continue iterating.  */
 }
 
 } // namespace
@@ -4245,7 +4239,7 @@ add_matching_symbols_to_info (const char *name,
 
   auto add_symbol = [&] (block_symbol *bsym)
     {
-      return info->add_symbol (bsym);
+      info->add_symbol (bsym);
     };
 
   for (const auto &elt : info->file_symtabs)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 62d9ecf0ee0a..f20deecb2a03 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2696,23 +2696,18 @@ lookup_transparent_type (const char *name, domain_search_flags flags)
 
 /* See symtab.h.  */
 
-bool
-iterate_over_symbols (const struct block *block,
-		      const lookup_name_info &name,
-		      const domain_search_flags domain,
-		      symbol_found_callback_ftype callback)
+void
+for_each_symbol (const struct block *block, const lookup_name_info &name,
+		 const domain_search_flags domain,
+		 for_each_symbol_callback_ftype callback)
 {
   for (struct symbol *sym : block_iterator_range (block, &name))
-    {
-      if (sym->matches (domain))
-	{
-	  struct block_symbol block_sym = {sym, block};
+    if (sym->matches (domain))
+      {
+	block_symbol block_sym = { sym, block };
 
-	  if (!callback (&block_sym))
-	    return false;
-	}
-    }
-  return true;
+	callback (&block_sym);
+      }
 }
 
 /* Find the compunit symtab associated with PC and SECTION.
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 3217d00914ce..68c02e07e397 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2806,26 +2806,18 @@ using find_symtab_callback_ftype = std::function<bool (symtab *)>;
 std::vector<const linetable_entry *> find_linetable_entries_for_symtab_line
     (struct symtab *symtab, int line, const linetable_entry **best_entry);
 
-/* Prototype for callbacks for LA_ITERATE_OVER_SYMBOLS.  The callback
-   is called once per matching symbol SYM.  The callback should return
-   true to indicate that LA_ITERATE_OVER_SYMBOLS should continue
-   iterating, or false to indicate that the iteration should end.  */
+/* Callback type for function for_each_symbol.  */
 
-using symbol_found_callback_ftype = gdb::function_view<bool (block_symbol *)>;
+using for_each_symbol_callback_ftype
+  = gdb::function_view<void (block_symbol *)>;
 
 /* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK.
 
-   For each symbol that matches, CALLBACK is called.  The symbol is
-   passed to the callback.
+   For each symbol that matches, call CALLBACK with the symbol.  */
 
-   If CALLBACK returns false, the iteration ends and this function
-   returns false.  Otherwise, the search continues, and the function
-   eventually returns true.  */
-
-bool iterate_over_symbols (const struct block *block,
-			   const lookup_name_info &name,
-			   const domain_search_flags domain,
-			   symbol_found_callback_ftype callback);
+void for_each_symbol (const struct block *block, const lookup_name_info &name,
+		      const domain_search_flags domain,
+		      for_each_symbol_callback_ftype callback);
 
 /* Storage type used by demangle_for_lookup.  demangle_for_lookup
    either returns a const char * pointer that points to either of the
-- 
2.53.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-04-16 20:27 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-16 20:16 [PATCH 00/11] Readability improvements of some iteration functions Simon Marchi
2026-04-16 20:16 ` [PATCH 01/11] gdb/dwarf: remove unused file_match parameter from dwarf2_base_index_functions::search_one Simon Marchi
2026-04-16 20:16 ` [PATCH 02/11] gdb: rename search_symtabs_expansion_listener -> compunit_symtab_iteration_callback Simon Marchi
2026-04-16 20:16 ` [PATCH 03/11] gdb: introduce iteration_status enum, use it for search callbacks Simon Marchi
2026-04-16 20:16 ` [PATCH 04/11] gdb, gdbserver: make iterate_over_lwps_ftype a function_view Simon Marchi
2026-04-16 20:16 ` [PATCH 05/11] gdb, gdbserver: split iterate_over_lwps in for_each_lwp and find_lwp Simon Marchi
2026-04-16 20:16 ` [PATCH 06/11] gdb: split iterate_over_threads in for_each_thread and find_thread Simon Marchi
2026-04-16 20:16 ` [PATCH 07/11] gdb: split iterate_over_minimal_symbols in for_each_minimal_symbol and find_minimal_symbol Simon Marchi
2026-04-16 20:16 ` [PATCH 08/11] gdb: split iterate_over_symtabs in for_each_symtab and find_symtab Simon Marchi
2026-04-16 20:16 ` [PATCH 09/11] gdb: change objfile::map_symtabs_matching_filename to find_symtab_matching_filename Simon Marchi
2026-04-16 20:16 ` [PATCH 10/11] gdb: make symbol_found_callback_ftype a function_view Simon Marchi
2026-04-16 20:16 ` [PATCH 11/11] gdb: make iterate_over_symbols return void, rename to for_each_symbol Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox