public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [review v2] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
@ 2019-11-01  1:28 ` Andrew Burgess (Code Review)
  2019-11-22 16:42 ` [review v4] " Andrew Burgess (Code Review)
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-11-01  1:28 UTC (permalink / raw)
  To: gdb-patches

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, 315 insertions(+), 1 deletion(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 11820e7..b11ceda 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
 2019-11-01  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-01  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 986d73b..5ce5a34 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -351,6 +351,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 c5d9e08..2901705 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,6 +1,11 @@
 2019-11-01  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-01  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
 	-symbol-info-modules.
 
 2019-11-01  Andrew Burgess  <andrew.burgess@embecosm.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7444f90..6219699 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -33960,6 +33960,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 0cf2613..0b14cb2 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -312,6 +312,106 @@
   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");
+  gdb::optional<ui_out_emit_tuple> module_tuple;
+  gdb::optional<ui_out_emit_list> files_list;
+  gdb::optional<ui_out_emit_tuple> current_file;
+  gdb::optional<ui_out_emit_list> item_list;
+
+  const symtab *last_symtab = nullptr;
+  const symbol *last_module_symbol = nullptr;
+  for (const module_symbol_search &ms : module_symbols)
+    {
+      const symbol_search &p = ms.first;
+      const symbol_search &q = ms.second;
+
+      gdb_assert (q.symbol != nullptr);
+
+      if (last_module_symbol != p.symbol)
+	{
+	  item_list.reset ();
+	  current_file.reset ();
+	  files_list.reset ();
+
+	  module_tuple.emplace (uiout, nullptr);
+	  uiout->field_string ("module", SYMBOL_PRINT_NAME (p.symbol));
+	  last_module_symbol = p.symbol;
+	  last_symtab = nullptr;
+	  files_list.emplace (uiout, "files");
+	}
+
+      struct symtab *s = symbol_symtab (q.symbol);
+      if (last_symtab != s)
+	{
+	  item_list.reset ();
+	  current_file.emplace (uiout, nullptr);
+	  uiout->field_string ("filename",
+			       symtab_to_filename_for_display (s));
+	  uiout->field_string ("fullname", symtab_to_fullname (s));
+	  item_list.emplace (uiout, "symbols");
+	  last_symtab = s;
+	}
+
+      mi_info_one_symbol_details (kind, q.symbol, q.block);
+    }
+}
+
 /* Implement -symbol-info-functions command.  */
 
 void
@@ -320,6 +420,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
@@ -401,4 +519,3 @@
 {
   mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
 }
-
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 72b6aee..47445ea 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2019-11-01  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-01  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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 2
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v4] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
  2019-11-01  1:28 ` [review v2] gdb/mi: Add -symbol-info-module-{variables,functions} Andrew Burgess (Code Review)
@ 2019-11-22 16:42 ` Andrew Burgess (Code Review)
  2019-11-22 19:28   ` Eli Zaretskii
  2019-11-26 23:26 ` [review v6] " Andrew Burgess (Code Review)
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-11-22 16:42 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker

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, 315 insertions(+), 1 deletion(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b83d493..e67635f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
 2019-11-22  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-22  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 ddc74f1..ee64e87 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -360,6 +360,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 c25f6d7..ae310ea 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,6 +1,11 @@
 2019-11-22  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-22  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
 	-symbol-info-modules.
 
 2019-11-22  Andrew Burgess  <andrew.burgess@embecosm.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 46001cc..fb32528 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -33982,6 +33982,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 5f7b165..7072d95 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -314,6 +314,106 @@
   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");
+  gdb::optional<ui_out_emit_tuple> module_tuple;
+  gdb::optional<ui_out_emit_list> files_list;
+  gdb::optional<ui_out_emit_tuple> current_file;
+  gdb::optional<ui_out_emit_list> item_list;
+
+  const symtab *last_symtab = nullptr;
+  const symbol *last_module_symbol = nullptr;
+  for (const module_symbol_search &ms : module_symbols)
+    {
+      const symbol_search &p = ms.first;
+      const symbol_search &q = ms.second;
+
+      gdb_assert (q.symbol != nullptr);
+
+      if (last_module_symbol != p.symbol)
+	{
+	  item_list.reset ();
+	  current_file.reset ();
+	  files_list.reset ();
+
+	  module_tuple.emplace (uiout, nullptr);
+	  uiout->field_string ("module", SYMBOL_PRINT_NAME (p.symbol));
+	  last_module_symbol = p.symbol;
+	  last_symtab = nullptr;
+	  files_list.emplace (uiout, "files");
+	}
+
+      struct symtab *s = symbol_symtab (q.symbol);
+      if (last_symtab != s)
+	{
+	  item_list.reset ();
+	  current_file.emplace (uiout, nullptr);
+	  uiout->field_string ("filename",
+			       symtab_to_filename_for_display (s));
+	  uiout->field_string ("fullname", symtab_to_fullname (s));
+	  item_list.emplace (uiout, "symbols");
+	  last_symtab = s;
+	}
+
+      mi_info_one_symbol_details (kind, q.symbol, q.block);
+    }
+}
+
 /* Implement -symbol-info-functions command.  */
 
 void
@@ -322,6 +422,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
@@ -403,4 +521,3 @@
 {
   mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
 }
-
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 19511f4..518d9cb 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2019-11-22  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-22  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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 4
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [review v4] gdb/mi: Add -symbol-info-module-{variables,functions}
  2019-11-22 16:42 ` [review v4] " Andrew Burgess (Code Review)
@ 2019-11-22 19:28   ` Eli Zaretskii
  0 siblings, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2019-11-22 19:28 UTC (permalink / raw)
  To: andrew.burgess, brobecker, gdb-patches

> Date: Fri, 22 Nov 2019 11:41:52 -0500
> From: "Andrew Burgess (Code Review)" <gerrit@gnutoolchain-gerrit.osci.io>
> Cc: Joel Brobecker <brobecker@adacore.com>
> 
> 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.

Any changes in the documentation parts since the previous version?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v6] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
  2019-11-01  1:28 ` [review v2] gdb/mi: Add -symbol-info-module-{variables,functions} Andrew Burgess (Code Review)
  2019-11-22 16:42 ` [review v4] " Andrew Burgess (Code Review)
@ 2019-11-26 23:26 ` Andrew Burgess (Code Review)
  2019-11-27  4:21 ` [review v7] " Simon Marchi (Code Review)
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-11-26 23:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker

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(-)



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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 6
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v7] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (2 preceding siblings ...)
  2019-11-26 23:26 ` [review v6] " Andrew Burgess (Code Review)
@ 2019-11-27  4:21 ` Simon Marchi (Code Review)
  2019-11-27 14:19 ` [review v8] " Andrew Burgess (Code Review)
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Simon Marchi (Code Review) @ 2019-11-27  4:21 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Joel Brobecker

Simon Marchi has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 7:

(2 comments)

| --- gdb/mi/mi-symbol-cmds.c
| +++ gdb/mi/mi-symbol-cmds.c
| @@ -219,0 +268,34 @@ mi_info_module_functions_or_variables (enum search_domain kind,
| +	}
| +    }
| +
| +  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 (); )

PS7, Line 277:

I would appreciate a few comments in this function, that explains what
each step does, at a high level.  Otherwise I'm not sure of what's the
intention, and therefore if the code what you intended it to do.

| +    {
| +      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);)

PS7, Line 292:

For example, this for loop is identical to the previous for loop.  I
find it a bit odd, but maybe that's intended?

| +	    {
| +	      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);

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 7
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Wed, 27 Nov 2019 04:21:26 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v8] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (3 preceding siblings ...)
  2019-11-27  4:21 ` [review v7] " Simon Marchi (Code Review)
@ 2019-11-27 14:19 ` Andrew Burgess (Code Review)
  2019-11-27 14:21 ` Andrew Burgess (Code Review)
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-11-27 14:19 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker, Simon Marchi

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(-)



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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 8
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v8] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (4 preceding siblings ...)
  2019-11-27 14:19 ` [review v8] " Andrew Burgess (Code Review)
@ 2019-11-27 14:21 ` Andrew Burgess (Code Review)
  2019-11-28 20:05 ` Simon Marchi (Code Review)
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-11-27 14:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi, Joel Brobecker

Andrew Burgess has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 8:

I split the output function into a few extra helpers, and added additional comments.  The extra loop you spotted was a mistake left over from development - it was harmless in the sense that it would break on the same condition as its more inner loop, but it added no value.

I think the new code is easier to follow.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 8
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Wed, 27 Nov 2019 14:21:18 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v8] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (5 preceding siblings ...)
  2019-11-27 14:21 ` Andrew Burgess (Code Review)
@ 2019-11-28 20:05 ` Simon Marchi (Code Review)
  2019-12-02 19:15 ` [review v9] " Andrew Burgess (Code Review)
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Simon Marchi (Code Review) @ 2019-11-28 20:05 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Joel Brobecker

Simon Marchi has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 8:

(1 comment)

| --- gdb/mi/mi-symbol-cmds.c
| +++ gdb/mi/mi-symbol-cmds.c
| @@ -219,0 +256,19 @@ /* 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);

PS8, Line 265:

Can't you use `iter->first` (throughout this patch)?

| +  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");

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 8
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Thu, 28 Nov 2019 20:05:21 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v9] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (6 preceding siblings ...)
  2019-11-28 20:05 ` Simon Marchi (Code Review)
@ 2019-12-02 19:15 ` Andrew Burgess (Code Review)
  2019-12-02 19:16 ` Andrew Burgess (Code Review)
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-12-02 19:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker, Simon Marchi

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(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1465c75..ff3d233 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2019-12-02  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* dwarf2read.c (read_tag_string_type): Read the fields required to
diff --git a/gdb/NEWS b/gdb/NEWS
index 0a04146..372a83a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -402,6 +402,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 6b6f28e..10e2207 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Tom Tromey  <tom@tromey.com>
 
 	* gdb.texinfo (TUI Configuration): Mention TUI border styles.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 198862a..6fb7e8a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34058,6 +34058,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..6334e39 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 a4d2556..7fa48e3 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/array-slices.exp: Add test for dynamic strings.
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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 9
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v9] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (7 preceding siblings ...)
  2019-12-02 19:15 ` [review v9] " Andrew Burgess (Code Review)
@ 2019-12-02 19:16 ` Andrew Burgess (Code Review)
  2019-12-02 23:44 ` [review v10] " Andrew Burgess (Code Review)
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-12-02 19:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi, Joel Brobecker

Andrew Burgess has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 9:

(1 comment)

| --- gdb/mi/mi-symbol-cmds.c
| +++ gdb/mi/mi-symbol-cmds.c
| @@ -219,0 +256,19 @@ /* 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);

PS8, Line 265:

Yes I can!  New patch uploaded.

| +  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");

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 9
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Mon, 02 Dec 2019 19:16:25 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v10] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (8 preceding siblings ...)
  2019-12-02 19:16 ` Andrew Burgess (Code Review)
@ 2019-12-02 23:44 ` Andrew Burgess (Code Review)
  2019-12-03  1:53 ` Simon Marchi (Code Review)
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-12-02 23:44 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker, Simon Marchi

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(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0c31ddd..ec49d95 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2019-12-02  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-12-02  Christian Biesinger  <cbiesinger@google.com>
 
 	* aix-thread.c (debug_aix_thread): Change type to bool.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0a04146..372a83a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -402,6 +402,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 6b6f28e..10e2207 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Tom Tromey  <tom@tromey.com>
 
 	* gdb.texinfo (TUI Configuration): Mention TUI border styles.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 198862a..6fb7e8a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34058,6 +34058,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..6334e39 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 a4d2556..7fa48e3 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/array-slices.exp: Add test for dynamic strings.
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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 10
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v10] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (9 preceding siblings ...)
  2019-12-02 23:44 ` [review v10] " Andrew Burgess (Code Review)
@ 2019-12-03  1:53 ` Simon Marchi (Code Review)
  2019-12-03  4:04 ` Simon Marchi (Code Review)
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Simon Marchi (Code Review) @ 2019-12-03  1:53 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Joel Brobecker

Simon Marchi has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 10: Code-Review+2

(1 comment)

| --- gdb/mi/mi-symbol-cmds.c
| +++ gdb/mi/mi-symbol-cmds.c
| @@ -219,0 +256,19 @@ /* 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);

PS8, Line 265:

Done

| +  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");

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 10
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-Comment-Date: Tue, 03 Dec 2019 01:53:30 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: Andrew Burgess <andrew.burgess@embecosm.com>
Comment-In-Reply-To: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v10] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (10 preceding siblings ...)
  2019-12-03  1:53 ` Simon Marchi (Code Review)
@ 2019-12-03  4:04 ` Simon Marchi (Code Review)
  2019-12-03 10:24 ` [review v11] " Andrew Burgess (Code Review)
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Simon Marchi (Code Review) @ 2019-12-03  4:04 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Joel Brobecker

Simon Marchi has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 10: -Code-Review

Actually, when I try to build (gcc 9.2.0), I get these errors:

 /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:225:8: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
   225 |        auto iter,
       |        ^~~~
 /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:226:8: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
   226 |        auto end,
       |        ^~~~
 /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:261:6: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
   261 |      auto iter,
       |      ^~~~
 /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:262:6: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
   262 |      auto end,
       |      ^~~~

You don't see this?  What do you compile with?


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 10
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-Comment-Date: Tue, 03 Dec 2019 04:03:56 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v11] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (11 preceding siblings ...)
  2019-12-03  4:04 ` Simon Marchi (Code Review)
@ 2019-12-03 10:24 ` Andrew Burgess (Code Review)
  2019-12-03 10:25 ` [review v10] " Andrew Burgess (Code Review)
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-12-03 10:24 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches; +Cc: Joel Brobecker

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
	(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
---
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, 355 insertions(+), 0 deletions(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0c31ddd..9b3df38 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2019-12-02  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
+	(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.
+
 2019-12-02  Christian Biesinger  <cbiesinger@google.com>
 
 	* aix-thread.c (debug_aix_thread): Change type to bool.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0a04146..372a83a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -402,6 +402,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 6b6f28e..10e2207 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Tom Tromey  <tom@tromey.com>
 
 	* gdb.texinfo (TUI Configuration): Mention TUI border styles.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 198862a..6fb7e8a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34058,6 +34058,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..2bebd11 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,143 @@
   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_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 a4d2556..7fa48e3 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-02  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/array-slices.exp: Add test for dynamic strings.
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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 11
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v10] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (12 preceding siblings ...)
  2019-12-03 10:24 ` [review v11] " Andrew Burgess (Code Review)
@ 2019-12-03 10:25 ` Andrew Burgess (Code Review)
  2019-12-03 16:38 ` [review v11] " Simon Marchi (Code Review)
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess (Code Review) @ 2019-12-03 10:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi, Joel Brobecker

Andrew Burgess has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 10:

> Patch Set 10: -Code-Review
> 
> Actually, when I try to build (gcc 9.2.0), I get these errors:
> 
>  /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:225:8: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
>    225 |        auto iter,
>        |        ^~~~
>  /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:226:8: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
>    226 |        auto end,
>        |        ^~~~
>  /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:261:6: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
>    261 |      auto iter,
>        |      ^~~~
>  /home/simark/src/binutils-gdb/gdb/mi/mi-symbol-cmds.c:262:6: error: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’ [-Werror]
>    262 |      auto end,
>        |      ^~~~
> 
> You don't see this?  What do you compile with?

Gcc 7.3.1 is what's installed on my machine by default.  If I switch to a 10.0 compiler then I can reproduce this failure.

I've updated the patch and will get a better default version of GCC setup.

Sorry for wasting your time with this mistake.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 10
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-Comment-Date: Tue, 03 Dec 2019 10:25:24 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [review v11] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (13 preceding siblings ...)
  2019-12-03 10:25 ` [review v10] " Andrew Burgess (Code Review)
@ 2019-12-03 16:38 ` Simon Marchi (Code Review)
  2019-12-04 10:49 ` [pushed] " Sourceware to Gerrit sync (Code Review)
  2019-12-04 10:49 ` Sourceware to Gerrit sync (Code Review)
  16 siblings, 0 replies; 18+ messages in thread
From: Simon Marchi (Code Review) @ 2019-12-03 16:38 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Joel Brobecker

Simon Marchi has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/268
......................................................................


Patch Set 11: Code-Review+2

> Gcc 7.3.1 is what's installed on my machine by default.  If I switch to a 10.0 compiler then I can reproduce this failure.
> 
> I've updated the patch and will get a better default version of GCC setup.
> 
> Sorry for wasting your time with this mistake.

No worries.  It would not be reasonable to ask everybody to test their patches with a bunch of different compilers.  Others or the CI can report the breakage if the patch builds with your gcc version, but not with an older or newer one.

Anyway, it builds now, LGTM.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 11
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-Comment-Date: Tue, 03 Dec 2019 16:38:21 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [pushed] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (14 preceding siblings ...)
  2019-12-03 16:38 ` [review v11] " Simon Marchi (Code Review)
@ 2019-12-04 10:49 ` Sourceware to Gerrit sync (Code Review)
  2019-12-04 10:49 ` Sourceware to Gerrit sync (Code Review)
  16 siblings, 0 replies; 18+ messages in thread
From: Sourceware to Gerrit sync (Code Review) @ 2019-12-04 10:49 UTC (permalink / raw)
  To: Andrew Burgess, Simon Marchi, gdb-patches; +Cc: Joel Brobecker

The original change was created by Andrew Burgess.

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
	(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
---
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, 355 insertions(+), 0 deletions(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d12bd1c..85607bb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2019-12-04  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
+	(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.
+
 2019-12-03  Christian Biesinger  <cbiesinger@google.com>
 
 	* bcache.c (hash): Remove.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0a04146..372a83a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -402,6 +402,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 6b6f28e..5b3eab7 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-04  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-12-01  Tom Tromey  <tom@tromey.com>
 
 	* gdb.texinfo (TUI Configuration): Mention TUI border styles.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 198862a..6fb7e8a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34058,6 +34058,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..2bebd11 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,143 @@
   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_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 a4d2556..9ed64d1 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-04  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/array-slices.exp: Add test for dynamic strings.
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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 12
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [pushed] gdb/mi: Add -symbol-info-module-{variables,functions}
       [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
                   ` (15 preceding siblings ...)
  2019-12-04 10:49 ` [pushed] " Sourceware to Gerrit sync (Code Review)
@ 2019-12-04 10:49 ` Sourceware to Gerrit sync (Code Review)
  16 siblings, 0 replies; 18+ messages in thread
From: Sourceware to Gerrit sync (Code Review) @ 2019-12-04 10:49 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches; +Cc: Simon Marchi, Joel Brobecker

Sourceware to Gerrit sync has submitted this change.

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
	(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
---
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, 355 insertions(+), 0 deletions(-)


diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d12bd1c..85607bb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2019-12-04  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
+	(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.
+
 2019-12-03  Christian Biesinger  <cbiesinger@google.com>
 
 	* bcache.c (hash): Remove.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0a04146..372a83a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -402,6 +402,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 6b6f28e..5b3eab7 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-04  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-12-01  Tom Tromey  <tom@tromey.com>
 
 	* gdb.texinfo (TUI Configuration): Mention TUI border styles.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 198862a..6fb7e8a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34058,6 +34058,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..2bebd11 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -216,6 +216,143 @@
   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_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 a4d2556..9ed64d1 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-04  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-12-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.fortran/array-slices.exp: Add test for dynamic strings.
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"
 
 
 

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ic96f12dd14bd7e34774c3cde008fec30a4055bfe
Gerrit-Change-Number: 268
Gerrit-PatchSet: 12
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-MessageType: merged

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2019-12-04 10:49 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <gerrit.1571909344000.Ic96f12dd14bd7e34774c3cde008fec30a4055bfe@gnutoolchain-gerrit.osci.io>
2019-11-01  1:28 ` [review v2] gdb/mi: Add -symbol-info-module-{variables,functions} Andrew Burgess (Code Review)
2019-11-22 16:42 ` [review v4] " Andrew Burgess (Code Review)
2019-11-22 19:28   ` Eli Zaretskii
2019-11-26 23:26 ` [review v6] " Andrew Burgess (Code Review)
2019-11-27  4:21 ` [review v7] " Simon Marchi (Code Review)
2019-11-27 14:19 ` [review v8] " Andrew Burgess (Code Review)
2019-11-27 14:21 ` Andrew Burgess (Code Review)
2019-11-28 20:05 ` Simon Marchi (Code Review)
2019-12-02 19:15 ` [review v9] " Andrew Burgess (Code Review)
2019-12-02 19:16 ` Andrew Burgess (Code Review)
2019-12-02 23:44 ` [review v10] " Andrew Burgess (Code Review)
2019-12-03  1:53 ` Simon Marchi (Code Review)
2019-12-03  4:04 ` Simon Marchi (Code Review)
2019-12-03 10:24 ` [review v11] " Andrew Burgess (Code Review)
2019-12-03 10:25 ` [review v10] " Andrew Burgess (Code Review)
2019-12-03 16:38 ` [review v11] " Simon Marchi (Code Review)
2019-12-04 10:49 ` [pushed] " Sourceware to Gerrit sync (Code Review)
2019-12-04 10:49 ` Sourceware to Gerrit sync (Code Review)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).