]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: introduce iteration_status enum, use it for search callbacks
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 16 Apr 2026 20:16:13 +0000 (16:16 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Fri, 17 Apr 2026 19:30:29 +0000 (15:30 -0400)
There are a bunch of iteration functions that take a callback returning
true or false to indicate whether to continue or stop iterating.  These
functions then return the same value, indicate whether the iteration was
done until the end of interrupted.  I think this is confusing and
error-prone, as I never know which value means what.  It is especially
confusing when two opposite conventions collide, such as in
objfile::map_symtabs_matching_filename.

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

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

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

Change-Id: I55d84d0c1af8ac0b82cc9f49ccf0d6b60e1769e0
Approved-By: Andrew Burgess <aburgess@redhat.com>
18 files changed:
gdb/ada-lang.c
gdb/cp-support.c
gdb/dwarf2/cooked-index-entry.c
gdb/dwarf2/cooked-index-entry.h
gdb/dwarf2/cooked-index.h
gdb/dwarf2/index-write.c
gdb/dwarf2/read.c
gdb/dwarf2/read.h
gdb/expanded-symbol.c
gdb/expanded-symbol.h
gdb/linespec.c
gdb/objfiles.h
gdb/python/py-symbol.c
gdb/quick-symbol.h
gdb/symfile-debug.c
gdb/symtab.c
gdb/symtab.h
gdbsupport/iteration-status.h [new file with mode: 0644]

index 805999e18eea0c4232f7ff882c542deb20cec86f..f8ed4cc5e1024ed02430f02270708c5778d1dee1 100644 (file)
@@ -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 @@ public:
                  }
              }
 
-           return true;
+           return iteration_status::keep_going;
          };
 
        objfile.search
index d321986f72dabc515db27367cf1940adc90f15ef..d040ad79469a20297e6cf7fc919a9671a867ffdf 100644 (file)
@@ -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
index 2f61e5c4c57bbf91ef4de00b652a3f468e0c0ddc..21e25e9461582ea8f8cbb7de64e54a8431affe26 100644 (file)
@@ -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)
index 9eed2ca9c46c1f84f702356f258884f74d060a76..9f7a7c42de4f67c532aaec16feebad46ba923472 100644 (file)
@@ -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
index 00a15661677b56d7337352a51339846d00adbb5a..2e177cb62dd29fb2555baec2f28e8468b3220731 100644 (file)
@@ -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,
index 0f940920862f8425cfef57f17526b8e4997b5431..6f8e41ff96faceaeb876d118391e489b24c08d2d 100644 (file)
@@ -721,7 +721,7 @@ public:
            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;
        });
     }
 }
index 6146ff78b678813f1b20b3542054049bdcaf937d..48e89d10eac781ed5dd217ea60d182fc2bd77fad 100644 (file)
@@ -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.  */
index 40b55a33bc8da0d0a58c86dfca22a3008578ef61..c65ee7f86990df1837428bc00e18f759ede2ec9b 100644 (file)
@@ -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 @@ public:
   }
 
   /* 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 @@ 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 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.  */
index fee55cd23db337b4a834189bcab7393ab26f9406..6dcb4047e3feb46eb503d9c027e4be482404e2ac 100644 (file)
@@ -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.  */
index fc42938d9d3d1fbfe468d949883c54c32f32521e..68f5532e6b8c73cf2b779e924459ece7de788833 100644 (file)
@@ -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,
index 981bd5faa4fca49ba5c9f9c741b0303292f973fa..4ea6d597a0931413019b55de0a42484bb6dd1fc2 100644 (file)
@@ -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.  */
index aafac6ac93c643a0a99c8a3bf7884d6518235e0b..8ae54b37bb794fa0d9e78899ee076dd5b63e4f20 100644 (file)
@@ -583,9 +583,9 @@ public:
      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 @@ public:
   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 *
index e74c8e4b3680b51e7916ca429d48c97264160d40..6293b658ea1dbf43ee539dff3c6f9409350fa28c 100644 (file)
@@ -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)
index 9cecc1bf52c17e47dfc2c660d142d42dc2e4a5a9..2d1ca78293ddc25181245bff5a7b0e48827b61ff 100644 (file)
@@ -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,
index d26662e206562c8857864d5ce0d3c045550fbd16..9fe5e030f7a0bf0f19d6f08ea1a0a6bdbce4b42a 100644 (file)
@@ -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,33 @@ 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.  */
+    return iterate_over_one_compunit_symtab (name_basename, name, real_path,
+                                            symtab, callback);
   };
 
+  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 +318,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 +400,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 +422,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 *
index a6b145e5331ba8921ce0a2e7959576d3aab2b595..d22dd81a246a0b7ea3afd91e2bfff30054d33f03 100644 (file)
@@ -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;
     });
 }
 
index 0db85bcf5baadd066c7a975be9dfe642a4f949f9..0c379db372c2ae842485c9ae620c392d60d1f95e 100644 (file)
@@ -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"
@@ -2793,10 +2794,11 @@ bool compare_filenames_for_search (const char *filename,
    symtab filename will also work.
 
    Call CALLBACK with each symtab that is found.  If CALLBACK returns
-   true, the search stops.  */
+   iteration_status::stop, 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 (file)
index 0000000..c4c17fe
--- /dev/null
@@ -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 */