aboutsummaryrefslogtreecommitdiff
path: root/gdb/mi
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-10-04 17:59:51 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2019-12-04 10:24:59 +0000
commit293b38d60f15422cf7e3d3ba06fdbc5cc90aee67 (patch)
treed95a350a906bba209d71ad579864f79de84ed48e /gdb/mi
parent0ba59a29407a9d24559a653ce0401a26d9a37aaa (diff)
downloadgdb-293b38d60f15422cf7e3d3ba06fdbc5cc90aee67.zip
gdb-293b38d60f15422cf7e3d3ba06fdbc5cc90aee67.tar.gz
gdb-293b38d60f15422cf7e3d3ba06fdbc5cc90aee67.tar.bz2
gdb/mi: Add -symbol-info-module-{variables,functions}
Two new MI command -symbol-info-module-variables and -symbol-info-module-functions, which are the equivalent of the CLI command 'info module variables' and 'info module functions'. These return information about functions and variables within Fortran modules. gdb/ChangeLog: * mi/mi-cmds.c (mi_cmds): Add -symbol-info-module-functions and -symbol-info-module-variables entries. * mi/mi-cmds.h (mi_cmd_symbol_info_module_functions): Declare. (mi_cmd_symbol_info_module_variables): Declare. * mi/mi-symbol-cmds.c (module_symbol_search_iterator): New typedef. (output_module_symbols_in_single_module_and_file): New function. (output_module_symbols_in_single_module): New function. (mi_info_module_functions_or_variables): New function. (mi_cmd_symbol_info_module_functions): New function. (mi_cmd_symbol_info_module_variables): New function. * NEWS: Mention new MI command. gdb/doc/ChangeLog: * doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command -symbol-info-module-functions and -symbol-info-module-variables. gdb/testsuite/ChangeLog: * gdb.mi/mi-fortran-modules.exp: Add additional tests for -symbol-info-module-functions and -symbol-info-module-variables. Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Diffstat (limited to 'gdb/mi')
-rw-r--r--gdb/mi/mi-cmds.c4
-rw-r--r--gdb/mi/mi-cmds.h2
-rw-r--r--gdb/mi/mi-symbol-cmds.c155
3 files changed, 161 insertions, 0 deletions
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 85c15ec..991fb4b 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -155,6 +155,10 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_MI ("symbol-info-variables", mi_cmd_symbol_info_variables),
DEF_MI_CMD_MI ("symbol-info-types", mi_cmd_symbol_info_types),
DEF_MI_CMD_MI ("symbol-info-modules", mi_cmd_symbol_info_modules),
+ DEF_MI_CMD_MI ("symbol-info-module-functions",
+ mi_cmd_symbol_info_module_functions),
+ DEF_MI_CMD_MI ("symbol-info-module-variables",
+ mi_cmd_symbol_info_module_variables),
DEF_MI_CMD_CLI ("target-attach", "attach", 1),
DEF_MI_CMD_MI ("target-detach", mi_cmd_target_detach),
DEF_MI_CMD_CLI ("target-disconnect", "disconnect", 0),
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 30de780..faeb36b 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -95,6 +95,8 @@ extern mi_cmd_argv_ftype mi_cmd_stack_list_variables;
extern mi_cmd_argv_ftype mi_cmd_stack_select_frame;
extern mi_cmd_argv_ftype mi_cmd_symbol_list_lines;
extern mi_cmd_argv_ftype mi_cmd_symbol_info_functions;
+extern mi_cmd_argv_ftype mi_cmd_symbol_info_module_functions;
+extern mi_cmd_argv_ftype mi_cmd_symbol_info_module_variables;
extern mi_cmd_argv_ftype mi_cmd_symbol_info_modules;
extern mi_cmd_argv_ftype mi_cmd_symbol_info_types;
extern mi_cmd_argv_ftype mi_cmd_symbol_info_variables;
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 10dd273..2bebd11 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,143 @@ mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc)
mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms);
}
+/* Type for an iterator over a vector of module_symbol_search results. */
+typedef std::vector<module_symbol_search>::const_iterator
+ module_symbol_search_iterator;
+
+/* Helper for mi_info_module_functions_or_variables. Display the results
+ from ITER up to END or until we find a symbol that is in a different
+ module, or in a different symtab than the first symbol we print. Update
+ and return the new value for ITER. */
+static module_symbol_search_iterator
+output_module_symbols_in_single_module_and_file
+ (struct ui_out *uiout, module_symbol_search_iterator iter,
+ const module_symbol_search_iterator end, enum search_domain kind)
+{
+ /* The symbol for the module in which the first result resides. */
+ const symbol *first_module_symbol = iter->first.symbol;
+
+ /* The symbol for the first result, and the symtab in which it resides. */
+ const symbol *first_result_symbol = iter->second.symbol;
+ symtab *first_symbtab = symbol_symtab (first_result_symbol);
+
+ /* Formatted output. */
+ ui_out_emit_tuple current_file (uiout, nullptr);
+ uiout->field_string ("filename",
+ symtab_to_filename_for_display (first_symbtab));
+ uiout->field_string ("fullname", symtab_to_fullname (first_symbtab));
+ ui_out_emit_list item_list (uiout, "symbols");
+
+ /* Repeatedly output result symbols until either we run out of symbols,
+ we change module, or we change symtab. */
+ for (; (iter != end
+ && first_module_symbol == iter->first.symbol
+ && first_symbtab == symbol_symtab (iter->second.symbol));
+ ++iter)
+ output_debug_symbol (uiout, kind, iter->second.symbol,
+ iter->second.block);
+
+ return iter;
+}
+
+/* Helper for mi_info_module_functions_or_variables. Display the results
+ from ITER up to END or until we find a symbol that is in a different
+ module than the first symbol we print. Update and return the new value
+ for ITER. */
+static module_symbol_search_iterator
+output_module_symbols_in_single_module
+ (struct ui_out *uiout, module_symbol_search_iterator iter,
+ const module_symbol_search_iterator end, enum search_domain kind)
+{
+ gdb_assert (iter->first.symbol != nullptr);
+ gdb_assert (iter->second.symbol != nullptr);
+
+ /* The symbol for the module in which the first result resides. */
+ const symbol *first_module_symbol = iter->first.symbol;
+
+ /* Create output formatting. */
+ ui_out_emit_tuple module_tuple (uiout, nullptr);
+ uiout->field_string ("module", first_module_symbol->print_name ());
+ ui_out_emit_list files_list (uiout, "files");
+
+ /* The results are sorted so that symbols within the same file are next
+ to each other in the list. Calling the output function once will
+ print all results within a single file. We keep calling the output
+ function until we change module. */
+ while (iter != end && first_module_symbol == iter->first.symbol)
+ iter = output_module_symbols_in_single_module_and_file (uiout, iter,
+ end, kind);
+ return iter;
+}
+
+/* Core of -symbol-info-module-functions and -symbol-info-module-variables.
+ KIND indicates what we are searching for, and ARGV and ARGC are the
+ command line options passed to the MI command. */
+
+static void
+mi_info_module_functions_or_variables (enum search_domain kind,
+ char **argv, int argc)
+{
+ const char *module_regexp = nullptr;
+ const char *regexp = nullptr;
+ const char *type_regexp = nullptr;
+
+ /* Process the command line options. */
+
+ enum opt
+ {
+ MODULE_REGEXP_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT
+ };
+ static const struct mi_opt opts[] =
+ {
+ {"-module", MODULE_REGEXP_OPT, 1},
+ {"-type", TYPE_REGEXP_OPT, 1},
+ {"-name", NAME_REGEXP_OPT, 1},
+ { 0, 0, 0 }
+ };
+
+ int oind = 0;
+ char *oarg = nullptr;
+
+ while (1)
+ {
+ const char *cmd_string
+ = ((kind == FUNCTIONS_DOMAIN)
+ ? "-symbol-info-module-functions"
+ : "-symbol-info-module-variables");
+ int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case MODULE_REGEXP_OPT:
+ module_regexp = oarg;
+ break;
+ case TYPE_REGEXP_OPT:
+ type_regexp = oarg;
+ break;
+ case NAME_REGEXP_OPT:
+ regexp = oarg;
+ break;
+ }
+ }
+
+ std::vector<module_symbol_search> module_symbols
+ = search_module_symbols (module_regexp, regexp, type_regexp, kind);
+
+ struct ui_out *uiout = current_uiout;
+ ui_out_emit_list all_matching_symbols (uiout, "symbols");
+
+ /* The results in the module_symbols list are ordered so symbols in the
+ same module are next to each other. Repeatedly call the output
+ function to print sequences of symbols that are in the same module
+ until we have no symbols left to print. */
+ module_symbol_search_iterator iter = module_symbols.begin ();
+ const module_symbol_search_iterator end = module_symbols.end ();
+ while (iter != end)
+ iter = output_module_symbols_in_single_module (uiout, iter, end, kind);
+}
+
/* Implement -symbol-info-functions command. */
void
@@ -224,6 +361,24 @@ mi_cmd_symbol_info_functions (const char *command, char **argv, int argc)
mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
}
+/* Implement -symbol-info-module-functions command. */
+
+void
+mi_cmd_symbol_info_module_functions (const char *command, char **argv,
+ int argc)
+{
+ mi_info_module_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
+}
+
+/* Implement -symbol-info-module-variables command. */
+
+void
+mi_cmd_symbol_info_module_variables (const char *command, char **argv,
+ int argc)
+{
+ mi_info_module_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
+}
+
/* Implement -symbol-inf-modules command. */
void