Use gdb::function_view in iterate_over_symtabs & co

I wanted to pass a lambda to iterate_over_symtabs (see following
patch), so I converted it to function_view, and then the rest is
cascaded from that.

This gets rid of a bunch of single-use callback functions and
corresponding manually managed callback capture types
(add_partial_datum, search_symbols_data, etc.) in favor of letting the
compiler generate them for us by using lambdas with a capture.  In a
couple cases, it was more natural to convert the existing function
callbacks to function objects (i.e., operator(), e.g.,
decode_compound_collector).

gdb/ChangeLog:
2017-02-23  Pedro Alves  <palves@redhat.com>

	* ada-lang.c: Include "common/function-view.h".
	(ada_iterate_over_symbols): Adjust to use function_view as
	callback type.
	(struct add_partial_datum, ada_complete_symbol_matcher): Delete.
	(ada_make_symbol_completion_list): Use a lambda.
	(ada_exc_search_name_matches): Delete.
	(name_matches_regex): New.
	(ada_add_global_exceptions): Use a lambda and name_matches_regex.
	* compile/compile-c-support.c: Include "common/function-view.h".
	(print_one_macro): Change prototype to accept a ui_file pointer.
	(write_macro_definitions): Use a lambda.
	* dwarf2read.c: Include "common/function-view.h".
	(dw2_map_expand_apply, dw2_map_symtabs_matching_filename)
	(dw2_expand_symtabs_matching): Adjust to use function_view as
	callback type.
	* language.h: Include "common/function-view.h".
	(struct language_defn) <la_iterate_over_symbols>: Adjust to use
	function_view as callback type.
	(LA_ITERATE_OVER_SYMBOLS): Remove DATA parameter.
	* linespec.c: Include "common/function-view.h".
	(collect_info::add_symbol): New method.
	(struct symbol_and_data_callback, iterate_inline_only, struct
	symbol_matcher_data, iterate_name_matcher): Delete.
	(iterate_over_all_matching_symtabs): Adjust to use function_view
	as callback type and lambdas.
	(iterate_over_file_blocks): Adjust to use function_view as
	callback type.
	(decode_compound_collector): Now a class with private fields.
	(decode_compound_collector::release_symbols): New method.
	(collect_one_symbol): Rename to...
	(decode_compound_collector::operator()): ... this and adjust.
	(lookup_prefix_sym): decode_compound_collector construction bits
	move to decode_compound_collector ctor.  Pass the
	decode_compound_collector object directly as callback.  Remove
	cleanups and use decode_compound_collector::release_symbols
	instead.
	(symtab_collector): Now a class with private fields.
	(symtab_collector::release_symtabs): New method.
	(add_symtabs_to_list): Rename to...
	(symtab_collector::operator()): ... this and adjust.
	(collect_symtabs_from_filename): symtab_collector construction
	bits move to symtab_collector ctor.  Pass the symtab_collector
	object directly as callback.  Remove cleanups and use
	symtab_collector::release_symtabs instead.
	(collect_symbols): Delete.
	(add_matching_symbols_to_info): Use lambdas.
	* macrocmd.c (print_macro_callback): Delete.
	(info_macro_command): Use a lambda.
	(info_macros_command): Pass print_macro_definition as callable
	directly.
	(print_one_macro): Remove 'ignore' parameter.
	(macro_list_command): Adjust.
	* macrotab.c (macro_for_each_data::fn): Now a function_view.
	(macro_for_each_data::user_data): Delete field.
	(foreach_macro): Adjust to call the function_view.
	(macro_for_each): Adjust to use function_view as callback type.
	(foreach_macro_in_scope): Adjust to call the function_view.
	(macro_for_each_in_scope): Adjust to use function_view as callback
	type.
	* macrotab.h: Include "common/function-view.h".
	(macro_callback_fn): Declare a prototype instead of a pointer.
	Remove "user_data" parameter.
	(macro_for_each, macro_for_each_in_scope): Adjust to use
	function_view as callback type.
	* psymtab.c (partial_map_expand_apply)
	(psym_map_symtabs_matching_filename, recursively_search_psymtabs):
	Adjust to use function_view as callback type and to return bool.
	(psym_expand_symtabs_matching): Adjust to use function_view as
	callback types.
	* symfile-debug.c (debug_qf_map_symtabs_matching_filename): Adjust
	to use function_view as callback type and to return bool.
	(debug_qf_expand_symtabs_matching): Adjust to use function_view as
	callback types.
	* symfile.c (expand_symtabs_matching): Adjust to use function_view
	as callback types.
	* symfile.h: Include "common/function-view.h".
	(expand_symtabs_file_matcher_ftype)
	(expand_symtabs_symbol_matcher_ftype)
	(expand_symtabs_exp_notify_ftype): Remove "data" parameter and
	return bool.
	(quick_symbol_functions::map_symtabs_matching_filename)
	(quick_symbol_functions::expand_symtabs_matching): Adjust to use
	function_view as callback type and return bool.
	(expand_symtabs_matching): Adjust to use function_view as callback
	type.
	(maintenance_expand_name_matcher)
	(maintenance_expand_file_matcher): Delete.
	(maintenance_expand_symtabs): Use lambdas.
	* symtab.c (iterate_over_some_symtabs): Adjust to use
	function_view as callback types and return bool.
	(iterate_over_symtabs): Likewise.  Use unique_xmalloc_ptr instead
	of a cleanup.
	(lookup_symtab_callback): Delete.
	(lookup_symtab): Use a lambda.
	(iterate_over_symbols): Adjust to use function_view as callback
	type.
	(struct search_symbols_data, search_symbols_file_matches)
	(search_symbols_name_matches): Delete.
	(search_symbols): Use a pair of lambdas.
	(struct add_name_data, add_macro_name, symbol_completion_matcher)
	(symtab_expansion_callback): Delete.
	(default_make_symbol_completion_list_break_on_1): Use lambdas.
	* symtab.h: Include "common/function-view.h".
	(iterate_over_some_symtabs): Adjust to use function_view as
	callback type and return bool.
	(iterate_over_symtabs): Adjust to use function_view as callback
	type.
	(symbol_found_callback_ftype): Remove 'data' parameter and return
	bool.
	(iterate_over_symbols): Adjust to use function_view as callback
	type.
This commit is contained in:
Pedro Alves
2017-02-22 14:43:35 +00:00
parent 07e253aa3b
commit 14bc53a814
16 changed files with 579 additions and 688 deletions

View File

@ -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,14 @@ 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 +1029,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 +2793,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);
}
/* Releases ownership of the collected symbols and returns them. */
VEC (symbolp) *release_symbols ()
{
VEC (symbolp) *res = m_symbols;
m_symbols = NULL;
return res;
}
/* 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;
};
/* A callback for iterate_over_symbols that is used by
lookup_prefix_sym to collect type symbols. */
static int
collect_one_symbol (struct symbol *sym, void *d)
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 +2867,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 +2884,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 +3095,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);
}
/* Callable as a symbol_found_callback_ftype callback. */
bool operator () (symtab *sym);
/* 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;
};
/* Callback for iterate_over_symtabs. */
static int
add_symtabs_to_list (struct symtab *symtab, void *d)
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 +3156,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 +3550,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 +3817,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 +3829,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