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

Message ID 20191126232549.6233E28173@gnutoolchain-gerrit.osci.io
State New, archived
Headers

Commit Message

Simon Marchi (Code Review) Nov. 26, 2019, 11:25 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 (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, 313 insertions(+), 0 deletions(-)
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cd8fb13..4df7cb8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@ 
 2019-11-26  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 (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-26  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 5f5337e..aa70c5d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -366,6 +366,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 b5db34d..7d7e265 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,6 +1,11 @@ 
 2019-11-26  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-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
 	-symbol-info-modules.
 
 2019-11-26  Andrew Burgess  <andrew.burgess@embecosm.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 2cf0293..ee6c95f 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 ac94414..4d94dc0 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,104 @@ 
   mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms);
 }
 
+/* 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");
+
+  for (int i = 0; i < module_symbols.size (); )
+    {
+      gdb_assert (module_symbols[i].second.symbol != nullptr);
+      const symbol *mod_sym = module_symbols[i].first.symbol;
+      const symbol *first_mod_sym = mod_sym;
+
+      ui_out_emit_tuple module_tuple (uiout, nullptr);
+      uiout->field_string ("module", mod_sym->print_name ());
+
+      for (; (i < module_symbols.size ()
+	      && first_mod_sym == module_symbols[i].first.symbol);)
+	{
+	  ui_out_emit_list files_list (uiout, "files");
+
+	  for (; (i < module_symbols.size ()
+		  && first_mod_sym == module_symbols[i].first.symbol);)
+	    {
+	      ui_out_emit_tuple current_file (uiout, nullptr);
+	      const symbol_search &q = module_symbols[i].second;
+	      struct symtab *s = symbol_symtab (q.symbol);
+	      uiout->field_string ("filename",
+				   symtab_to_filename_for_display (s));
+	      uiout->field_string ("fullname", symtab_to_fullname (s));
+	      ui_out_emit_list item_list (uiout, "symbols");
+	      const symtab *last_symtab = symbol_symtab (q.symbol);
+
+	      for (; (i < module_symbols.size ()
+		      && (last_symtab
+			  == symbol_symtab (module_symbols[i].second.symbol))
+		      && first_mod_sym == module_symbols[i].first.symbol);
+		   ++i)
+		{
+		  const symbol_search &tmp = module_symbols[i].second;
+		  output_debug_symbol (uiout, kind, tmp.symbol, tmp.block);
+		}
+	    }
+	}
+    }
+}
+
 /* Implement -symbol-info-functions command.  */
 
 void
@@ -224,6 +322,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 b8559ca..7121ad4 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@ 
 2019-11-26  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-26  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"