[review,v8] gdb/mi: Add -symbol-info-module-{variables,functions}

Message ID 20191127141906.889E020AF6@gnutoolchain-gerrit.osci.io
State New, archived
Headers

Commit Message

Simon Marchi (Code Review) Nov. 27, 2019, 2:19 p.m. UTC
  Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................

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
	(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
---
M gdb/ChangeLog
M gdb/NEWS
M gdb/doc/ChangeLog
M gdb/doc/gdb.texinfo
M gdb/mi/mi-cmds.c
M gdb/mi/mi-cmds.h
M gdb/mi/mi-symbol-cmds.c
M gdb/testsuite/ChangeLog
M gdb/testsuite/gdb.mi/mi-fortran-modules.exp
9 files changed, 352 insertions(+), 0 deletions(-)
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6544661..718d340 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@ 
 2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
 
+	* 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
+	(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.
+
+2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
+
 	* mi/mi-cmds.c (mi_cmds): Add 'symbol-info-modules' entry.
 	* mi/mi-cmds.h (mi_cmd_symbol_info_modules): Declare.
 	* mi/mi-symbol-cmds.c (mi_cmd_symbol_info_modules): New function.
diff --git a/gdb/NEWS b/gdb/NEWS
index cf8c41c..d31a05c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -373,6 +373,10 @@ 
 -symbol-info-modules, this is the MI equivalent of the CLI 'info
   modules' command.
 
+-symbol-info-module-functions and -symbol-info-module-variables.
+  These commands are the MI equivalent of the CLI commands 'info
+  module functions' and 'info module variables'.
+
 * Other MI changes
 
  ** The default version of the MI interpreter is now 3 (-i=mi3).
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 2889538..54b65ef 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,6 +1,11 @@ 
 2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
+	-symbol-info-module-functions and -symbol-info-module-variables.
+
+2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
 	-symbol-info-modules.
 
 2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 478c95b..e04aac9 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -33995,6 +33995,148 @@ 
 @end group
 @end smallexample
 
+@subheading The @code{-symbol-info-module-functions} Command
+@findex -symbol-info-module-functions
+@anchor{-symbol-info-module-functions}
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-module-functions [--module @var{module_regexp}]
+                               [--name @var{name_regexp}]
+                               [--type @var{type_regexp}]
+@end smallexample
+
+@noindent
+Return a list containing the names of all known functions within all
+know Fortran modules.  The functions are grouped by source file and
+containing module, and shown with the line number on which each
+function is defined.
+
+The option @code{--module} only returns results for modules matching
+@var{module_regexp}.  The option @code{--name} only returns functions
+whose name matches @var{name_regexp}, and @code{--type} only returns
+functions whose type matches @var{type_regexp}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info module functions}.
+
+@subsubheading Example
+
+@smallexample
+@group
+(gdb)
+-symbol-info-module-functions
+^done,symbols=
+  [@{module="mod1",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            symbols=[@{line="21",name="mod1::check_all",type="void (void)",
+                      description="void mod1::check_all(void);"@}]@}]@},
+    @{module="mod2",
+     files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+             fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+             symbols=[@{line="30",name="mod2::check_var_i",type="void (void)",
+                       description="void mod2::check_var_i(void);"@}]@}]@},
+    @{module="mod3",
+     files=[@{filename="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             fullname="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             symbols=[@{line="21",name="mod3::check_all",type="void (void)",
+                       description="void mod3::check_all(void);"@},
+                      @{line="27",name="mod3::check_mod2",type="void (void)",
+                       description="void mod3::check_mod2(void);"@}]@}]@},
+    @{module="modmany",
+     files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             symbols=[@{line="35",name="modmany::check_some",type="void (void)",
+                       description="void modmany::check_some(void);"@}]@}]@},
+    @{module="moduse",
+     files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+             symbols=[@{line="44",name="moduse::check_all",type="void (void)",
+                       description="void moduse::check_all(void);"@},
+                      @{line="49",name="moduse::check_var_x",type="void (void)",
+                       description="void moduse::check_var_x(void);"@}]@}]@}]
+@end group
+@end smallexample
+
+@subheading The @code{-symbol-info-module-variables} Command
+@findex -symbol-info-module-variables
+@anchor{-symbol-info-module-variables}
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-module-variables [--module @var{module_regexp}]
+                               [--name @var{name_regexp}]
+                               [--type @var{type_regexp}]
+@end smallexample
+
+@noindent
+Return a list containing the names of all known variables within all
+know Fortran modules.  The variables are grouped by source file and
+containing module, and shown with the line number on which each
+variable is defined.
+
+The option @code{--module} only returns results for modules matching
+@var{module_regexp}.  The option @code{--name} only returns variables
+whose name matches @var{name_regexp}, and @code{--type} only returns
+variables whose type matches @var{type_regexp}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info module variables}.
+
+@subsubheading Example
+
+@smallexample
+@group
+(gdb)
+-symbol-info-module-variables
+^done,symbols=
+  [@{module="mod1",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            symbols=[@{line="18",name="mod1::var_const",type="integer(kind=4)",
+                      description="integer(kind=4) mod1::var_const;"@},
+                     @{line="17",name="mod1::var_i",type="integer(kind=4)",
+                      description="integer(kind=4) mod1::var_i;"@}]@}]@},
+   @{module="mod2",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90",
+            symbols=[@{line="28",name="mod2::var_i",type="integer(kind=4)",
+                      description="integer(kind=4) mod2::var_i;"@}]@}]@},
+   @{module="mod3",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            symbols=[@{line="18",name="mod3::mod1",type="integer(kind=4)",
+                      description="integer(kind=4) mod3::mod1;"@},
+                     @{line="17",name="mod3::mod2",type="integer(kind=4)",
+                      description="integer(kind=4) mod3::mod2;"@},
+                     @{line="19",name="mod3::var_i",type="integer(kind=4)",
+                      description="integer(kind=4) mod3::var_i;"@}]@}]@},
+   @{module="modmany",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            symbols=[@{line="33",name="modmany::var_a",type="integer(kind=4)",
+                      description="integer(kind=4) modmany::var_a;"@},
+                     @{line="33",name="modmany::var_b",type="integer(kind=4)",
+                      description="integer(kind=4) modmany::var_b;"@},
+                     @{line="33",name="modmany::var_c",type="integer(kind=4)",
+                      description="integer(kind=4) modmany::var_c;"@},
+                     @{line="33",name="modmany::var_i",type="integer(kind=4)",
+                      description="integer(kind=4) modmany::var_i;"@}]@}]@},
+   @{module="moduse",
+    files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90",
+            symbols=[@{line="42",name="moduse::var_x",type="integer(kind=4)",
+                      description="integer(kind=4) moduse::var_x;"@},
+                     @{line="42",name="moduse::var_y",type="integer(kind=4)",
+                      description="integer(kind=4) moduse::var_y;"@}]@}]@}]
+@end group
+@end smallexample
+
 @subheading The @code{-symbol-info-modules} Command
 @findex -symbol-info-modules
 @anchor{-symbol-info-modules}
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 @@ 
   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_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..8133239 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,141 @@ 
   mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms);
 }
 
+/* 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 auto
+output_module_symbols_in_single_module_and_file (struct ui_out *uiout,
+						 auto iter,
+						 auto 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 auto
+output_module_symbols_in_single_module (struct ui_out *uiout,
+					auto iter,
+					auto 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.  */
+  auto iter = module_symbols.begin ();
+  auto 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 +359,24 @@ 
   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
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 93e94f8..115a13f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@ 
 2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
 
+	* gdb.mi/mi-fortran-modules.exp: Add additional tests for
+	-symbol-info-module-functions and -symbol-info-module-variables.
+
+2019-11-27  Andrew Burgess  <andrew.burgess@embecosm.com>
+
 	* gdb.mi/mi-fortran-modules-2.f90: New file.
 	* gdb.mi/mi-fortran-modules.exp: New file.
 	* gdb.mi/mi-fortran-modules.f90: New file.
diff --git a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
index 640bb12..12a81a6 100644
--- a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
+++ b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
@@ -45,7 +45,30 @@ 
     "103\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"41\",name=\"moduse\"\}\\\]\}\\\]\}" \
     "-symbol-info-modules --name moduse"
 
+mi_gdb_test "104-symbol-info-module-functions" \
+    [join \
+     [list \
+      "104\\^done,symbols=\\\[\{module=\"mod1\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"mod1::check_all\",type=\"void \\(void\\)\",description=\"void mod1::check_all\\(void\\);\"\}\\\]\}\\\]\},\{module=\"mod2\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"30\",name=\"mod2::check_var_i\",type=\"void \\(void\\)\",description=\"void mod2::check_var_i\\(void\\);\"\}\\\]\}\\\]\},\{module=\"mod3\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"21\",name=\"mod3::check_all\",type=\"void \\(void\\)\",description=\"void mod3::check_all\\(void\\);\"\},\{line=\"27\",name=\"mod3::check_mod2\",type=\"void \\(void\\)\",description=\"void mod3::check_mod2\\(void\\);\"\}\\\]\}\\\]\}," \
+	  "\{module=\"modmany\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"35\",name=\"modmany::check_some\",type=\"void \\(void\\)\",description=\"void modmany::check_some\\(void\\);\"\}\\\]\}\\\]\},\{module=\"moduse\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"44\",name=\"moduse::check_all\",type=\"void \\(void\\)\",description=\"void moduse::check_all\\(void\\);\"\},\{line=\"49\",name=\"moduse::check_var_x\",type=\"void \\(void\\)\",description=\"void moduse::check_var_x\\(void\\);\"\}\\\]\}\\\]\}\\\]" ] "" ] \
+    "-symbol-info-module-functions"
 
+mi_gdb_test "105-symbol-info-module-functions --name _all" \
+    "105\\^done,symbols=\\\[\{module=\"mod1\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"mod1::check_all\",type=\"void \\(void\\)\",description=\"void mod1::check_all\\(void\\);\"\}\\\]\}\\\]\},\{module=\"mod3\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"21\",name=\"mod3::check_all\",type=\"void \\(void\\)\",description=\"void mod3::check_all\\(void\\);\"\}\\\]\}\\\]\},\{module=\"moduse\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"44\",name=\"moduse::check_all\",type=\"void \\(void\\)\",description=\"void moduse::check_all\\(void\\);\"\}\\\]\}\\\]\}\\\]" \
+    "-symbol-info-module-functions --name _all"
+
+mi_gdb_test "106-symbol-info-module-functions --module mod\[123\]" \
+    "106\\^done,symbols=\\\[\{module=\"mod1\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"mod1::check_all\",type=\"void \\(void\\)\",description=\"void mod1::check_all\\(void\\);\"\}\\\]\}\\\]\},\{module=\"mod2\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"30\",name=\"mod2::check_var_i\",type=\"void \\(void\\)\",description=\"void mod2::check_var_i\\(void\\);\"\}\\\]\}\\\]\},\{module=\"mod3\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"21\",name=\"mod3::check_all\",type=\"void \\(void\\)\",description=\"void mod3::check_all\\(void\\);\"\},\{line=\"27\",name=\"mod3::check_mod2\",type=\"void \\(void\\)\",description=\"void mod3::check_mod2\\(void\\);\"\}\\\]\}\\\]\}\\\]" \
+    "-symbol-info-module-functions --module mod\[123\]"
+
+set int4 [fortran_int4]
+
+mi_gdb_test "107-symbol-info-module-variables" \
+    [join \
+     [list \
+      "107\\^done,symbols=\\\[\{module=\"mod1\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"18\",name=\"mod1::var_const\",type=\"$int4\",description=\"$int4 mod1::var_const;\"\},\{line=\"17\",name=\"mod1::var_i\",type=\"$int4\",description=\"$int4 mod1::var_i;\"\}\\\]\}\\\]\},\{module=\"mod2\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"28\",name=\"mod2::var_i\",type=\"$int4\",description=\"$int4 mod2::var_i;\"\}\\\]\}\\\]\}," \
+	  "\{module=\"mod3\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"18\",name=\"mod3::mod1\",type=\"$int4\",description=\"$int4 mod3::mod1;\"\},\{line=\"17\",name=\"mod3::mod2\",type=\"$int4\",description=\"$int4 mod3::mod2;\"\},\{line=\"19\",name=\"mod3::var_i\",type=\"$int4\",description=\"$int4 mod3::var_i;\"\}\\\]\}\\\]\},\{module=\"modmany\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"33\",name=\"modmany::var_a\",type=\"$int4\",description=\"$int4 modmany::var_a;\"\}," \
+	  "\{line=\"33\",name=\"modmany::var_b\",type=\"$int4\",description=\"$int4 modmany::var_b;\"\},\{line=\"33\",name=\"modmany::var_c\",type=\"$int4\",description=\"$int4 modmany::var_c;\"\},\{line=\"33\",name=\"modmany::var_i\",type=\"$int4\",description=\"$int4 modmany::var_i;\"\}\\\]\}\\\]\},\{module=\"moduse\",files=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"42\",name=\"moduse::var_x\",type=\"$int4\",description=\"$int4 moduse::var_x;\"\},\{line=\"42\",name=\"moduse::var_y\",type=\"$int4\",description=\"$int4 moduse::var_y;\"\}\\\]\}\\\]\}\\\]" ] "" ] \
+    "-symbol-info-module-variables"