diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 502710a..753409c 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -60,6 +60,7 @@
 #include "mi/mi-common.h"
 #include "arch-utils.h"
 #include "cli/cli-utils.h"
+#include "common/function-view.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C).
@@ -5850,10 +5851,9 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
 /* Implementation of the la_iterate_over_symbols method.  */
 
 static void
-ada_iterate_over_symbols (const struct block *block,
-			  const char *name, domain_enum domain,
-			  symbol_found_callback_ftype *callback,
-			  void *data)
+ada_iterate_over_symbols
+  (const struct block *block, const char *name, domain_enum domain,
+   gdb::function_view<symbol_found_callback_ftype> callback)
 {
   int ndefs, i;
   struct block_symbol *results;
@@ -5861,7 +5861,7 @@ ada_iterate_over_symbols (const struct block *block,
   ndefs = ada_lookup_symbol_list_worker (name, block, domain, &results, 0);
   for (i = 0; i < ndefs; ++i)
     {
-      if (! (*callback) (results[i].symbol, data))
+      if (!callback (results[i].symbol))
 	break;
     }
 }
@@ -6497,30 +6497,6 @@ symbol_completion_add (VEC(char_ptr) **sv,
   VEC_safe_push (char_ptr, *sv, completion);
 }
 
-/* An object of this type is passed as the user_data argument to the
-   expand_symtabs_matching method.  */
-struct add_partial_datum
-{
-  VEC(char_ptr) **completions;
-  const char *text;
-  int text_len;
-  const char *text0;
-  const char *word;
-  int wild_match;
-  int encoded;
-};
-
-/* A callback for expand_symtabs_matching.  */
-
-static int
-ada_complete_symbol_matcher (const char *name, void *user_data)
-{
-  struct add_partial_datum *data = (struct add_partial_datum *) user_data;
-  
-  return symbol_completion_match (name, data->text, data->text_len,
-                                  data->wild_match, data->encoded) != NULL;
-}
-
 /* Return a list of possible symbol names completing TEXT0.  WORD is
    the entire command on which completion is made.  */
 
@@ -6569,19 +6545,16 @@ ada_make_symbol_completion_list (const char *text0, const char *word,
     }
 
   /* First, look at the partial symtab symbols.  */
-  {
-    struct add_partial_datum data;
-
-    data.completions = &completions;
-    data.text = text;
-    data.text_len = text_len;
-    data.text0 = text0;
-    data.word = word;
-    data.wild_match = wild_match_p;
-    data.encoded = encoded_p;
-    expand_symtabs_matching (NULL, ada_complete_symbol_matcher, NULL,
-			     ALL_DOMAIN, &data);
-  }
+  expand_symtabs_matching (NULL,
+			   [&] (const char *symname)
+			   {
+			     return symbol_completion_match (symname,
+							     text, text_len,
+							     wild_match_p,
+							     encoded_p);
+			   },
+			   NULL,
+			   ALL_DOMAIN);
 
   /* At this point scan through the misc symbol vectors and add each
      symbol you find to the list.  Eventually we want to ignore
@@ -13267,30 +13240,6 @@ sort_remove_dups_ada_exceptions_list (VEC(ada_exc_info) **exceptions,
   VEC_truncate(ada_exc_info, *exceptions, skip + to_sort_len);
 }
 
-/* A function intended as the "name_matcher" callback in the struct
-   quick_symbol_functions' expand_symtabs_matching method.
-
-   SEARCH_NAME is the symbol's search name.
-
-   If USER_DATA is not NULL, it is a pointer to a regext_t object
-   used to match the symbol (by natural name).  Otherwise, when USER_DATA
-   is null, no filtering is performed, and all symbols are a positive
-   match.  */
-
-static int
-ada_exc_search_name_matches (const char *search_name, void *user_data)
-{
-  regex_t *preg = (regex_t *) user_data;
-
-  if (preg == NULL)
-    return 1;
-
-  /* In Ada, the symbol "search name" is a linkage name, whereas
-     the regular expression used to do the matching refers to
-     the natural name.  So match against the decoded name.  */
-  return (regexec (preg, ada_decode (search_name), 0, NULL, 0) == 0);
-}
-
 /* Add all exceptions defined by the Ada standard whose name match
    a regular expression.
 
@@ -13370,6 +13319,15 @@ ada_add_exceptions_from_frame (regex_t *preg, struct frame_info *frame,
     }
 }
 
+/* Return true if NAME matches PREG or if PREG is NULL.  */
+
+static bool
+name_matches_regex (const char *name, regex_t *preg)
+{
+  return (preg == NULL
+	  || regexec (preg, ada_decode (name), 0, NULL, 0) == 0);
+}
+
 /* Add all exceptions defined globally whose name name match
    a regular expression, excluding standard exceptions.
 
@@ -13395,8 +13353,17 @@ ada_add_global_exceptions (regex_t *preg, VEC(ada_exc_info) **exceptions)
   struct objfile *objfile;
   struct compunit_symtab *s;
 
-  expand_symtabs_matching (NULL, ada_exc_search_name_matches, NULL,
-			   VARIABLES_DOMAIN, preg);
+  /* In Ada, the symbol "search name" is a linkage name, whereas the
+     regular expression used to do the matching refers to the natural
+     name.  So match against the decoded name.  */
+  expand_symtabs_matching (NULL,
+			   [&] (const char *search_name)
+			   {
+			     const char *decoded = ada_decode (search_name);
+			     return name_matches_regex (decoded, preg);
+			   },
+			   NULL,
+			   VARIABLES_DOMAIN);
 
   ALL_COMPUNITS (objfile, s)
     {
@@ -13411,9 +13378,7 @@ ada_add_global_exceptions (regex_t *preg, VEC(ada_exc_info) **exceptions)
 
 	  ALL_BLOCK_SYMBOLS (b, iter, sym)
 	    if (ada_is_non_standard_exception_sym (sym)
-		&& (preg == NULL
-		    || regexec (preg, SYMBOL_NATURAL_NAME (sym),
-				0, NULL, 0) == 0))
+		&& name_matches_regex (SYMBOL_NATURAL_NAME (sym), preg))
 	      {
 		struct ada_exc_info info
 		  = {SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE_ADDRESS (sym)};
diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 7ad0a87..c969b42 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -25,6 +25,7 @@
 #include "macrotab.h"
 #include "macroscope.h"
 #include "regcache.h"
+#include "common/function-view.h"
 
 /* See compile-internal.h.  */
 
@@ -122,10 +123,8 @@ c_get_compile_context (void)
 static void
 print_one_macro (const char *name, const struct macro_definition *macro,
 		 struct macro_source_file *source, int line,
-		 void *user_data)
+		 ui_file *file)
 {
-  struct ui_file *file = (struct ui_file *) user_data;
-
   /* Don't print command-line defines.  They will be supplied another
      way.  */
   if (line == 0)
@@ -168,7 +167,16 @@ write_macro_definitions (const struct block *block, CORE_ADDR pc,
     scope = user_macro_scope ();
 
   if (scope != NULL && scope->file != NULL && scope->file->table != NULL)
-    macro_for_each_in_scope (scope->file, scope->line, print_one_macro, file);
+    {
+      macro_for_each_in_scope (scope->file, scope->line,
+			       [&] (const char *name,
+				    const macro_definition *macro,
+				    macro_source_file *source,
+				    int line)
+	{
+	  print_one_macro (name, macro, source, line, file);
+	});
+    }
 }
 
 /* Helper function to construct a header scope for a block of code.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 9654fa5..f119750 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -70,6 +70,7 @@
 #include "build-id.h"
 #include "namespace.h"
 #include "common/gdb_unlinker.h"
+#include "common/function-view.h"
 
 #include <fcntl.h>
 #include <sys/types.h>
@@ -3490,8 +3491,7 @@ static int
 dw2_map_expand_apply (struct objfile *objfile,
 		      struct dwarf2_per_cu_data *per_cu,
 		      const char *name, const char *real_path,
-		      int (*callback) (struct symtab *, void *),
-		      void *data)
+		      gdb::function_view<bool (symtab *)> callback)
 {
   struct compunit_symtab *last_made = objfile->compunit_symtabs;
 
@@ -3503,17 +3503,16 @@ dw2_map_expand_apply (struct objfile *objfile,
      all of them.  */
   dw2_instantiate_symtab (per_cu);
 
-  return iterate_over_some_symtabs (name, real_path, callback, data,
-				    objfile->compunit_symtabs, last_made);
+  return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
+				    last_made, callback);
 }
 
 /* Implementation of the map_symtabs_matching_filename method.  */
 
-static int
-dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
-				   const char *real_path,
-				   int (*callback) (struct symtab *, void *),
-				   void *data)
+static bool
+dw2_map_symtabs_matching_filename
+  (struct objfile *objfile, const char *name, const char *real_path,
+   gdb::function_view<bool (symtab *)> callback)
 {
   int i;
   const char *name_basename = lbasename (name);
@@ -3545,8 +3544,8 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
 	  if (compare_filenames_for_search (this_name, name))
 	    {
 	      if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-					callback, data))
-		return 1;
+					callback))
+		return true;
 	      continue;
 	    }
 
@@ -3560,8 +3559,8 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
 	  if (compare_filenames_for_search (this_real_name, name))
 	    {
 	      if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-					callback, data))
-		return 1;
+					callback))
+		return true;
 	      continue;
 	    }
 
@@ -3573,15 +3572,15 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
 		  && FILENAME_CMP (real_path, this_real_name) == 0)
 		{
 		  if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-					    callback, data))
-		    return 1;
+					    callback))
+		    return true;
 		  continue;
 		}
 	    }
 	}
     }
 
-  return 0;
+  return false;
 }
 
 /* Struct used to manage iterating over all CUs looking for a symbol.  */
@@ -3919,11 +3918,10 @@ dw2_map_matching_symbols (struct objfile *objfile,
 static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
-   expand_symtabs_file_matcher_ftype *file_matcher,
-   expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-   expand_symtabs_exp_notify_ftype *expansion_notify,
-   enum search_domain kind,
-   void *data)
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   int i;
   offset_type iter;
@@ -3979,7 +3977,7 @@ dw2_expand_symtabs_matching
 	    {
 	      const char *this_real_name;
 
-	      if (file_matcher (file_data->file_names[j], data, 0))
+	      if (file_matcher (file_data->file_names[j], false))
 		{
 		  per_cu->v.quick->mark = 1;
 		  break;
@@ -3989,11 +3987,11 @@ dw2_expand_symtabs_matching
 		 files are involved, do a quick comparison of the basenames.  */
 	      if (!basenames_may_differ
 		  && !file_matcher (lbasename (file_data->file_names[j]),
-				    data, 1))
+				    true))
 		continue;
 
 	      this_real_name = dw2_get_real_path (objfile, file_data, j);
-	      if (file_matcher (this_real_name, data, 0))
+	      if (file_matcher (this_real_name, false))
 		{
 		  per_cu->v.quick->mark = 1;
 		  break;
@@ -4022,7 +4020,7 @@ dw2_expand_symtabs_matching
 
       name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
 
-      if (! (*symbol_matcher) (name, data))
+      if (!symbol_matcher (name))
 	continue;
 
       /* The name was matched, now expand corresponding CUs that were
@@ -4100,8 +4098,7 @@ dw2_expand_symtabs_matching
 		  && symtab_was_null
 		  && per_cu->v.quick->compunit_symtab != NULL)
 		{
-		  expansion_notify (per_cu->v.quick->compunit_symtab,
-				    data);
+		  expansion_notify (per_cu->v.quick->compunit_symtab);
 		}
 	    }
 	}
diff --git a/gdb/language.h b/gdb/language.h
index b808c9e..3d21e4e 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -24,6 +24,7 @@
 #define LANGUAGE_H 1
 
 #include "symtab.h"
+#include "common/function-view.h"
 
 /* Forward decls for prototypes.  */
 struct value;
@@ -372,18 +373,15 @@ struct language_defn
        The caller is responsible for iterating up through superblocks
        if desired.
 
-       For each one, call CALLBACK with the symbol and the DATA
-       argument.  If CALLBACK returns zero, the iteration ends at that
-       point.
+       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.  */
-    void (*la_iterate_over_symbols) (const struct block *block,
-				     const char *name,
-				     domain_enum domain,
-				     symbol_found_callback_ftype *callback,
-				     void *data);
+    void (*la_iterate_over_symbols)
+      (const struct block *block, const char *name, domain_enum domain,
+       gdb::function_view<symbol_found_callback_ftype> callback);
 
     /* Various operations on varobj.  */
     const struct lang_varobj_ops *la_varobj_ops;
@@ -527,9 +525,8 @@ extern enum language set_language (enum language);
 #define LA_PRINT_ARRAY_INDEX(index_value, stream, options) \
   (current_language->la_print_array_index(index_value, stream, options))
 
-#define LA_ITERATE_OVER_SYMBOLS(BLOCK, NAME, DOMAIN, CALLBACK, DATA) \
-  (current_language->la_iterate_over_symbols (BLOCK, NAME, DOMAIN, CALLBACK, \
-					      DATA))
+#define LA_ITERATE_OVER_SYMBOLS(BLOCK, NAME, DOMAIN, CALLBACK) \
+  (current_language->la_iterate_over_symbols (BLOCK, NAME, DOMAIN, CALLBACK))
 
 /* Test a character to decide whether it can be printed in literal form
    or needs to be printed in another representation.  For example,
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 6308026..5e3732d 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -44,6 +44,7 @@
 #include "ada-lang.h"
 #include "stack.h"
 #include "location.h"
+#include "common/function-view.h"
 
 typedef struct symbol *symbolp;
 DEF_VEC_P (symbolp);
@@ -171,8 +172,23 @@ struct collect_info
     VEC (symbolp) *symbols;
     VEC (bound_minimal_symbol_d) *minimal_symbols;
   } result;
+
+  /* Possibly add a symbol to the results.  */
+  bool add_symbol (symbol *sym);
 };
 
+bool
+collect_info::add_symbol (symbol *sym)
+{
+  /* In list mode, add all matching symbols, regardless of class.
+     This allows the user to type "list a_global_variable".  */
+  if (SYMBOL_CLASS (sym) == LOC_BLOCK || this->state->list_mode)
+    VEC_safe_push (symbolp, this->result.symbols, sym);
+
+  /* Continue iterating.  */
+  return true;
+}
+
 /* Token types  */
 
 enum ls_token_type
@@ -264,10 +280,9 @@ typedef struct ls_parser linespec_parser;
 
 /* Prototypes for local functions.  */
 
-static void iterate_over_file_blocks (struct symtab *symtab,
-				      const char *name, domain_enum domain,
-				      symbol_found_callback_ftype *callback,
-				      void *data);
+static void iterate_over_file_blocks
+  (struct symtab *symtab, const char *name, domain_enum domain,
+   gdb::function_view<symbol_found_callback_ftype> callback);
 
 static void initialize_defaults (struct symtab **default_symtab,
 				 int *default_line);
@@ -916,83 +931,26 @@ maybe_add_address (htab_t set, struct program_space *pspace, CORE_ADDR addr)
   return 1;
 }
 
-/* A callback function and the additional data to call it with.  */
-
-struct symbol_and_data_callback
-{
-  /* The callback to use.  */
-  symbol_found_callback_ftype *callback;
-
-  /* Data to be passed to the callback.  */
-  void *data;
-};
-
-/* A helper for iterate_over_all_matching_symtabs that is used to
-   restrict calls to another callback to symbols representing inline
-   symbols only.  */
-
-static int
-iterate_inline_only (struct symbol *sym, void *d)
-{
-  if (SYMBOL_INLINED (sym))
-    {
-      struct symbol_and_data_callback *cad
-	= (struct symbol_and_data_callback *) d;
-
-      return cad->callback (sym, cad->data);
-    }
-  return 1; /* Continue iterating.  */
-}
-
-/* Some data for the expand_symtabs_matching callback.  */
-
-struct symbol_matcher_data
-{
-  /* The lookup name against which symbol name should be compared.  */
-  const char *lookup_name;
-
-  /* The routine to be used for comparison.  */
-  symbol_name_cmp_ftype symbol_name_cmp;
-};
-
-/* A helper for iterate_over_all_matching_symtabs that is passed as a
-   callback to the expand_symtabs_matching method.  */
-
-static int
-iterate_name_matcher (const char *name, void *d)
-{
-  const struct symbol_matcher_data *data
-    = (const struct symbol_matcher_data *) d;
-
-  if (data->symbol_name_cmp (name, data->lookup_name) == 0)
-    return 1; /* Expand this symbol's symbol table.  */
-  return 0; /* Skip this symbol.  */
-}
-
 /* A helper that walks over all matching symtabs in all objfiles and
    calls CALLBACK for each symbol matching NAME.  If SEARCH_PSPACE is
    not NULL, then the search is restricted to just that program
-   space.  If INCLUDE_INLINE is nonzero then symbols representing
+   space.  If INCLUDE_INLINE is true then symbols representing
    inlined instances of functions will be included in the result.  */
 
 static void
-iterate_over_all_matching_symtabs (struct linespec_state *state,
-				   const char *name,
-				   const domain_enum domain,
-				   symbol_found_callback_ftype *callback,
-				   void *data,
-				   struct program_space *search_pspace,
-				   int include_inline)
+iterate_over_all_matching_symtabs
+  (struct linespec_state *state, const char *name, const domain_enum domain,
+   struct program_space *search_pspace, bool include_inline,
+   gdb::function_view<symbol_found_callback_ftype> callback)
 {
   struct objfile *objfile;
   struct program_space *pspace;
-  struct symbol_matcher_data matcher_data;
 
-  matcher_data.lookup_name = name;
-  matcher_data.symbol_name_cmp =
-    state->language->la_get_symbol_name_cmp != NULL
-    ? state->language->la_get_symbol_name_cmp (name)
-    : strcmp_iw;
+  /* The routine to be used for comparison.  */
+  symbol_name_cmp_ftype symbol_name_cmp
+    = (state->language->la_get_symbol_name_cmp != NULL
+       ? state->language->la_get_symbol_name_cmp (name)
+       : strcmp_iw);
 
   ALL_PSPACES (pspace)
   {
@@ -1008,20 +966,24 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
       struct compunit_symtab *cu;
 
       if (objfile->sf)
-	objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
-						  iterate_name_matcher,
-						  NULL, ALL_DOMAIN,
-						  &matcher_data);
+	objfile->sf->qf->expand_symtabs_matching
+	  (objfile,
+	   NULL,
+	   [&] (const char *symbol_name)
+	   {
+	     return symbol_name_cmp (symbol_name, name) == 0;
+	   },
+	   NULL,
+	   ALL_DOMAIN);
 
       ALL_OBJFILE_COMPUNITS (objfile, cu)
 	{
 	  struct symtab *symtab = COMPUNIT_FILETABS (cu);
 
-	  iterate_over_file_blocks (symtab, name, domain, callback, data);
+	  iterate_over_file_blocks (symtab, name, domain, callback);
 
 	  if (include_inline)
 	    {
-	      struct symbol_and_data_callback cad = { callback, data };
 	      struct block *block;
 	      int i;
 
@@ -1031,7 +993,16 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
 		{
 		  block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
 		  state->language->la_iterate_over_symbols
-		    (block, name, domain, iterate_inline_only, &cad);
+		    (block, name,
+		     domain,
+		     [&] (symbol *sym)
+		     {
+		       /* Restrict calls to CALLBACK to symbols
+			  representing inline symbols only.  */
+		       if (SYMBOL_INLINED (sym))
+			 return callback (sym);
+		       return true;
+		     });
 		}
 	    }
 	}
@@ -1060,16 +1031,16 @@ get_current_search_block (void)
 /* Iterate over static and global blocks.  */
 
 static void
-iterate_over_file_blocks (struct symtab *symtab,
-			  const char *name, domain_enum domain,
-			  symbol_found_callback_ftype *callback, void *data)
+iterate_over_file_blocks
+  (struct symtab *symtab, const char *name, domain_enum domain,
+   gdb::function_view<symbol_found_callback_ftype> callback)
 {
   struct block *block;
 
   for (block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), STATIC_BLOCK);
        block != NULL;
        block = BLOCK_SUPERBLOCK (block))
-    LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data);
+    LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
 }
 
 /* A helper for find_method.  This finds all methods in type T which
@@ -2824,60 +2795,70 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
   return values;
 }
 
-/* An instance of this type is used when collecting prefix symbols for
-   decode_compound.  */
-
-struct decode_compound_collector
+/* A function object that serves as symbol_found_callback_ftype
+   callback for iterate_over_symbols.  This is used by
+   lookup_prefix_sym to collect type symbols.  */
+class decode_compound_collector
 {
-  /* The result vector.  */
-  VEC (symbolp) *symbols;
-
-  /* A hash table of all symbols we found.  We use this to avoid
-     adding any symbol more than once.  */
-  htab_t unique_syms;
-
+public:
   decode_compound_collector ()
-  : symbols (NULL),
-    unique_syms (NULL)
+    : m_symbols (NULL)
   {
+    m_unique_syms = htab_create_alloc (1, htab_hash_pointer,
+				       htab_eq_pointer, NULL,
+				       xcalloc, xfree);
   }
 
   ~decode_compound_collector ()
   {
-    if (unique_syms != NULL)
-      htab_delete (unique_syms);
+    if (m_unique_syms != NULL)
+      htab_delete (m_unique_syms);
   }
-};
 
-/* A callback for iterate_over_symbols that is used by
-   lookup_prefix_sym to collect type symbols.  */
+  /* Releases ownership of the collected symbols and returns them.  */
+  VEC (symbolp) *release_symbols ()
+  {
+    VEC (symbolp) *res = m_symbols;
+    m_symbols = NULL;
+    return res;
+  }
 
-static int
-collect_one_symbol (struct symbol *sym, void *d)
+  /* Callable as a symbol_found_callback_ftype callback.  */
+  bool operator () (symbol *sym);
+
+private:
+  /* A hash table of all symbols we found.  We use this to avoid
+     adding any symbol more than once.  */
+  htab_t m_unique_syms;
+
+  /* The result vector.  */
+  VEC (symbolp) *m_symbols;
+};
+
+bool
+decode_compound_collector::operator () (symbol *sym)
 {
-  struct decode_compound_collector *collector
-    = (struct decode_compound_collector *) d;
   void **slot;
   struct type *t;
 
   if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
-    return 1; /* Continue iterating.  */
+    return true; /* Continue iterating.  */
 
   t = SYMBOL_TYPE (sym);
   t = check_typedef (t);
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION
       && TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
-    return 1; /* Continue iterating.  */
+    return true; /* Continue iterating.  */
 
-  slot = htab_find_slot (collector->unique_syms, sym, INSERT);
+  slot = htab_find_slot (m_unique_syms, sym, INSERT);
   if (!*slot)
     {
       *slot = sym;
-      VEC_safe_push (symbolp, collector->symbols, sym);
+      VEC_safe_push (symbolp, m_symbols, sym);
     }
 
-  return 1; /* Continue iterating.  */
+  return true; /* Continue iterating.  */
 }
 
 /* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS.  */
@@ -2888,27 +2869,16 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
 {
   int ix;
   struct symtab *elt;
-  struct decode_compound_collector collector;
-  struct cleanup *outer;
-  struct cleanup *cleanup;
-
-  collector.symbols = NULL;
-  outer = make_cleanup (VEC_cleanup (symbolp), &collector.symbols);
-
-  collector.unique_syms = htab_create_alloc (1, htab_hash_pointer,
-					     htab_eq_pointer, NULL,
-					     xcalloc, xfree);
+  decode_compound_collector collector;
 
   for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix)
     {
       if (elt == NULL)
 	{
 	  iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN,
-					     collect_one_symbol, &collector,
-					     NULL, 0);
+					     NULL, false, collector);
 	  iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN,
-					     collect_one_symbol, &collector,
-					     NULL, 0);
+					     NULL, false, collector);
 	}
       else
 	{
@@ -2916,15 +2886,12 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
 	     been filtered out earlier.  */
 	  gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
 	  set_current_program_space (SYMTAB_PSPACE (elt));
-	  iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN,
-				    collect_one_symbol, &collector);
-	  iterate_over_file_blocks (elt, class_name, VAR_DOMAIN,
-				    collect_one_symbol, &collector);
+	  iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN, collector);
+	  iterate_over_file_blocks (elt, class_name, VAR_DOMAIN, collector);
 	}
     }
 
-  discard_cleanups (outer);
-  return collector.symbols;
+  return collector.release_symbols ();
 }
 
 /* A qsort comparison function for symbols.  The resulting order does
@@ -3130,45 +3097,57 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
 
 
 
-/* This object is used when collecting all matching symtabs.  */
+/* This function object is a callback for iterate_over_symtabs, used
+   when collecting all matching symtabs.  */
 
-struct symtab_collector
+class symtab_collector
 {
-  /* The result vector of symtabs.  */
-  VEC (symtab_ptr) *symtabs;
-
-  /* This is used to ensure the symtabs are unique.  */
-  htab_t symtab_table;
-
+public:
   symtab_collector ()
-  : symtabs (NULL),
-    symtab_table (NULL)
   {
+    m_symtabs = NULL;
+    m_symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
+				  NULL);
   }
 
   ~symtab_collector ()
   {
-    if (symtab_table != NULL)
-      htab_delete (symtab_table);
+    if (m_symtab_table != NULL)
+      htab_delete (m_symtab_table);
   }
-};
 
-/* Callback for iterate_over_symtabs.  */
+  /* Callable as a symbol_found_callback_ftype callback.  */
+  bool operator () (symtab *sym);
 
-static int
-add_symtabs_to_list (struct symtab *symtab, void *d)
+  /* Releases ownership of the collected symtabs and returns them.  */
+  VEC (symtab_ptr) *release_symtabs ()
+  {
+    VEC (symtab_ptr) *res = m_symtabs;
+    m_symtabs = NULL;
+    return res;
+  }
+
+private:
+  /* The result vector of symtabs.  */
+  VEC (symtab_ptr) *m_symtabs;
+
+  /* This is used to ensure the symtabs are unique.  */
+  htab_t m_symtab_table;
+};
+
+bool
+symtab_collector::operator () (struct symtab *symtab)
 {
-  struct symtab_collector *data = (struct symtab_collector *) d;
   void **slot;
 
-  slot = htab_find_slot (data->symtab_table, symtab, INSERT);
+  slot = htab_find_slot (m_symtab_table, symtab, INSERT);
   if (!*slot)
     {
       *slot = symtab;
-      VEC_safe_push (symtab_ptr, data->symtabs, symtab);
+      VEC_safe_push (symtab_ptr, m_symtabs, symtab);
     }
 
-  return 0;
+  return false;
 }
 
 /* Given a file name, return a VEC of all matching symtabs.  If
@@ -3179,33 +3158,29 @@ static VEC (symtab_ptr) *
 collect_symtabs_from_filename (const char *file,
 			       struct program_space *search_pspace)
 {
-  struct symtab_collector collector;
-  struct cleanup *cleanups;
-  struct program_space *pspace;
-
-  collector.symtabs = NULL;
-  collector.symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
-					NULL);
+  symtab_collector collector;
 
   /* Find that file's data.  */
   if (search_pspace == NULL)
     {
+      struct program_space *pspace;
+
       ALL_PSPACES (pspace)
         {
 	  if (pspace->executing_startup)
 	    continue;
 
 	  set_current_program_space (pspace);
-	  iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+	  iterate_over_symtabs (file, collector);
 	}
     }
   else
     {
       set_current_program_space (search_pspace);
-      iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+      iterate_over_symtabs (file, collector);
     }
 
-  return collector.symtabs;
+  return collector.release_symtabs ();
 }
 
 /* Return all the symtabs associated to the FILENAME.  If SEARCH_PSPACE is
@@ -3577,20 +3552,6 @@ linespec_parse_variable (struct linespec_state *self, const char *variable)
 }
 
 
-/* A callback used to possibly add a symbol to the results.  */
-
-static int
-collect_symbols (struct symbol *sym, void *data)
-{
-  struct collect_info *info = (struct collect_info *) data;
-
-  /* In list mode, add all matching symbols, regardless of class.
-     This allows the user to type "list a_global_variable".  */
-  if (SYMBOL_CLASS (sym) == LOC_BLOCK || info->state->list_mode)
-    VEC_safe_push (symbolp, info->result.symbols, sym);
-  return 1; /* Continue iterating.  */
-}
-
 /* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
    linespec; return the SAL in RESULT.  This function should return SALs
    matching those from find_function_start_sal, otherwise false
@@ -3858,8 +3819,8 @@ add_matching_symbols_to_info (const char *name,
       if (elt == NULL)
 	{
 	  iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
-					     collect_symbols, info,
-					     pspace, 1);
+					     pspace, true, [&] (symbol *sym)
+	    { return info->add_symbol (sym); });
 	  search_minsyms_for_name (info, name, pspace, NULL);
 	}
       else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
@@ -3870,8 +3831,8 @@ add_matching_symbols_to_info (const char *name,
 	     been filtered out earlier.  */
 	  gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
 	  set_current_program_space (SYMTAB_PSPACE (elt));
-	  iterate_over_file_blocks (elt, name, VAR_DOMAIN,
-				    collect_symbols, info);
+	  iterate_over_file_blocks (elt, name, VAR_DOMAIN, [&] (symbol *sym)
+	    { return info->add_symbol (sym); });
 
 	  /* If no new symbols were found in this iteration and this symtab
 	     is in assembler, we might actually be looking for a label for
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index 69668a2..de28545 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -186,20 +186,6 @@ print_macro_definition (const char *name,
     fprintf_filtered (gdb_stdout, "=%s\n", d->replacement);
 }
 
-/* A callback function for usage with macro_for_each and friends.
-   If USER_DATA is null all macros will be printed.
-   Otherwise USER_DATA is considered to be a string, printing
-   only macros who's NAME matches USER_DATA.  Other arguments are
-   routed to print_macro_definition.  */
-static void
-print_macro_callback (const char *name, const struct macro_definition *macro,
-		   struct macro_source_file *source, int line,
-		   void *user_data)
-{
-  if (! user_data || strcmp ((const char *) user_data, name) == 0)
-    print_macro_definition (name, macro, source, line);
-}
-
 /* The implementation of the `info macro' command.  */
 static void
 info_macro_command (char *args, int from_tty)
@@ -248,7 +234,15 @@ info_macro_command (char *args, int from_tty)
   if (! ms)
     macro_inform_no_debuginfo ();
   else if (show_all_macros_named)
-    macro_for_each (ms->file->table, print_macro_callback, name);
+    macro_for_each (ms->file->table,
+		    [name] (const char *macro_name,
+			    const macro_definition *macro,
+			    macro_source_file *source,
+			    int line)
+      {
+	if (strcmp (name, macro_name) == 0)
+	  print_macro_definition (name, macro, source, line);
+      });
   else
     {
       struct macro_definition *d;
@@ -296,7 +290,7 @@ info_macros_command (char *args, int from_tty)
   if (! ms || ! ms->file || ! ms->file->table)
     macro_inform_no_debuginfo ();
   else
-    macro_for_each_in_scope (ms->file, ms->line, print_macro_callback, NULL);
+    macro_for_each_in_scope (ms->file, ms->line, print_macro_definition);
 
   do_cleanups (cleanup_chain);
 }
@@ -465,8 +459,7 @@ macro_undef_command (char *exp, int from_tty)
 
 static void
 print_one_macro (const char *name, const struct macro_definition *macro,
-		 struct macro_source_file *source, int line,
-		 void *ignore)
+		 struct macro_source_file *source, int line)
 {
   fprintf_filtered (gdb_stdout, "macro define %s", name);
   if (macro->kind == macro_function_like)
@@ -486,7 +479,7 @@ print_one_macro (const char *name, const struct macro_definition *macro,
 static void
 macro_list_command (char *exp, int from_tty)
 {
-  macro_for_each (macro_user_macros, print_one_macro, NULL);
+  macro_for_each (macro_user_macros, print_one_macro);
 }
 
 
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 6b3ab6b..1b85c8c 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -965,8 +965,7 @@ macro_definition_location (struct macro_source_file *source,
    the FILE and LINE fields.  */
 struct macro_for_each_data
 {
-  macro_callback_fn fn;
-  void *user_data;
+  gdb::function_view<macro_callback_fn> fn;
   struct macro_source_file *file;
   int line;
 };
@@ -985,20 +984,18 @@ foreach_macro (splay_tree_node node, void *arg)
 			  (struct macro_definition *) node->value);
   xfree (key_fullname);
 
-  (*datum->fn) (key->name, def, key->start_file, key->start_line,
-		datum->user_data);
+  datum->fn (key->name, def, key->start_file, key->start_line);
   return 0;
 }
 
 /* Call FN for every macro in TABLE.  */
 void
-macro_for_each (struct macro_table *table, macro_callback_fn fn,
-		void *user_data)
+macro_for_each (struct macro_table *table,
+		gdb::function_view<macro_callback_fn> fn)
 {
   struct macro_for_each_data datum;
 
   datum.fn = fn;
-  datum.user_data = user_data;
   datum.file = NULL;
   datum.line = 0;
   splay_tree_foreach (table->definitions, foreach_macro, &datum);
@@ -1024,20 +1021,18 @@ foreach_macro_in_scope (splay_tree_node node, void *info)
       && (!key->end_file
 	  || compare_locations (key->end_file, key->end_line,
 				datum->file, datum->line) >= 0))
-    (*datum->fn) (key->name, def, key->start_file, key->start_line,
-		  datum->user_data);
+    datum->fn (key->name, def, key->start_file, key->start_line);
   return 0;
 }
 
 /* Call FN for every macro is visible in SCOPE.  */
 void
 macro_for_each_in_scope (struct macro_source_file *file, int line,
-			 macro_callback_fn fn, void *user_data)
+			 gdb::function_view<macro_callback_fn> fn)
 {
   struct macro_for_each_data datum;
 
   datum.fn = fn;
-  datum.user_data = user_data;
   datum.file = file;
   datum.line = line;
   splay_tree_foreach (file->table->definitions,
diff --git a/gdb/macrotab.h b/gdb/macrotab.h
index 0d06dde..16e959a 100644
--- a/gdb/macrotab.h
+++ b/gdb/macrotab.h
@@ -20,6 +20,8 @@
 #ifndef MACROTAB_H
 #define MACROTAB_H
 
+#include "common/function-view.h"
+
 struct obstack;
 struct bcache;
 struct compunit_symtab;
@@ -329,28 +331,23 @@ struct macro_source_file *(macro_definition_location
                             const char *name,
                             int *definition_line));
 
-/* Callback function when walking a macro table.  NAME is the name of
-   the macro, and DEFINITION is the definition.  SOURCE is the file at the
-   start of the include path, and LINE is the line number of the SOURCE file
-   where the macro was defined.  USER_DATA is an arbitrary pointer which is
-   passed by the caller to macro_for_each or macro_for_each_in_scope.  */
-typedef void (*macro_callback_fn) (const char *name,
-				   const struct macro_definition *definition,
-				   struct macro_source_file *source,
-				   int line,
-				   void *user_data);
-
-/* Call the function FN for each macro in the macro table TABLE.
-   USER_DATA is passed, untranslated, to FN.  */
-void macro_for_each (struct macro_table *table, macro_callback_fn fn,
-		     void *user_data);
-
-/* Call the function FN for each macro that is visible in a given
-   scope.  The scope is represented by FILE and LINE.  USER_DATA is
-   passed, untranslated, to FN.  */
+/* Prototype for a callback callable when walking a macro table.  NAME
+   is the name of the macro, and DEFINITION is the definition.  SOURCE
+   is the file at the start of the include path, and LINE is the line
+   number of the SOURCE file where the macro was defined.  */
+typedef void (macro_callback_fn) (const char *name,
+				  const struct macro_definition *definition,
+				  struct macro_source_file *source,
+				  int line);
+
+/* Call the callable FN for each macro in the macro table TABLE.  */
+void macro_for_each (struct macro_table *table,
+		     gdb::function_view<macro_callback_fn> fn);
+
+/* Call FN for each macro that is visible in a given scope.  The scope
+   is represented by FILE and LINE.  */
 void macro_for_each_in_scope (struct macro_source_file *file, int line,
-			      macro_callback_fn fn,
-			      void *user_data);
+			      gdb::function_view<macro_callback_fn> fn);
 
 /* Return FILE->filename with possibly prepended compilation directory name.
    This is raw concatenation without the "set substitute-path" and gdb_realpath
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 6e42bc5..d98a4af 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -123,13 +123,12 @@ require_partial_symbols (struct objfile *objfile, int verbose)
 /* Helper function for psym_map_symtabs_matching_filename that
    expands the symtabs and calls the iterator.  */
 
-static int
+static bool
 partial_map_expand_apply (struct objfile *objfile,
 			  const char *name,
 			  const char *real_path,
 			  struct partial_symtab *pst,
-			  int (*callback) (struct symtab *, void *),
-			  void *data)
+			  gdb::function_view<bool (symtab *)> callback)
 {
   struct compunit_symtab *last_made = objfile->compunit_symtabs;
 
@@ -145,20 +144,19 @@ partial_map_expand_apply (struct objfile *objfile,
      all of them.  */
   psymtab_to_symtab (objfile, pst);
 
-  return iterate_over_some_symtabs (name, real_path, callback, data,
-				    objfile->compunit_symtabs, last_made);
+  return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
+				    last_made, callback);
 }
 
 /*  Psymtab version of map_symtabs_matching_filename.  See its definition in
     the definition of quick_symbol_functions in symfile.h.  */
 
-static int
-psym_map_symtabs_matching_filename (struct objfile *objfile,
-				    const char *name,
-				    const char *real_path,
-				    int (*callback) (struct symtab *,
-						     void *),
-				    void *data)
+static bool
+psym_map_symtabs_matching_filename
+  (struct objfile *objfile,
+   const char *name,
+   const char *real_path,
+   gdb::function_view<bool (symtab *)> callback)
 {
   struct partial_symtab *pst;
   const char *name_basename = lbasename (name);
@@ -177,8 +175,8 @@ psym_map_symtabs_matching_filename (struct objfile *objfile,
     if (compare_filenames_for_search (pst->filename, name))
       {
 	if (partial_map_expand_apply (objfile, name, real_path,
-				      pst, callback, data))
-	  return 1;
+				      pst, callback))
+	  return true;
 	continue;
       }
 
@@ -191,8 +189,8 @@ psym_map_symtabs_matching_filename (struct objfile *objfile,
     if (compare_filenames_for_search (psymtab_to_fullname (pst), name))
       {
 	if (partial_map_expand_apply (objfile, name, real_path,
-				      pst, callback, data))
-	  return 1;
+				      pst, callback))
+	  return true;
 	continue;
       }
 
@@ -205,14 +203,14 @@ psym_map_symtabs_matching_filename (struct objfile *objfile,
 	if (filename_cmp (psymtab_to_fullname (pst), real_path) == 0)
 	  {
 	    if (partial_map_expand_apply (objfile, name, real_path,
-					  pst, callback, data))
-	      return 1;
+					  pst, callback))
+	      return true;
 	    continue;
 	  }
       }
   }
 
-  return 0;
+  return false;
 }
 
 /* Find which partial symtab contains PC and SECTION starting at psymtab PST.
@@ -1291,17 +1289,15 @@ psym_map_matching_symbols (struct objfile *objfile,
     }
 }
 
-/* A helper for psym_expand_symtabs_matching that handles
-   searching included psymtabs.  This returns 1 if a symbol is found,
-   and zero otherwise.  It also updates the 'searched_flag' on the
+/* A helper for psym_expand_symtabs_matching that handles searching
+   included psymtabs.  This returns true if a symbol is found, and
+   false otherwise.  It also updates the 'searched_flag' on the
    various psymtabs that it searches.  */
 
-static int
-recursively_search_psymtabs (struct partial_symtab *ps,
-			     struct objfile *objfile,
-			     enum search_domain kind,
-			     expand_symtabs_symbol_matcher_ftype *sym_matcher,
-			     void *data)
+static bool
+recursively_search_psymtabs
+  (struct partial_symtab *ps, struct objfile *objfile, enum search_domain kind,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> sym_matcher)
 {
   struct partial_symbol **psym;
   struct partial_symbol **bound, **gbound, **sbound;
@@ -1323,11 +1319,11 @@ recursively_search_psymtabs (struct partial_symtab *ps,
 	continue;
 
       r = recursively_search_psymtabs (ps->dependencies[i],
-				       objfile, kind, sym_matcher, data);
+				       objfile, kind, sym_matcher);
       if (r != 0)
 	{
 	  ps->searched_flag = PST_SEARCHED_AND_FOUND;
-	  return 1;
+	  return true;
 	}
     }
 
@@ -1365,7 +1361,7 @@ recursively_search_psymtabs (struct partial_symtab *ps,
 		   && PSYMBOL_CLASS (*psym) == LOC_BLOCK)
 	       || (kind == TYPES_DOMAIN
 		   && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
-	      && (*sym_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
+	      && sym_matcher (SYMBOL_SEARCH_NAME (*psym)))
 	    {
 	      /* Found a match, so notify our caller.  */
 	      result = PST_SEARCHED_AND_FOUND;
@@ -1385,11 +1381,10 @@ recursively_search_psymtabs (struct partial_symtab *ps,
 static void
 psym_expand_symtabs_matching
   (struct objfile *objfile,
-   expand_symtabs_file_matcher_ftype *file_matcher,
-   expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-   expand_symtabs_exp_notify_ftype *expansion_notify,
-   enum search_domain kind,
-   void *data)
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   struct partial_symtab *ps;
 
@@ -1413,31 +1408,31 @@ psym_expand_symtabs_matching
 
       if (file_matcher)
 	{
-	  int match;
+	  bool match;
 
 	  if (ps->anonymous)
 	    continue;
 
-	  match = (*file_matcher) (ps->filename, data, 0);
+	  match = file_matcher (ps->filename, false);
 	  if (!match)
 	    {
 	      /* Before we invoke realpath, which can get expensive when many
 		 files are involved, do a quick comparison of the basenames.  */
 	      if (basenames_may_differ
-		  || (*file_matcher) (lbasename (ps->filename), data, 1))
-		match = (*file_matcher) (psymtab_to_fullname (ps), data, 0);
+		  || file_matcher (lbasename (ps->filename), true))
+		match = file_matcher (psymtab_to_fullname (ps), false);
 	    }
 	  if (!match)
 	    continue;
 	}
 
-      if (recursively_search_psymtabs (ps, objfile, kind, symbol_matcher, data))
+      if (recursively_search_psymtabs (ps, objfile, kind, symbol_matcher))
 	{
 	  struct compunit_symtab *symtab =
 	    psymtab_to_symtab (objfile, ps);
 
 	  if (expansion_notify != NULL)
-	    expansion_notify (symtab, data);
+	    expansion_notify (symtab);
 	}
     }
 }
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 80039a0..5ca1fa7 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -117,28 +117,23 @@ debug_qf_forget_cached_source_info (struct objfile *objfile)
   debug_data->real_sf->qf->forget_cached_source_info (objfile);
 }
 
-static int
-debug_qf_map_symtabs_matching_filename (struct objfile *objfile,
-					const char *name,
-					const char *real_path,
-					int (*callback) (struct symtab *,
-							 void *),
-					void *data)
+static bool
+debug_qf_map_symtabs_matching_filename
+  (struct objfile *objfile, const char *name, const char *real_path,
+   gdb::function_view<bool (symtab *)> callback)
 {
   const struct debug_sym_fns_data *debug_data
     = ((const struct debug_sym_fns_data *)
        objfile_data (objfile, symfile_debug_objfile_data_key));
-  int retval;
 
   fprintf_filtered (gdb_stdlog,
-		    "qf->map_symtabs_matching_filename (%s, \"%s\", \"%s\", %s, %s)\n",
+		    "qf->map_symtabs_matching_filename (%s, \"%s\", \"%s\", %s)\n",
 		    objfile_debug_name (objfile), name,
 		    real_path ? real_path : NULL,
-		    host_address_to_string (callback),
-		    host_address_to_string (data));
+		    host_address_to_string (&callback));
 
-  retval = debug_data->real_sf->qf->map_symtabs_matching_filename
-    (objfile, name, real_path, callback, data);
+  bool retval = (debug_data->real_sf->qf->map_symtabs_matching_filename
+		 (objfile, name, real_path, callback));
 
   fprintf_filtered (gdb_stdlog,
 		    "qf->map_symtabs_matching_filename (...) = %d\n",
@@ -291,29 +286,28 @@ debug_qf_map_matching_symbols (struct objfile *objfile,
 static void
 debug_qf_expand_symtabs_matching
   (struct objfile *objfile,
-   expand_symtabs_file_matcher_ftype *file_matcher,
-   expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-   expand_symtabs_exp_notify_ftype *expansion_notify,
-   enum search_domain kind, void *data)
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   const struct debug_sym_fns_data *debug_data
     = ((const struct debug_sym_fns_data *)
        objfile_data (objfile, symfile_debug_objfile_data_key));
 
   fprintf_filtered (gdb_stdlog,
-		    "qf->expand_symtabs_matching (%s, %s, %s, %s, %s, %s)\n",
+		    "qf->expand_symtabs_matching (%s, %s, %s, %s, %s)\n",
 		    objfile_debug_name (objfile),
-		    host_address_to_string (file_matcher),
-		    host_address_to_string (symbol_matcher),
-		    host_address_to_string (expansion_notify),
-		    search_domain_name (kind),
-		    host_address_to_string (data));
+		    host_address_to_string (&file_matcher),
+		    host_address_to_string (&symbol_matcher),
+		    host_address_to_string (&expansion_notify),
+		    search_domain_name (kind));
 
   debug_data->real_sf->qf->expand_symtabs_matching (objfile,
 						    file_matcher,
 						    symbol_matcher,
 						    expansion_notify,
-						    kind, data);
+						    kind);
 }
 
 static struct compunit_symtab *
diff --git a/gdb/symfile.c b/gdb/symfile.c
index f2528fc..8b79508 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -3856,11 +3856,11 @@ symfile_free_objfile (struct objfile *objfile)
    See quick_symbol_functions.expand_symtabs_matching for details.  */
 
 void
-expand_symtabs_matching (expand_symtabs_file_matcher_ftype *file_matcher,
-			 expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-			 expand_symtabs_exp_notify_ftype *expansion_notify,
-			 enum search_domain kind,
-			 void *data)
+expand_symtabs_matching
+  (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   struct objfile *objfile;
 
@@ -3869,8 +3869,7 @@ expand_symtabs_matching (expand_symtabs_file_matcher_ftype *file_matcher,
     if (objfile->sf)
       objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
 						symbol_matcher,
-						expansion_notify, kind,
-						data);
+						expansion_notify, kind);
   }
 }
 
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 02aee8d..c3e7a31 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -26,6 +26,7 @@
 #include "symfile-add-flags.h"
 #include "objfile-flags.h"
 #include "gdb_bfd.h"
+#include "common/function-view.h"
 
 /* Opaque declarations.  */
 struct target_section;
@@ -133,20 +134,18 @@ typedef void (symbol_filename_ftype) (const char *filename,
 /* Callback for quick_symbol_functions->expand_symtabs_matching
    to match a file name.  */
 
-typedef int (expand_symtabs_file_matcher_ftype) (const char *filename,
-						 void *data, int basenames);
+typedef bool (expand_symtabs_file_matcher_ftype) (const char *filename,
+						  bool basenames);
 
 /* Callback for quick_symbol_functions->expand_symtabs_matching
    to match a symbol name.  */
 
-typedef int (expand_symtabs_symbol_matcher_ftype) (const char *name,
-						   void *data);
+typedef bool (expand_symtabs_symbol_matcher_ftype) (const char *name);
 
 /* Callback for quick_symbol_functions->expand_symtabs_matching
    to be called after a symtab has been expanded.  */
 
-typedef void (expand_symtabs_exp_notify_ftype) \
-  (struct compunit_symtab *symtab, void *data);
+typedef void (expand_symtabs_exp_notify_ftype) (compunit_symtab *symtab);
 
 /* The "quick" symbol functions exist so that symbol readers can
    avoiding an initial read of all the symbols.  For example, symbol
@@ -189,14 +188,11 @@ struct quick_symbol_functions
 
      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 and DATA to it.
+     all newly-created symbol tables, passing CALLBACK to it.
      The result of this call is returned.  */
-  int (*map_symtabs_matching_filename) (struct objfile *objfile,
-					const char *name,
-					const char *real_path,
-					int (*callback) (struct symtab *,
-							 void *),
-					void *data);
+  bool (*map_symtabs_matching_filename)
+    (struct objfile *objfile, const char *name, const char *real_path,
+     gdb::function_view<bool (symtab *)> callback);
 
   /* Check to see if the symbol is defined in a "partial" symbol table
      of OBJFILE.  BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
@@ -272,30 +268,27 @@ struct quick_symbol_functions
   /* Expand all symbol tables in OBJFILE matching some criteria.
 
      FILE_MATCHER is called for each file in OBJFILE.  The file name
-     and the DATA argument are passed to it.  If it returns zero, this
-     file is skipped.  If FILE_MATCHER is NULL such file is not skipped.
-     If BASENAMES is non-zero the function should consider only base name of
-     DATA (passed file name is already only the lbasename part).
+     is passed to it.  If the matcher returns false, the file is
+     skipped.  If FILE_MATCHER is NULL the file is not skipped.  If
+     BASENAMES is true the matcher should consider only file base
+     names (the passed file name is already only the lbasename'd
+     part).
 
-     Otherwise, if KIND does not match this symbol is skipped.
+     Otherwise, if KIND does not match, this symbol is skipped.
 
-     If even KIND matches, then SYMBOL_MATCHER is called for each symbol
-     defined in the file.  The symbol "search" name and DATA are passed
-     to SYMBOL_MATCHER.
+     If even KIND matches, SYMBOL_MATCHER is called for each symbol
+     defined in the file.  The symbol "search" name is passed to
+     SYMBOL_MATCHER.
 
-     If SYMBOL_MATCHER returns zero, then this symbol is skipped.
+     If SYMBOL_MATCHER returns false, then the symbol is skipped.
 
-     Otherwise, this symbol's symbol table is expanded.
-
-     DATA is user data that is passed unmodified to the callback
-     functions.  */
+     Otherwise, the symbol's symbol table is expanded.  */
   void (*expand_symtabs_matching)
     (struct objfile *objfile,
-     expand_symtabs_file_matcher_ftype *file_matcher,
-     expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-     expand_symtabs_exp_notify_ftype *expansion_notify,
-     enum search_domain kind,
-     void *data);
+     gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+     gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+     gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+     enum search_domain kind);
 
   /* Return the comp unit from OBJFILE that contains PC and
      SECTION.  Return NULL if there is no such compunit.  This
@@ -565,10 +558,11 @@ void free_symfile_segment_data (struct symfile_segment_data *data);
 
 extern struct cleanup *increment_reading_symtab (void);
 
-void expand_symtabs_matching (expand_symtabs_file_matcher_ftype *,
-			      expand_symtabs_symbol_matcher_ftype *,
-			      expand_symtabs_exp_notify_ftype *,
-			      enum search_domain kind, void *data);
+void expand_symtabs_matching
+  (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind);
 
 void map_symbol_filenames (symbol_filename_ftype *fun, void *data,
 			   int need_fullname);
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index ab50570..32a5331 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -937,37 +937,6 @@ maintenance_check_symtabs (char *ignore, int from_tty)
     }
 }
 
-/* Helper function for maintenance_expand_symtabs.
-   This is the name_matcher function for expand_symtabs_matching.  */
-
-static int
-maintenance_expand_name_matcher (const char *symname, void *data)
-{
-  /* Since we're not searching on symbols, just return TRUE.  */
-  return 1;
-}
-
-/* Helper function for maintenance_expand_symtabs.
-   This is the file_matcher function for expand_symtabs_matching.  */
-
-static int
-maintenance_expand_file_matcher (const char *filename, void *data,
-				 int basenames)
-{
-  const char *regexp = (const char *) data;
-
-  QUIT;
-
-  /* KISS: Only apply the regexp to the complete file name.  */
-  if (basenames)
-    return 0;
-
-  if (regexp == NULL || re_exec (filename))
-    return 1;
-
-  return 0;
-}
-
 /* Expand all symbol tables whose name matches an optional regexp.  */
 
 static void
@@ -1003,8 +972,20 @@ maintenance_expand_symtabs (char *args, int from_tty)
       if (objfile->sf)
 	{
 	  objfile->sf->qf->expand_symtabs_matching
-	    (objfile, maintenance_expand_file_matcher,
-	     maintenance_expand_name_matcher, NULL, ALL_DOMAIN, regexp);
+	    (objfile,
+	     [&] (const char *filename, bool basenames)
+	     {
+	       /* KISS: Only apply the regexp to the complete file name.  */
+	       return (!basenames
+		       && (regexp == NULL || re_exec (filename)));
+	     },
+	     [] (const char *symname)
+	     {
+	       /* Since we're not searching on symbols, just return true.  */
+	       return true;
+	     },
+	     NULL,
+	     ALL_DOMAIN);
 	}
     }
 
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2c141e5..346d5d2 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -382,23 +382,20 @@ compare_glob_filenames_for_search (const char *filename,
    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, CALLBACK, and DATA
-   are identical to the `map_symtabs_matching_filename' method of
-   quick_symbol_functions.
+   The return value, NAME, REAL_PATH and CALLBACK are identical to the
+   `map_symtabs_matching_filename' method of quick_symbol_functions.
 
    FIRST and AFTER_LAST indicate the range of compunit symtabs to search.
    Each symtab within the specified compunit symtab is also searched.
    AFTER_LAST is one past the last compunit symtab to search; NULL means to
    search until the end of the list.  */
 
-int
+bool
 iterate_over_some_symtabs (const char *name,
 			   const char *real_path,
-			   int (*callback) (struct symtab *symtab,
-					    void *data),
-			   void *data,
 			   struct compunit_symtab *first,
-			   struct compunit_symtab *after_last)
+			   struct compunit_symtab *after_last,
+			   gdb::function_view<bool (symtab *)> callback)
 {
   struct compunit_symtab *cust;
   struct symtab *s;
@@ -410,8 +407,8 @@ iterate_over_some_symtabs (const char *name,
 	{
 	  if (compare_filenames_for_search (s->filename, name))
 	    {
-	      if (callback (s, data))
-		return 1;
+	      if (callback (s))
+		return true;
 	      continue;
 	    }
 
@@ -423,8 +420,8 @@ iterate_over_some_symtabs (const char *name,
 
 	  if (compare_filenames_for_search (symtab_to_fullname (s), name))
 	    {
-	      if (callback (s, data))
-		return 1;
+	      if (callback (s))
+		return true;
 	      continue;
 	    }
 
@@ -438,82 +435,59 @@ iterate_over_some_symtabs (const char *name,
 	      gdb_assert (IS_ABSOLUTE_PATH (name));
 	      if (FILENAME_CMP (real_path, fullname) == 0)
 		{
-		  if (callback (s, data))
-		    return 1;
+		  if (callback (s))
+		    return true;
 		  continue;
 		}
 	    }
 	}
     }
 
-  return 0;
+  return false;
 }
 
 /* Check 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.
 
-   Calls CALLBACK with each symtab that is found and with the supplied
-   DATA.  If CALLBACK returns true, the search stops.  */
+   Calls CALLBACK with each symtab that is found.  If CALLBACK returns
+   true, the search stops.  */
 
 void
 iterate_over_symtabs (const char *name,
-		      int (*callback) (struct symtab *symtab,
-				       void *data),
-		      void *data)
+		      gdb::function_view<bool (symtab *)> callback)
 {
   struct objfile *objfile;
-  char *real_path = NULL;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+  gdb::unique_xmalloc_ptr <char> real_path;
 
   /* Here we are interested in canonicalizing an absolute path, not
      absolutizing a relative path.  */
   if (IS_ABSOLUTE_PATH (name))
     {
-      real_path = gdb_realpath (name);
-      make_cleanup (xfree, real_path);
-      gdb_assert (IS_ABSOLUTE_PATH (real_path));
+      real_path.reset (gdb_realpath (name));
+      gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
     }
 
   ALL_OBJFILES (objfile)
-  {
-    if (iterate_over_some_symtabs (name, real_path, callback, data,
-				   objfile->compunit_symtabs, NULL))
-      {
-	do_cleanups (cleanups);
+    {
+      if (iterate_over_some_symtabs (name, real_path.get (),
+				     objfile->compunit_symtabs, NULL,
+				     callback))
 	return;
-      }
-  }
+    }
 
   /* Same search rules as above apply here, but now we look thru the
      psymtabs.  */
 
   ALL_OBJFILES (objfile)
-  {
-    if (objfile->sf
-	&& objfile->sf->qf->map_symtabs_matching_filename (objfile,
-							   name,
-							   real_path,
-							   callback,
-							   data))
-      {
-	do_cleanups (cleanups);
+    {
+      if (objfile->sf
+	  && objfile->sf->qf->map_symtabs_matching_filename (objfile,
+							     name,
+							     real_path.get (),
+							     callback))
 	return;
-      }
-  }
-
-  do_cleanups (cleanups);
-}
-
-/* The callback function used by lookup_symtab.  */
-
-static int
-lookup_symtab_callback (struct symtab *symtab, void *data)
-{
-  struct symtab **result_ptr = (struct symtab **) data;
-
-  *result_ptr = symtab;
-  return 1;
+    }
 }
 
 /* A wrapper for iterate_over_symtabs that returns the first matching
@@ -524,7 +498,12 @@ lookup_symtab (const char *name)
 {
   struct symtab *result = NULL;
 
-  iterate_over_symtabs (name, lookup_symtab_callback, &result);
+  iterate_over_symtabs (name, [&] (symtab *symtab)
+    {
+      result = symtab;
+      return true;
+    });
+
   return result;
 }
 
@@ -2777,18 +2756,17 @@ basic_lookup_transparent_type (const char *name)
 }
 
 /* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK.
-   
-   For each symbol that matches, CALLBACK is called.  The symbol and
-   DATA are passed to the callback.
-   
-   If CALLBACK returns zero, the iteration ends.  Otherwise, the
+
+   For each symbol that matches, CALLBACK is called.  The symbol is
+   passed to the callback.
+
+   If CALLBACK returns false, the iteration ends.  Otherwise, the
    search continues.  */
 
 void
 iterate_over_symbols (const struct block *block, const char *name,
 		      const domain_enum domain,
-		      symbol_found_callback_ftype *callback,
-		      void *data)
+		      gdb::function_view<symbol_found_callback_ftype> callback)
 {
   struct block_iterator iter;
   struct symbol *sym;
@@ -2798,7 +2776,7 @@ iterate_over_symbols (const struct block *block, const char *name,
       if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
 				 SYMBOL_DOMAIN (sym), domain))
 	{
-	  if (!callback (sym, data))
+	  if (!callback (sym))
 	    return;
 	}
     }
@@ -4282,39 +4260,6 @@ sort_search_symbols_remove_dups (struct symbol_search *found, int nfound,
   xfree (symbols);
 }
 
-/* An object of this type is passed as the user_data to the
-   expand_symtabs_matching method.  */
-struct search_symbols_data
-{
-  int nfiles;
-  const char **files;
-
-  /* It is true if PREG contains valid data, false otherwise.  */
-  unsigned preg_p : 1;
-  regex_t preg;
-};
-
-/* A callback for expand_symtabs_matching.  */
-
-static int
-search_symbols_file_matches (const char *filename, void *user_data,
-			     int basenames)
-{
-  struct search_symbols_data *data = (struct search_symbols_data *) user_data;
-
-  return file_matches (filename, data->files, data->nfiles, basenames);
-}
-
-/* A callback for expand_symtabs_matching.  */
-
-static int
-search_symbols_name_matches (const char *symname, void *user_data)
-{
-  struct search_symbols_data *data = (struct search_symbols_data *) user_data;
-
-  return !data->preg_p || regexec (&data->preg, symname, 0, NULL, 0) == 0;
-}
-
 /* Search the symbol table for matches to the regular expression REGEXP,
    returning the results in *MATCHES.
 
@@ -4359,8 +4304,10 @@ search_symbols (const char *regexp, enum search_domain kind,
   enum minimal_symbol_type ourtype4;
   struct symbol_search *found;
   struct symbol_search *tail;
-  struct search_symbols_data datum;
   int nfound;
+  /* This is true if PREG contains valid data, false otherwise.  */
+  bool preg_p;
+  regex_t preg;
 
   /* OLD_CHAIN .. RETVAL_CHAIN is always freed, RETVAL_CHAIN .. current
      CLEANUP_CHAIN is freed only in the case of an error.  */
@@ -4375,7 +4322,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   ourtype4 = types4[kind];
 
   *matches = NULL;
-  datum.preg_p = 0;
+  preg_p = false;
 
   if (regexp != NULL)
     {
@@ -4414,31 +4361,35 @@ search_symbols (const char *regexp, enum search_domain kind,
 	    }
 	}
 
-      errcode = regcomp (&datum.preg, regexp,
+      errcode = regcomp (&preg, regexp,
 			 REG_NOSUB | (case_sensitivity == case_sensitive_off
 				      ? REG_ICASE : 0));
       if (errcode != 0)
 	{
-	  char *err = get_regcomp_error (errcode, &datum.preg);
+	  char *err = get_regcomp_error (errcode, &preg);
 
 	  make_cleanup (xfree, err);
 	  error (_("Invalid regexp (%s): %s"), err, regexp);
 	}
-      datum.preg_p = 1;
-      make_regfree_cleanup (&datum.preg);
+      preg_p = true;
+      make_regfree_cleanup (&preg);
     }
 
   /* Search through the partial symtabs *first* for all symbols
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below.  */
-
-  datum.nfiles = nfiles;
-  datum.files = files;
-  expand_symtabs_matching ((nfiles == 0
-			    ? NULL
-			    : search_symbols_file_matches),
-			   search_symbols_name_matches,
-			   NULL, kind, &datum);
+  expand_symtabs_matching ([&] (const char *filename, bool basenames)
+			   {
+			     return file_matches (filename, files, nfiles,
+						  basenames);
+			   },
+			   [&] (const char *symname)
+			   {
+			     return (!preg_p || regexec (&preg, symname,
+							 0, NULL, 0) == 0);
+			   },
+			   NULL,
+			   kind);
 
   /* Here, we search through the minimal symbol tables for functions
      and variables that match, and force their symbols to be read.
@@ -4470,8 +4421,8 @@ search_symbols (const char *regexp, enum search_domain kind,
 	    || MSYMBOL_TYPE (msymbol) == ourtype3
 	    || MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (!datum.preg_p
-		|| regexec (&datum.preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
+	    if (!preg_p
+		|| regexec (&preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
 			    NULL, 0) == 0)
 	      {
 		/* Note: An important side-effect of these lookup functions
@@ -4514,8 +4465,8 @@ search_symbols (const char *regexp, enum search_domain kind,
 				       files, nfiles, 1))
 		     && file_matches (symtab_to_fullname (real_symtab),
 				      files, nfiles, 0)))
-		&& ((!datum.preg_p
-		     || regexec (&datum.preg, SYMBOL_NATURAL_NAME (sym), 0,
+		&& ((!preg_p
+		     || regexec (&preg, SYMBOL_NATURAL_NAME (sym), 0,
 				 NULL, 0) == 0)
 		    && ((kind == VARIABLES_DOMAIN
 			 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
@@ -4572,8 +4523,8 @@ search_symbols (const char *regexp, enum search_domain kind,
 	    || MSYMBOL_TYPE (msymbol) == ourtype3
 	    || MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (!datum.preg_p
-		|| regexec (&datum.preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
+	    if (!preg_p
+		|| regexec (&preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
 			    NULL, 0) == 0)
 	      {
 		/* For functions we can do a quick check of whether the
@@ -5110,46 +5061,6 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text,
     }
 }
 
-/* Type of the user_data argument passed to add_macro_name,
-   symbol_completion_matcher and symtab_expansion_callback.  */
-
-struct add_name_data
-{
-  /* Arguments required by completion_list_add_name.  */
-  const char *sym_text;
-  int sym_text_len;
-  const char *text;
-  const char *word;
-
-  /* Extra argument required for add_symtab_completions.  */
-  enum type_code code;
-};
-
-/* A callback used with macro_for_each and macro_for_each_in_scope.
-   This adds a macro's name to the current completion list.  */
-
-static void
-add_macro_name (const char *name, const struct macro_definition *ignore,
-		struct macro_source_file *ignore2, int ignore3,
-		void *user_data)
-{
-  struct add_name_data *datum = (struct add_name_data *) user_data;
-
-  completion_list_add_name (name,
-			    datum->sym_text, datum->sym_text_len,
-			    datum->text, datum->word);
-}
-
-/* A callback for expand_symtabs_matching.  */
-
-static int
-symbol_completion_matcher (const char *name, void *user_data)
-{
-  struct add_name_data *datum = (struct add_name_data *) user_data;
-
-  return compare_symbol_name (name, datum->sym_text, datum->sym_text_len);
-}
-
 /* Add matching symbols from SYMTAB to the current completion list.  */
 
 static void
@@ -5182,21 +5093,6 @@ add_symtab_completions (struct compunit_symtab *cust,
     }
 }
 
-/* Callback to add completions to the current list when symbol tables
-   are expanded during completion list generation.  */
-
-static void
-symtab_expansion_callback (struct compunit_symtab *symtab,
-			   void *user_data)
-{
-  struct add_name_data *datum = (struct add_name_data *) user_data;
-
-  add_symtab_completions (symtab,
-			  datum->sym_text, datum->sym_text_len,
-			  datum->text, datum->word,
-			  datum->code);
-}
-
 static void
 default_make_symbol_completion_list_break_on_1 (const char *text,
 						const char *word,
@@ -5218,7 +5114,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
   const char *sym_text;
   /* Length of sym_text.  */
   int sym_text_len;
-  struct add_name_data datum;
   struct cleanup *cleanups;
 
   /* Now look for the symbol we are supposed to complete on.  */
@@ -5292,12 +5187,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
   completion_tracker = new_completion_tracker ();
   cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
 
-  datum.sym_text = sym_text;
-  datum.sym_text_len = sym_text_len;
-  datum.text = text;
-  datum.word = word;
-  datum.code = code;
-
   /* At this point scan through the misc symbol vectors and add each
      symbol you find to the list.  Eventually we want to ignore
      anything that isn't a text symbol (everything else will be
@@ -5321,13 +5210,22 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
     add_symtab_completions (cust, sym_text, sym_text_len, text, word,
 			    code);
 
-  /* Look through the partial symtabs for all symbols which begin
-     by matching SYM_TEXT.  Expand all CUs that you find to the list.
-     symtab_expansion_callback is called for each expanded symtab,
-     causing those symtab's completions to be added to the list too.  */
-  expand_symtabs_matching (NULL, symbol_completion_matcher,
-			   symtab_expansion_callback, ALL_DOMAIN,
-			   &datum);
+  /* Look through the partial symtabs for all symbols which begin by
+     matching SYM_TEXT.  Expand all CUs that you find to the list.  */
+  expand_symtabs_matching (NULL,
+			   [&] (const char *name) /* symbol matcher */
+			     {
+			       return compare_symbol_name (name,
+							   sym_text,
+							   sym_text_len);
+			     },
+			   [&] (compunit_symtab *symtab) /* expansion notify */
+			     {
+			       add_symtab_completions (symtab,
+						       sym_text, sym_text_len,
+						       text, word, code);
+			     },
+			   ALL_DOMAIN);
 
   /* Search upwards from currently selected frame (so that we can
      complete on local vars).  Also catch fields of types defined in
@@ -5385,6 +5283,17 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
     {
       struct macro_scope *scope;
 
+      /* This adds a macro's name to the current completion list.  */
+      auto add_macro_name = [&] (const char *macro_name,
+				 const macro_definition *,
+				 macro_source_file *,
+				 int)
+	{
+	  completion_list_add_name (macro_name,
+				    sym_text, sym_text_len,
+				    text, word);
+	};
+
       /* Add any macros visible in the default scope.  Note that this
 	 may yield the occasional wrong result, because an expression
 	 might be evaluated in a scope other than the default.  For
@@ -5396,12 +5305,12 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
       if (scope)
 	{
 	  macro_for_each_in_scope (scope->file, scope->line,
-				   add_macro_name, &datum);
+				   add_macro_name);
 	  xfree (scope);
 	}
 
       /* User-defined macros are always visible.  */
-      macro_for_each (macro_user_macros, add_macro_name, &datum);
+      macro_for_each (macro_user_macros, add_macro_name);
     }
 
   do_cleanups (cleanups);
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 88bdd27..d8c665c 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -24,6 +24,7 @@
 #include "gdb_vecs.h"
 #include "gdbtypes.h"
 #include "common/enum-flags.h"
+#include "common/function-view.h"
 
 /* Opaque declarations.  */
 struct ui_file;
@@ -1607,35 +1608,29 @@ int compare_filenames_for_search (const char *filename,
 int compare_glob_filenames_for_search (const char *filename,
 				       const char *search_name);
 
-int iterate_over_some_symtabs (const char *name,
-			       const char *real_path,
-			       int (*callback) (struct symtab *symtab,
-						void *data),
-			       void *data,
-			       struct compunit_symtab *first,
-			       struct compunit_symtab *after_last);
+bool iterate_over_some_symtabs (const char *name,
+				const char *real_path,
+				struct compunit_symtab *first,
+				struct compunit_symtab *after_last,
+				gdb::function_view<bool (symtab *)> callback);
 
 void iterate_over_symtabs (const char *name,
-			   int (*callback) (struct symtab *symtab,
-					    void *data),
-			   void *data);
+			   gdb::function_view<bool (symtab *)> callback);
+
 
 VEC (CORE_ADDR) *find_pcs_for_symtab_line (struct symtab *symtab, int line,
 					   struct linetable_entry **best_entry);
 
-/* Callback for LA_ITERATE_OVER_SYMBOLS.  The callback will be called
-   once per matching symbol SYM, with DATA being the argument of the
-   same name that was passed to LA_ITERATE_OVER_SYMBOLS.  The callback
-   should return nonzero to indicate that LA_ITERATE_OVER_SYMBOLS
-   should continue iterating, or zero to indicate that the iteration
-   should end.  */
+/* 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.  */
 
-typedef int (symbol_found_callback_ftype) (struct symbol *sym, void *data);
+typedef bool (symbol_found_callback_ftype) (symbol *sym);
 
 void iterate_over_symbols (const struct block *block, const char *name,
 			   const domain_enum domain,
-			   symbol_found_callback_ftype *callback,
-			   void *data);
+			   gdb::function_view<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
