public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
  2019-10-03 11:29 ` [PATCHv2 2/4] gdb/fortran: Add test for module variables in 'info variables' output Andrew Burgess
  2019-10-03 11:29 ` [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command Andrew Burgess
@ 2019-10-03 11:29 ` Andrew Burgess
  2019-10-03 16:16   ` Eli Zaretskii
                     ` (2 more replies)
  2019-10-03 11:29 ` [PATCHv2 1/4] gdb/testsuite: Allow cc-with-tweaks board file to be used with Fortran Andrew Burgess
  2019-10-10 15:59 ` [PATCHv2 0/4] Fortran info types, info modules, info module Tom Tromey
  4 siblings, 3 replies; 13+ messages in thread
From: Andrew Burgess @ 2019-10-03 11:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This patch adds two new commands "info module functions" and "info
module variables".  These commands list all of the functions and
variables grouped by module and then by file.

For example:

  (gdb) info module functions
  All functions in all modules:

  Module "mod1":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  35:	void mod1::__copy_mod1_M1t1(Type m1t1, Type m1t1);
  25:	void mod1::sub_m1_a(integer(kind=4));
  31:	integer(kind=4) mod1::sub_m1_b(void);

  Module "mod2":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  41:	void mod2::sub_m2_a(integer(kind=4), logical(kind=4));
  49:	logical(kind=4) mod2::sub_m2_b(real(kind=4));

The new commands take set of flags that allow the output to be
filtered, the user can filter by variable/function name, type, or
containing module.

As GDB doesn't currently track the relationship between a module and
the variables or functions within it in the symbol table, so I filter
based on the module prefix in order to find the functions or variables
in each module.  What this makes clear is that a user could get this
same information using "info variables" and simply provide the prefix
themselves, for example:

  (gdb) info module functions -m mod1 _a
  All functions matching regular expression "_a",
  	in all modules matching regular expression "mod1":

  Module "mod1":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  25:	void mod1::sub_m1_a(integer(kind=4));

Is similar to:

  (gdb) info functions mod1::.*_a.*
  All functions matching regular expression "mod1::.*_a":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  25:	void mod1::sub_m1_a(integer(kind=4));

The benefits I see for a separate command are that the user doesn't
have to think (or know) about the module prefix format, nor worry
about building a proper regexp.  The user can also easily can across
modules without having to build complex regexps.

This patch is a new implementation of an idea originally worked on by
Mark O'Connor, Chris January, David Lecomber, and Xavier Oro from ARM.

gdb/ChangeLog:

	* symtab.c (info_module_cmdlist): New variable.
	(info_module_command): New function.
	(info_module_subcommand_helper): New function.
	(struct info_modules_var_func_options): New struct.
	(info_modules_var_func_options_defs): New variable.
	(make_info_modules_var_func_options_def_group): New function.
	(info_module_functions_command): New function.
	(info_module_variables_command): New function.
	(info_module_var_func_command_completer): New function.
	(_initialize_symtab): Register new 'info module functions' and
	'info module variables' commands.
	* NEWS: Mention new commands.

gdb/doc/ChangeLog:

	* gdb.texinfo (Symbols): Document new 'info module variables' and
	'info module functions' commands.

gdb/testsuite/ChangeLog:

	* gdb.fortran/info-modules.exp: Update expected results, and add
	additional tests for 'info module functinos', and 'info module
	variables'.
	* gdb.fortran/info-types.exp: Update expected results.
	* gdb.fortran/info-types.f90: Extend testcase with additional
	module variables and functions.
---
 gdb/ChangeLog                              |  15 ++
 gdb/NEWS                                   |  14 ++
 gdb/doc/ChangeLog                          |   5 +
 gdb/doc/gdb.texinfo                        |  22 ++
 gdb/symtab.c                               | 311 +++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                    |   9 +
 gdb/testsuite/gdb.fortran/info-modules.exp | 128 +++++++++++-
 gdb/testsuite/gdb.fortran/info-types.exp   |   6 +-
 gdb/testsuite/gdb.fortran/info-types.f90   |  31 +++
 9 files changed, 535 insertions(+), 6 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 2347c14d37d..d92ab2d6e20 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -142,6 +142,20 @@ info modules [-q] [REGEXP]
   Return a list of Fortran modules matching REGEXP, or all modules if
   no REGEXP is given.
 
+info module functions [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
+  Return a list of functions within all modules, grouped by module.
+  The list of functions can be restricted with the optional regular
+  expressions.  MODULE_REGEXP matches against the module name,
+  TYPE_REGEXP matches against the function type signature, and REGEXP
+  matches against the function name.
+
+info module variables [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
+  Return a list of variables within all modules, grouped by module.
+  The list of variables can be restricted with the optional regular
+  expressions.  MODULE_REGEXP matches against the module name,
+  TYPE_REGEXP matches against the variable type, and REGEXP matches
+  against the variable name.
+
 * Changed commands
 
 help
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 17e2c4cce71..f43b009af9a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18790,6 +18790,28 @@
 printing header information and messages explaining why no modules
 have been printed.
 
+@kindex info module functions
+@kindex info module variables
+@cindex modules
+@cindex functions
+@cindex variables
+@cindex module functions
+@cindex module variables
+@item info module functions [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
+@item info module variables [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
+List all functions or variables within all Fortran modules.  The set
+of functions or variables listed can be limited by providing some or
+all of the optional regular expressions.  If @var{module-regexp} is
+provided, then only Fortran modules matching @var{module-regexp} will
+be searched.  Only functions or variables whose type matches the
+optional regular expression @var{type-regexp} will be listed.  And
+only functions or variables whose name matches the optional regular
+expression @var{regexp} will be listed.
+
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no functions
+or variables have been printed.
+
 @kindex info classes
 @cindex Objective-C, classes and selectors
 @item info classes
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 27db03089d2..53e89cd4dfb 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -6331,6 +6331,278 @@ get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
 
 \f
 
+/* Hold the sub-commands of 'info module'.  */
+
+static struct cmd_list_element *info_module_cmdlist = NULL;
+
+/* Implement the 'info module' command, just displays some help text for
+   the available sub-commands.  */
+
+static void
+info_module_command (const char *args, int from_tty)
+{
+  help_list (info_module_cmdlist, "info module ", class_info, gdb_stdout);
+}
+
+/* Implement the core of both 'info module functions' and 'info module
+   variables'.  */
+
+static void
+info_module_subcommand_helper (bool quiet,
+			       const char *module_regexp,
+			       const char *regexp,
+			       const char *type_regexp,
+			       search_domain kind)
+{
+  /* Must make sure that if we're interrupted, MODULES gets freed.  */
+  std::vector<symbol_search> modules = search_symbols (module_regexp,
+						       MODULES_DOMAIN,
+						       NULL, 0, NULL,
+						       true);
+
+  /* Print a header line.  Don't build the header line bit by bit as this
+     prevents internationalisation.  */
+  if (!quiet)
+    {
+      if (module_regexp == nullptr)
+	{
+	  if(type_regexp == nullptr)
+	    {
+	      if (regexp == nullptr)
+		printf_filtered ((kind == VARIABLES_DOMAIN
+				  ? _("All variables in all modules:")
+				  : _("All functions in all modules:")));
+	      else
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables matching regular expression"
+			" \"%s\" in all modules:")
+		    : _("All functions matching regular expression"
+			" \"%s\" in all modules:")),
+		   regexp);
+	    }
+	  else
+	    {
+	      if (regexp == nullptr)
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables with type matching regular "
+			"expression \"%s\" in all modules:")
+		    : _("All functions with type matching regular "
+			"expression \"%s\" in all modules:")),
+		   type_regexp);
+	      else
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables matching regular expression "
+			"\"%s\",\n\twith type matching regular "
+			"expression \"%s\" in all modules:")
+		    : _("All functions matching regular expression "
+			"\"%s\",\n\twith type matching regular "
+			"expression \"%s\" in all modules:")),
+		   regexp, type_regexp);
+	    }
+	}
+      else
+	{
+	  if(type_regexp == nullptr)
+	    {
+	      if (regexp == nullptr)
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables in all modules matching regular "
+			"expression \"%s\":")
+		    : _("All functions in all modules matching regular "
+			"expression \"%s\":")),
+		   module_regexp);
+	      else
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables matching regular expression "
+			"\"%s\",\n\tin all modules matching regular "
+			"expression \"%s\":")
+		    : _("All functions matching regular expression "
+			"\"%s\",\n\tin all modules matching regular "
+			"expression \"%s\":")),
+		   regexp, module_regexp);
+	    }
+	  else
+	    {
+	      if (regexp == nullptr)
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables with type matching regular "
+			"expression \"%s\"\n\tin all modules matching "
+			"regular expression \"%s\":")
+		    : _("All functions with type matching regular "
+			"expression \"%s\"\n\tin all modules matching "
+			"regular expression \"%s\":")),
+		   type_regexp, module_regexp);
+	      else
+		printf_filtered
+		  ((kind == VARIABLES_DOMAIN
+		    ? _("All variables matching regular expression "
+			"\"%s\",\n\twith type matching regular expression "
+			"\"%s\",\n\tin all modules matching regular "
+			"expression \"%s\":")
+		    : _("All functions matching regular expression "
+			"\"%s\",\n\twith type matching regular expression "
+			"\"%s\",\n\tin all modules matching regular "
+			"expression \"%s\":")),
+		   regexp, type_regexp, module_regexp);
+	    }
+	}
+      printf_filtered ("\n");
+    }
+
+  /* Now search for all symbols of the required KIND matching the required
+     regular expressions.  We figure out which ones are in which modules
+     below.  */
+  std::vector<symbol_search> symbols = search_symbols (regexp, kind,
+						       type_regexp, 0,
+						       NULL, true);
+
+  /* Now iterate over all MODULES, checking to see which items from
+     SYMBOLS are in each module.  */
+  for (const symbol_search &p : modules)
+    {
+      QUIT;
+
+      /* This is a module.  */
+      gdb_assert (p.symbol != nullptr);
+
+      std::string prefix = SYMBOL_PRINT_NAME (p.symbol);
+      prefix += "::";
+
+      bool module_header_printed = false;
+      const char *last_filename = "";
+      for (const symbol_search &q : symbols)
+	{
+	  if (q.symbol == nullptr)
+	    continue;
+
+	  if (strncmp (SYMBOL_PRINT_NAME (q.symbol), prefix.c_str (),
+		       prefix.size ()) != 0)
+	    continue;
+
+	  if (!module_header_printed)
+	    {
+	      printf_filtered ("\n");
+	      printf_filtered (_("Module \"%s\":\n"),
+			       SYMBOL_PRINT_NAME (p.symbol));
+	      module_header_printed = true;
+	    }
+
+	  print_symbol_info (FUNCTIONS_DOMAIN, q.symbol, q.block,
+			     last_filename);
+	  last_filename
+	    = symtab_to_filename_for_display (symbol_symtab (q.symbol));
+	}
+    }
+}
+
+/* Hold the option values for the 'info module .....' sub-commands.  */
+
+struct info_modules_var_func_options
+{
+  bool quiet = false;
+  char *type_regexp = nullptr;
+  char *module_regexp = nullptr;
+
+  ~info_modules_var_func_options ()
+  {
+    xfree (type_regexp);
+    xfree (module_regexp);
+  }
+};
+
+/* The options used by 'info module variables' and 'info module functions'
+   commands.  */
+
+static const gdb::option::option_def info_modules_var_func_options_defs [] = {
+  gdb::option::boolean_option_def<info_modules_var_func_options> {
+    "q",
+    [] (info_modules_var_func_options *opt) { return &opt->quiet; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_modules_var_func_options> {
+    "t",
+    [] (info_modules_var_func_options *opt) { return &opt->type_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_modules_var_func_options> {
+    "m",
+    [] (info_modules_var_func_options *opt) { return &opt->module_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  }
+};
+
+/* Return the option group used by the 'info module ...' sub-commands.  */
+
+static inline gdb::option::option_def_group
+make_info_modules_var_func_options_def_group
+	(info_modules_var_func_options *opts)
+{
+  return {{info_modules_var_func_options_defs}, opts};
+}
+
+/* Implements the 'info module functions' command.  */
+
+static void
+info_module_functions_command (const char *args, int from_tty)
+{
+  info_modules_var_func_options opts;
+  auto grp = make_info_modules_var_func_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
+  info_module_subcommand_helper (opts.quiet, opts.module_regexp, args,
+				 opts.type_regexp, FUNCTIONS_DOMAIN);
+}
+
+/* Implements the 'info module variables' command.  */
+
+static void
+info_module_variables_command (const char *args, int from_tty)
+{
+  info_modules_var_func_options opts;
+  auto grp = make_info_modules_var_func_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
+  info_module_subcommand_helper (opts.quiet, opts.module_regexp, args,
+				 opts.type_regexp, VARIABLES_DOMAIN);
+}
+
+/* Command completer for 'info module ...' sub-commands.  */
+
+static void
+info_module_var_func_command_completer (struct cmd_list_element *ignore,
+					completion_tracker &tracker,
+					const char *text,
+					const char * /* word */)
+{
+
+  const auto group = make_info_modules_var_func_options_def_group (nullptr);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
+
+  const char *word = advance_to_expression_complete_word_point (tracker, text);
+  symbol_completer (ignore, tracker, text, word);
+}
+
+\f
+
 void
 _initialize_symtab (void)
 {
@@ -6393,6 +6665,45 @@ Options:\n\
 		_("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
+  add_prefix_cmd ("module", class_info, info_module_command, _("\
+Print information about modules."),
+		  &info_module_cmdlist, "info module ",
+		  0, &infolist);
+
+  c = add_cmd ("functions", class_info, info_module_functions_command, _("\
+Display functions arranged by modules.\n\
+Usage: info module functions [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
+Print a summary of all functions within each Fortran module, grouped by\n\
+module and file.  For each function the line on which the function is\n\
+defined is given along with the type signature and name of the function.\n\
+\n\
+If REGEXP is provided then only functions whose name matches REGEXP are\n\
+listed.  If MODREGEXP is provided then only functions in modules matching\n\
+MODREGEXP are listed.  If TYPEREGEXP is given then only functions whose\n\
+type signature matches TYPEREGEXP are listed.\n\
+\n\
+The -q flag suppresses printing some header information."),
+	       &info_module_cmdlist);
+  set_cmd_completer_handle_brkchars
+    (c, info_module_var_func_command_completer);
+
+  c = add_cmd ("variables", class_info, info_module_variables_command, _("\
+Display variables arranged by modules.\n\
+Usage: info module variables [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
+Print a summary of all variables within each Fortran module, grouped by\n\
+module and file.  For each variable the line on which the variable is\n\
+defined is given along with the type and name of the variable.\n\
+\n\
+If REGEXP is provided then only variables whose name matches REGEXP are\n\
+listed.  If MODREGEXP is provided then only variables in modules matching\n\
+MODREGEXP are listed.  If TYPEREGEXP is given then only variables whose\n\
+type matches TYPEREGEXP are listed.\n\
+\n\
+The -q flag suppresses printing some header information."),
+	       &info_module_cmdlist);
+  set_cmd_completer_handle_brkchars
+    (c, info_module_var_func_command_completer);
+
   add_com ("rbreak", class_breakpoint, rbreak_command,
 	   _("Set a breakpoint for all functions matching REGEXP."));
 
diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
index 33110236271..0ce73c8d41a 100644
--- a/gdb/testsuite/gdb.fortran/info-modules.exp
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -13,7 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# This file tests 'info modules'.
+# This file tests 'info modules', 'info module functions', and 'info
+# module variables'.
 
 load_lib "fortran.exp"
 
@@ -30,13 +31,19 @@ if { ![runto MAIN__] } {
     continue
 }
 
+set logical4 [fortran_logical4]
+set integer4 [fortran_int4]
+set real4 [fortran_real4]
+
+# Test 'info modules' command.
+
 gdb_test "info modules" \
     [multi_line \
 	 "All defined modules:" \
 	 "" \
 	 "File .*:" \
 	 "16:\[\t \]+mod1" \
-	 "22:\[\t \]+mod2" ]
+	 "37:\[\t \]+mod2" ]
 
 gdb_test "info modules 1" \
     [multi_line \
@@ -50,7 +57,7 @@ gdb_test "info modules 2" \
 	 "All modules matching regular expression \"2\":" \
 	 "" \
 	 "File .*:" \
-	 "22:\[\t \]+mod2" ]
+	 "37:\[\t \]+mod2" ]
 
 gdb_test "info modules mod" \
     [multi_line \
@@ -58,4 +65,117 @@ gdb_test "info modules mod" \
 	 "" \
 	 "File .*:" \
 	 "16:\[\t \]+mod1" \
-	 "22:\[\t \]+mod2" ]
+	 "37:\[\t \]+mod2" ]
+
+# Test 'info module functions'.
+
+gdb_test "info module functions" \
+    [multi_line \
+	 "All functions in all modules:" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "35:\[\t \]+void mod1::__copy_mod1_M1t1\\(Type m1t1, Type m1t1\\);" \
+	 "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+	 "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "41:\[\t \]+void mod2::sub_m2_a\\(${integer4}, ${logical4}\\);" \
+	 "49:\[\t \]+${logical4} mod2::sub_m2_b\\(${real4}\\);" ]
+
+gdb_test "info module functions -m mod1" \
+    [multi_line \
+	 "All functions in all modules matching regular expression \"mod1\":" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "35:\[\t \]+void mod1::__copy_mod1_M1t1\\(Type m1t1, Type m1t1\\);" \
+	 "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+	 "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" ]
+
+gdb_test "info module functions -t integer" \
+    [multi_line \
+	 "All functions with type matching regular expression \"integer\" in all modules:" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+	 "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "41:\[\t \]+void mod2::sub_m2_a\\(${integer4}, ${logical4}\\);" ]
+
+# Test 'info module variables'.
+
+gdb_test "info module variables" \
+    [multi_line \
+	 "All variables in all modules:" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "35:\[\t \]+Type m1t1 mod1::__def_init_mod1_M1t1;" \
+	 "35:\[\t \]+Type __vtype_mod1_M1t1 mod1::__vtab_mod1_M1t1;" \
+	 "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+	 "22:\[\t \]+${integer4} mod1::mod1_var_2;" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "38:\[\t \]+${integer4} mod2::mod2_var_1;" \
+	 "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -t real" \
+    [multi_line \
+	 "All variables with type matching regular expression \"real\" in all modules:" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -m mod2" \
+    [multi_line \
+	 "All variables in all modules matching regular expression \"mod2\":" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "38:\[\t \]+${integer4} mod2::mod2_var_1;" \
+	 "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -m mod2 -t real" \
+    [multi_line \
+	 "All variables with type matching regular expression \"real\"" \
+	 "	in all modules matching regular expression \"mod2\":" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables _1" \
+    [multi_line \
+	 "All variables matching regular expression \"_1\" in all modules:" \
+	 "" \
+	 "Module \"mod1\":" \
+	 "" \
+	 "File .*:" \
+	 "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+	 "" \
+	 "Module \"mod2\":" \
+	 "" \
+	 "File .*:" \
+	 "38:\[\t \]+${integer4} mod2::mod2_var_1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
index efaf4e57368..733ca73e556 100644
--- a/gdb/testsuite/gdb.fortran/info-types.exp
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -34,6 +34,7 @@ set integer4 [fortran_int4]
 set integer8 [fortran_int8]
 set logical4 [fortran_logical4]
 set character1 [fortran_character1]
+set real4 [fortran_real4]
 
 gdb_test "info types" \
     [multi_line \
@@ -44,7 +45,8 @@ gdb_test "info types" \
 	 "\[\t \]+${integer4}" \
 	 "(\[\t \]+${integer8}" \
 	 ")?\[\t \]+${logical4}" \
-	 "(20:\[\t \]+Type __vtype_mod1_M1t1;" \
+	 "(35:\[\t \]+Type __vtype_mod1_M1t1;" \
 	 ")?$decimal:\[\t \]+Type m1t1;" \
-	 "26:\[\t \]+Type s1;(" \
+	 "\[\t \]+${real4}" \
+	 "57:\[\t \]+Type s1;(" \
 	 ".*)?"]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
index 859a9485c8f..d2b61372226 100644
--- a/gdb/testsuite/gdb.fortran/info-types.f90
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -17,10 +17,41 @@ module mod1
   type :: m1t1
      integer :: b
   end type m1t1
+
+  real :: mod1_var_1 = 1.0
+  integer, parameter :: mod1_var_2 = 456
+
+contains
+  subroutine sub_m1_a(arg)
+    integer :: arg
+    print*, "sub_m1_a"
+    print*, "arg = ", arg
+  end subroutine sub_m1_a
+
+  integer function sub_m1_b()
+    print*, "sub_m1_b"
+    sub_m1_b = 3
+  end function sub_m1_b
 end module mod1
 
 module mod2
   integer :: mod2_var_1 = 123
+  real, parameter :: mod2_var_2 = 0.5
+contains
+  subroutine sub_m2_a(a, b)
+    integer :: a
+    logical :: b
+    print*, "sub_m2_a = ", abc
+    print*, "a = ", a
+    print*, "b = ", b
+  end subroutine sub_m2_a
+
+  logical function sub_m2_b(x)
+    real :: x
+    print*, "sub_m2_b = ", cde
+    print*, "x = ", x
+    sub_m2_b = .true.
+  end function sub_m2_b
 end module mod2
 
 program info_types_test
-- 
2.14.5

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

* [PATCHv2 0/4] Fortran info types, info modules, info module ...
@ 2019-10-03 11:29 Andrew Burgess
  2019-10-03 11:29 ` [PATCHv2 2/4] gdb/fortran: Add test for module variables in 'info variables' output Andrew Burgess
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Andrew Burgess @ 2019-10-03 11:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This is a new version of the series I originally posted here:

   https://sourceware.org/ml/gdb-patches/2019-07/msg00608.html

From the original series patches #1, #4, and #5 have already been
merged, while patches #2 and #3 are no longer needed thanks to Tom's
recent copy relocation work.

In this series patches #1 and #2 are new, while patches #3, and #4
correspond to #6 and #7 respectively from the original series.

For the content of these patches then:

  #1, #2 - These are pretty simple testsuite changes.

  #3, #4 - I've updated these after the feedback from Eli and Tom in
   the original series, but the docs especially probably need another
   review.  The general strategy is mostly unchanged, but I now cover
   additional cases to handle .debug_names and .gdb_index.

Thanks,
Andrew

--

Andrew Burgess (4):
  gdb/testsuite: Allow cc-with-tweaks board file to be used with Fortran
  gdb/fortran: Add test for module variables in 'info variables' output
  gdb/fortran: Add new 'info modules' command
  gdb: Add new commands to list module variables and functions

 gdb/ChangeLog                              |  31 +++
 gdb/NEWS                                   |  18 ++
 gdb/doc/ChangeLog                          |   9 +
 gdb/doc/gdb.texinfo                        |  32 +++
 gdb/dwarf2read.c                           |  25 +++
 gdb/psymtab.c                              |   2 +
 gdb/symtab.c                               | 347 ++++++++++++++++++++++++++++-
 gdb/symtab.h                               |   5 +-
 gdb/testsuite/ChangeLog                    |  24 ++
 gdb/testsuite/boards/cc-with-tweaks.exp    |  10 +
 gdb/testsuite/gdb.fortran/info-modules.exp | 181 +++++++++++++++
 gdb/testsuite/gdb.fortran/info-types.exp   |   6 +-
 gdb/testsuite/gdb.fortran/info-types.f90   |  36 +++
 gdb/testsuite/gdb.fortran/module.exp       |  24 ++
 14 files changed, 743 insertions(+), 7 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/info-modules.exp

-- 
2.14.5

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

* [PATCHv2 2/4] gdb/fortran: Add test for module variables in 'info variables' output
  2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
@ 2019-10-03 11:29 ` Andrew Burgess
  2019-10-03 11:29 ` [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command Andrew Burgess
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Andrew Burgess @ 2019-10-03 11:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Recent work from Tom Tromey to better handle variables with associated
copy relocations has fixed a Fortran issue where module variables
wouldn't show up in the output of 'info variables'.

This commit adds a test for this functionality to ensure it doesn't
get broken in the future.

gdb/testsuite/ChangeLog:

	* gdb.fortran/module.exp: Extend with 'info variables' test.
---
 gdb/testsuite/ChangeLog              |  4 ++++
 gdb/testsuite/gdb.fortran/module.exp | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp
index 4d71e7efac5..276f7dc3c24 100644
--- a/gdb/testsuite/gdb.fortran/module.exp
+++ b/gdb/testsuite/gdb.fortran/module.exp
@@ -13,6 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+load_lib "fortran.exp"
+
 standard_testfile .f90
 
 if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
@@ -32,6 +34,28 @@ if ![runto MAIN__] then {
     continue
 }
 
+set int_type [fortran_int4]
+
+# Test 'info variables' can find module variables.
+gdb_test "info variables -n" \
+    [multi_line \
+	 "All defined variables:" \
+	 "" \
+	 "File .*$srcfile:" \
+	 "18:\[ \t\]+${int_type} mod1::var_const;" \
+	 "17:\[ \t\]+${int_type} mod1::var_i;" \
+	 "23:\[ \t\]+${int_type} mod2::var_i;" \
+	 "28:\[ \t\]+${int_type} mod3::mod1;" \
+	 "27:\[ \t\]+${int_type} mod3::mod2;" \
+	 "29:\[ \t\]+${int_type} mod3::var_i;" \
+	 "33:\[ \t\]+${int_type} modmany::var_a;" \
+	 "33:\[ \t\]+${int_type} modmany::var_b;" \
+	 "33:\[ \t\]+${int_type} modmany::var_c;" \
+	 "33:\[ \t\]+${int_type} modmany::var_i;" \
+	 "37:\[ \t\]+${int_type} moduse::var_x;" \
+	 "37:\[ \t\]+${int_type} moduse::var_y;" ]
+
+
 # Do not use simple single-letter names as GDB would pick up for expectedly
 # nonexisting symbols some static variables from system libraries debuginfos.
 
-- 
2.14.5

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

* [PATCHv2 1/4] gdb/testsuite: Allow cc-with-tweaks board file to be used with Fortran
  2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
                   ` (2 preceding siblings ...)
  2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
@ 2019-10-03 11:29 ` Andrew Burgess
  2019-10-10 15:59 ` [PATCHv2 0/4] Fortran info types, info modules, info module Tom Tromey
  4 siblings, 0 replies; 13+ messages in thread
From: Andrew Burgess @ 2019-10-03 11:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

The board file cc-with-tweaks is used as the core for lots of other
board files, for example cc-with-gdb-index and cc-with-debug-names.
This commit extends cc-with-tweaks so that it will wrap the Fortran
compiler, allowing for more test coverage.

I tested all of the board files that make use of cc-with-tweaks
running the gdb.fortran/*.exp test set, and in some cases I did see
extra failures.  The "standard" results are:

                    === gdb Summary ===

    # of expected passes            953
    # of known failures             2

With board file 'cc-with-dwz-m':

                    === gdb Summary ===

    # of expected passes            903
    # of unexpected failures        1
    # of known failures             2
    # of untested testcases         4

With board file 'dwarf4-gdb-index':

                    === gdb Summary ===

    # of expected passes            950
    # of unexpected failures        3
    # of known failures             2

With board file 'fission-dwp':

                    === gdb Summary ===

    # of expected passes            949
    # of unexpected failures        4
    # of known failures             2

Despite these extra failure I don't think this should prevent this
change going in as these failures presumably already exist in GDB.

gdb/testsuite/ChangeLog:

	* boards/cc-with-tweaks.exp: Setup F90_FOR_TARGET and
	F77_FOR_TARGET.
---
 gdb/testsuite/ChangeLog                 |  5 +++++
 gdb/testsuite/boards/cc-with-tweaks.exp | 10 ++++++++++
 2 files changed, 15 insertions(+)

diff --git a/gdb/testsuite/boards/cc-with-tweaks.exp b/gdb/testsuite/boards/cc-with-tweaks.exp
index 371481477ae..dfca1ad94bb 100644
--- a/gdb/testsuite/boards/cc-with-tweaks.exp
+++ b/gdb/testsuite/boards/cc-with-tweaks.exp
@@ -43,6 +43,8 @@ process_multilib_options ""
 set found_gcc [find_gcc]
 set found_gxx [find_g++]
 set found_gnatmake [find_gnatmake]
+set found_f90 [find_gfortran]
+set found_f77 [find_g77]
 set_board_info compiler "$found_gcc"
 
 set contrib_dir [file normalize $srcdir/../contrib]
@@ -58,6 +60,14 @@ if ![info exists GNATMAKE_FOR_TARGET] {
     set GNATMAKE_FOR_TARGET "$found_gnatmake"
 }
 set GNATMAKE_FOR_TARGET "$contrib_dir/cc-with-tweaks.sh $CC_WITH_TWEAKS_FLAGS $GNATMAKE_FOR_TARGET"
+if ![info exists F90_FOR_TARGET] {
+    set F90_FOR_TARGET "$found_f90"
+}
+set F90_FOR_TARGET "$contrib_dir/cc-with-tweaks.sh $CC_WITH_TWEAKS_FLAGS $F90_FOR_TARGET"
+if ![info exists F77_FOR_TARGET] {
+    set F77_FOR_TARGET "$found_f77"
+}
+set F77_FOR_TARGET "$contrib_dir/cc-with-tweaks.sh $CC_WITH_TWEAKS_FLAGS $F77_FOR_TARGET"
 
 set pwd [exec pwd -P]
 exec echo $GDB $INTERNAL_GDBFLAGS $GDBFLAGS \"\$@\" > $pwd/gdb.sh
-- 
2.14.5

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

* [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command
  2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
  2019-10-03 11:29 ` [PATCHv2 2/4] gdb/fortran: Add test for module variables in 'info variables' output Andrew Burgess
@ 2019-10-03 11:29 ` Andrew Burgess
  2019-10-03 16:12   ` Eli Zaretskii
  2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Andrew Burgess @ 2019-10-03 11:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Add a new command 'info modules' that lists all of the modules GDB
knows about from the debug information.

A module is a debugging entity in the DWARF defined with
DW_TAG_module, currently Fortran is known to use this tag for its
modules.  I'm not aware of any other language that currently makes use
of DW_TAG_module.

The output style is similar to the 'info type' output:

    (gdb) info modules
    All defined modules:

    File info-types.f90:
    16:     mod1
    24:     mod2
    (gdb)

Where the user is told the file the module is defined in and, on the
left hand side, the line number at which the module is defined along
with the name of the module.

This patch is a new implementation of an idea originally worked on by
Mark O'Connor, Chris January, David Lecomber, and Xavier Oro from ARM.

gdb/ChangeLog:

	* dwarf2read.c (dw2_symtab_iter_next): Handle MODULE_DOMAIN.
	(dw2_expand_marked_cus): Handle MODULES_DOMAIN.
	(dw2_debug_names_iterator::next): Handle MODULE_DOMAIN and
	MODULES_DOMAIN.
	* psymtab.c (recursively_search_psymtabs): Likewise.
	* symtab.c (search_domain_name): Likewise.
	(search_symbols): Likewise.
	(print_symbol_info): Likewise.
	(symtab_symbol_info): Likewise.
	(info_modules_command): New function.
	(_initialize_symtab): Register 'info modules' command.
	* symtab.h (enum search_domain): Add MODULES_DOMAIN.
	* NEWS: Mention new 'info modules' command.

gdb/doc/ChangeLog:

	* gdb.texinfo (Symbols): Document new 'info modules' command.

gdb/testsuite/ChangeLog:

	* gdb.fortran/info-modules.exp: New file.
	* gdb.fortran/info-types.exp: Update expected results.
	* gdb.fortran/info-types.f90: Extend with extra module.
---
 gdb/ChangeLog                              | 16 ++++++++
 gdb/NEWS                                   |  4 ++
 gdb/doc/ChangeLog                          |  4 ++
 gdb/doc/gdb.texinfo                        | 10 +++++
 gdb/dwarf2read.c                           | 25 ++++++++++++
 gdb/psymtab.c                              |  2 +
 gdb/symtab.c                               | 36 ++++++++++++++++--
 gdb/symtab.h                               |  5 ++-
 gdb/testsuite/ChangeLog                    |  6 +++
 gdb/testsuite/gdb.fortran/info-modules.exp | 61 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/info-types.exp   |  2 +-
 gdb/testsuite/gdb.fortran/info-types.f90   |  5 +++
 12 files changed, 170 insertions(+), 6 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/info-modules.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index 3211ec9542c..2347c14d37d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -138,6 +138,10 @@ show print frame-info
   'frame', 'stepi'.  The python frame filtering also respect this setting.
   The 'backtrace' '-frame-info' option can override this global setting.
 
+info modules [-q] [REGEXP]
+  Return a list of Fortran modules matching REGEXP, or all modules if
+  no REGEXP is given.
+
 * Changed commands
 
 help
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 78d38284693..17e2c4cce71 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18780,6 +18780,16 @@
 is printed only if its name matches @var{regexp} and its type matches
 @var{type_regexp}.
 
+@kindex info modules
+@cindex modules
+@item info modules [-q] [@var{regexp}]
+List all Fortran modules in the program, or all modules matching the
+optional regular expression @var{regexp}.
+
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no modules
+have been printed.
+
 @kindex info classes
 @cindex Objective-C, classes and selectors
 @item info classes
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 9d9dd6db709..c7b3a90042f 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4025,6 +4025,10 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
 	      if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
 		continue;
 	      break;
+	    case MODULE_DOMAIN:
+	      if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+		continue;
+	      break;
 	    default:
 	      break;
 	    }
@@ -5047,6 +5051,10 @@ dw2_expand_marked_cus
 	      if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
 		continue;
 	      break;
+	    case MODULES_DOMAIN:
+	      if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+		continue;
+	      break;
 	    default:
 	      break;
 	    }
@@ -5953,6 +5961,15 @@ dw2_debug_names_iterator::next ()
 	  goto again;
 	}
       break;
+    case MODULE_DOMAIN:
+      switch (indexval.dwarf_tag)
+	{
+	case DW_TAG_module:
+	  break;
+	default:
+	  goto again;
+	}
+      break;
     default:
       break;
     }
@@ -5989,6 +6006,14 @@ dw2_debug_names_iterator::next ()
 	  goto again;
 	}
       break;
+    case MODULES_DOMAIN:
+      switch (indexval.dwarf_tag)
+	{
+	case DW_TAG_module:
+	  break;
+	default:
+	  goto again;
+	}
     default:
       break;
     }
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 31b6d597773..44af8031fc4 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1272,6 +1272,8 @@ recursively_search_psymtabs
 	  QUIT;
 
 	  if ((domain == ALL_DOMAIN
+	       || (domain == MODULES_DOMAIN
+		   && (*psym)->domain == MODULE_DOMAIN)
 	       || (domain == VARIABLES_DOMAIN
 		   && (*psym)->aclass != LOC_TYPEDEF
 		   && (*psym)->aclass != LOC_BLOCK)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 8a551f1575a..27db03089d2 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -297,6 +297,7 @@ search_domain_name (enum search_domain e)
     case VARIABLES_DOMAIN: return "VARIABLES_DOMAIN";
     case FUNCTIONS_DOMAIN: return "FUNCTIONS_DOMAIN";
     case TYPES_DOMAIN: return "TYPES_DOMAIN";
+    case MODULES_DOMAIN: return "MODULES_DOMAIN";
     case ALL_DOMAIN: return "ALL_DOMAIN";
     default: gdb_assert_not_reached ("bad search_domain");
     }
@@ -4474,7 +4475,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   gdb::optional<compiled_regex> preg;
   gdb::optional<compiled_regex> treg;
 
-  gdb_assert (kind <= TYPES_DOMAIN);
+  gdb_assert (kind <= MODULES_DOMAIN);
 
   ourtype = types[kind];
   ourtype2 = types2[kind];
@@ -4648,7 +4649,9 @@ search_symbols (const char *regexp, enum search_domain kind,
 								     sym)))
 			      || (kind == TYPES_DOMAIN
 				  && SYMBOL_CLASS (sym) == LOC_TYPEDEF
-				  && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN))))
+				  && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN)
+			      || (kind == MODULES_DOMAIN
+				  && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN))))
 		    {
 		      /* match */
 		      result.emplace_back (i, sym);
@@ -4779,6 +4782,11 @@ print_symbol_info (enum search_domain kind,
 
       printf_filtered (";\n");
     }
+  /* Printing of modules is currently done here, maybe at some future
+     point we might want a language specific method to print the module
+     symbol so that we can customise the output more.  */
+  else if (kind == MODULES_DOMAIN)
+    printf_filtered ("%s\n", SYMBOL_PRINT_NAME (sym));
 }
 
 /* This help function for symtab_symbol_info() prints information
@@ -4819,11 +4827,11 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms,
 		    const char *t_regexp, int from_tty)
 {
   static const char * const classnames[] =
-    {"variable", "function", "type"};
+    {"variable", "function", "type", "module"};
   const char *last_filename = "";
   int first = 1;
 
-  gdb_assert (kind <= TYPES_DOMAIN);
+  gdb_assert (kind <= MODULES_DOMAIN);
 
   if (regexp != nullptr && *regexp == '\0')
     regexp = nullptr;
@@ -5042,6 +5050,22 @@ info_types_command_completer (struct cmd_list_element *ignore,
   symbol_completer (ignore, tracker, text, word);
 }
 
+/* Implement the 'info modules' command.  */
+
+static void
+info_modules_command (const char *args, int from_tty)
+{
+  info_types_options opts;
+
+  auto grp = make_info_types_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+  symtab_symbol_info (opts.quiet, true, args, MODULES_DOMAIN, NULL,
+		      from_tty);
+}
+
 /* Breakpoint all functions matching regular expression.  */
 
 void
@@ -6365,6 +6389,10 @@ Options:\n\
   c = add_info ("sources", info_sources_command, info_sources_help.c_str ());
   set_cmd_completer_handle_brkchars (c, info_sources_command_completer);
 
+  c = add_info ("modules", info_modules_command,
+		_("All module names, or those matching REGEXP."));
+  set_cmd_completer_handle_brkchars (c, info_types_command_completer);
+
   add_com ("rbreak", class_breakpoint, rbreak_command,
 	   _("Set a breakpoint for all functions matching REGEXP."));
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index dc65409dd24..ba8df9191ff 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -829,8 +829,11 @@ enum search_domain
   /* All defined types */
   TYPES_DOMAIN = 2,
 
+  /* All modules.  */
+  MODULES_DOMAIN = 3,
+
   /* Any type.  */
-  ALL_DOMAIN = 3
+  ALL_DOMAIN = 4
 };
 
 extern const char *search_domain_name (enum search_domain);
diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
new file mode 100644
index 00000000000..33110236271
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -0,0 +1,61 @@
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file tests 'info modules'.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+standard_testfile info-types.f90
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
+    return -1
+}
+
+if { ![runto MAIN__] } {
+    perror "Could not run to breakpoint `MAIN__'."
+    continue
+}
+
+gdb_test "info modules" \
+    [multi_line \
+	 "All defined modules:" \
+	 "" \
+	 "File .*:" \
+	 "16:\[\t \]+mod1" \
+	 "22:\[\t \]+mod2" ]
+
+gdb_test "info modules 1" \
+    [multi_line \
+	 "All modules matching regular expression \"1\":" \
+	 "" \
+	 "File .*:" \
+	 "16:\[\t \]+mod1" ]
+
+gdb_test "info modules 2" \
+    [multi_line \
+	 "All modules matching regular expression \"2\":" \
+	 "" \
+	 "File .*:" \
+	 "22:\[\t \]+mod2" ]
+
+gdb_test "info modules mod" \
+    [multi_line \
+	 "All modules matching regular expression \"mod\":" \
+	 "" \
+	 "File .*:" \
+	 "16:\[\t \]+mod1" \
+	 "22:\[\t \]+mod2" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
index 30646287ee9..efaf4e57368 100644
--- a/gdb/testsuite/gdb.fortran/info-types.exp
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -46,5 +46,5 @@ gdb_test "info types" \
 	 ")?\[\t \]+${logical4}" \
 	 "(20:\[\t \]+Type __vtype_mod1_M1t1;" \
 	 ")?$decimal:\[\t \]+Type m1t1;" \
-	 "22:\[\t \]+Type s1;(" \
+	 "26:\[\t \]+Type s1;(" \
 	 ".*)?"]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
index 0e27e1ddf08..859a9485c8f 100644
--- a/gdb/testsuite/gdb.fortran/info-types.f90
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -19,8 +19,13 @@ module mod1
   end type m1t1
 end module mod1
 
+module mod2
+  integer :: mod2_var_1 = 123
+end module mod2
+
 program info_types_test
   use mod1
+  use mod2
 
   type :: s1
      integer :: a
-- 
2.14.5

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

* Re: [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command
  2019-10-03 11:29 ` [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command Andrew Burgess
@ 2019-10-03 16:12   ` Eli Zaretskii
  0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2019-10-03 16:12 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Cc: Andrew Burgess <andrew.burgess@embecosm.com>
> Date: Thu,  3 Oct 2019 12:29:16 +0100
> 
> gdb/ChangeLog:
> 
> 	* dwarf2read.c (dw2_symtab_iter_next): Handle MODULE_DOMAIN.
> 	(dw2_expand_marked_cus): Handle MODULES_DOMAIN.
> 	(dw2_debug_names_iterator::next): Handle MODULE_DOMAIN and
> 	MODULES_DOMAIN.
> 	* psymtab.c (recursively_search_psymtabs): Likewise.
> 	* symtab.c (search_domain_name): Likewise.
> 	(search_symbols): Likewise.
> 	(print_symbol_info): Likewise.
> 	(symtab_symbol_info): Likewise.
> 	(info_modules_command): New function.
> 	(_initialize_symtab): Register 'info modules' command.
> 	* symtab.h (enum search_domain): Add MODULES_DOMAIN.
> 	* NEWS: Mention new 'info modules' command.
> 
> gdb/doc/ChangeLog:
> 
> 	* gdb.texinfo (Symbols): Document new 'info modules' command.
> 
> gdb/testsuite/ChangeLog:
> 
> 	* gdb.fortran/info-modules.exp: New file.
> 	* gdb.fortran/info-types.exp: Update expected results.
> 	* gdb.fortran/info-types.f90: Extend with extra module.

OK for the documentation changes.

Thanks.

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
@ 2019-10-03 16:16   ` Eli Zaretskii
  2019-10-10 15:58   ` Tom Tromey
  2019-11-22 12:44   ` Tom de Vries
  2 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2019-10-03 16:16 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Cc: Andrew Burgess <andrew.burgess@embecosm.com>
> Date: Thu,  3 Oct 2019 12:29:17 +0100
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 2347c14d37d..d92ab2d6e20 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -142,6 +142,20 @@ info modules [-q] [REGEXP]
>    Return a list of Fortran modules matching REGEXP, or all modules if
>    no REGEXP is given.
>  
> +info module functions [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
> +  Return a list of functions within all modules, grouped by module.
> +  The list of functions can be restricted with the optional regular
> +  expressions.  MODULE_REGEXP matches against the module name,
> +  TYPE_REGEXP matches against the function type signature, and REGEXP
> +  matches against the function name.
> +
> +info module variables [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
> +  Return a list of variables within all modules, grouped by module.
> +  The list of variables can be restricted with the optional regular
> +  expressions.  MODULE_REGEXP matches against the module name,
> +  TYPE_REGEXP matches against the variable type, and REGEXP matches
> +  against the variable name.

This part is OK.

> +@kindex info module functions
> +@kindex info module variables
> +@cindex modules
> +@cindex functions
> +@cindex variables
> +@cindex module functions
> +@cindex module variables

It is not useful to have several index entries which all begin with
the same string and point to the same place.  I suggest to have just
these:

  +@kindex info module
  +@cindex Fortran modules, information about
  +@cindex functions and variables by Fortran module
  +@cindex module functions and variables

> +@item info module functions [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
> +@item info module variables [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]

The second one should be @itemx.

The patch for the manual is OK with these nits fixed.

Thanks.

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
  2019-10-03 16:16   ` Eli Zaretskii
@ 2019-10-10 15:58   ` Tom Tromey
  2019-11-22 12:44   ` Tom de Vries
  2 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2019-10-10 15:58 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:

Andrew> This patch adds two new commands "info module functions" and "info
Andrew> module variables".  These commands list all of the functions and
Andrew> variables grouped by module and then by file.

Andrew> +	  if(type_regexp == nullptr)
...
Andrew> +	  if(type_regexp == nullptr)

I noticed these two lines were missing a space after the "if".

Tom

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

* Re: [PATCHv2 0/4] Fortran info types, info modules, info module ...
  2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
                   ` (3 preceding siblings ...)
  2019-10-03 11:29 ` [PATCHv2 1/4] gdb/testsuite: Allow cc-with-tweaks board file to be used with Fortran Andrew Burgess
@ 2019-10-10 15:59 ` Tom Tromey
  4 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2019-10-10 15:59 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:

Andrew> This is a new version of the series I originally posted here:
Andrew>    https://sourceware.org/ml/gdb-patches/2019-07/msg00608.html

I read through these.  Aside from some tiny nits for patch #4,
everything looked good to me.

Tom

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
  2019-10-03 16:16   ` Eli Zaretskii
  2019-10-10 15:58   ` Tom Tromey
@ 2019-11-22 12:44   ` Tom de Vries
  2019-11-27 21:29     ` Andrew Burgess
  2 siblings, 1 reply; 13+ messages in thread
From: Tom de Vries @ 2019-11-22 12:44 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 03-10-2019 13:29, Andrew Burgess wrote:
> 	* gdb.fortran/info-modules.exp: Update expected results, and add
> 	additional tests for 'info module functinos', and 'info module
> 	variables'.
> 	* gdb.fortran/info-types.exp: Update expected results.
> 	* gdb.fortran/info-types.f90: Extend testcase with additional
> 	module variables and functions.

Hi,

This test-case fails to compile for me:
...
$ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:

   use mod2
      1
Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
such file or directory
compilation terminated.

                === gdb Summary ===

# of untested testcases         1
...

Interestingly, if I first run:
...
$ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/module.exp"
Running src/gdb/testsuite/gdb.fortran/module.exp ...

                === gdb Summary ===

# of expected passes            27
...
which produces:
...
$ ls -la build/gdb/testsuite/mod2.mod
-rw-r--r-- 1 vries users 208 22 nov 13:35 build/gdb/testsuite/mod2.mod
...
then the test-case passes:
...
$ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
Running src/gdb/testsuite/gdb.fortran/info-modules.exp ...

                === gdb Summary ===

# of expected passes            12
...

Removing mod2.mod brings the failure back:
...
$ rm -f build/gdb/testsuite/mod2.mod
             $ cd build/gdb; make check
RUNTESTFLAGS="gdb.fortran/info-modules.exp"
gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:

   use mod2
      1
Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
such file or directory
compilation terminated.

                === gdb Summary ===

# of untested testcases         1
...

So, I think that in a parallel test run this may succeed, but in a
sequential testrun this should fail.

Thanks,
- Tom

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-11-22 12:44   ` Tom de Vries
@ 2019-11-27 21:29     ` Andrew Burgess
  2019-11-28  9:21       ` Tom de Vries
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Burgess @ 2019-11-27 21:29 UTC (permalink / raw)
  To: Tom de Vries; +Cc: gdb-patches

* Tom de Vries <tdevries@suse.de> [2019-11-22 13:44:09 +0100]:

> On 03-10-2019 13:29, Andrew Burgess wrote:
> > 	* gdb.fortran/info-modules.exp: Update expected results, and add
> > 	additional tests for 'info module functinos', and 'info module
> > 	variables'.
> > 	* gdb.fortran/info-types.exp: Update expected results.
> > 	* gdb.fortran/info-types.f90: Extend testcase with additional
> > 	module variables and functions.
> 
> Hi,
> 
> This test-case fails to compile for me:
> ...
> $ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
> gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:
> 
>    use mod2
>       1
> Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
> such file or directory
> compilation terminated.
> 
>                 === gdb Summary ===
> 
> # of untested testcases         1
> ...
> 
> Interestingly, if I first run:
> ...
> $ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/module.exp"
> Running src/gdb/testsuite/gdb.fortran/module.exp ...
> 
>                 === gdb Summary ===
> 
> # of expected passes            27
> ...
> which produces:
> ...
> $ ls -la build/gdb/testsuite/mod2.mod
> -rw-r--r-- 1 vries users 208 22 nov 13:35 build/gdb/testsuite/mod2.mod
> ...
> then the test-case passes:
> ...
> $ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
> Running src/gdb/testsuite/gdb.fortran/info-modules.exp ...
> 
>                 === gdb Summary ===
> 
> # of expected passes            12
> ...
> 
> Removing mod2.mod brings the failure back:
> ...
> $ rm -f build/gdb/testsuite/mod2.mod
>              $ cd build/gdb; make check
> RUNTESTFLAGS="gdb.fortran/info-modules.exp"
> gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:
> 
>    use mod2
>       1
> Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
> such file or directory
> compilation terminated.
> 
>                 === gdb Summary ===
> 
> # of untested testcases         1
> ...
> 
> So, I think that in a parallel test run this may succeed, but in a
> sequential testrun this should fail.

Tom,

Thanks for finding this issue.  Sorry that I didn't spot this feedback
until after I'd pushed this patch.

I've committed the fix below to address this issue.

Thanks,
Andrew

---

From 640ab94712483457b99bd1039b52821c510b28a7 Mon Sep 17 00:00:00 2001
From: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Wed, 27 Nov 2019 21:18:38 +0000
Subject: [PATCH] gdb/testsuite: Fix race condition compiling fortran test

The Fortran test gdb.fortran/info-modules compiles the files
info-types.f90 and info-types-2.f90 in that order.  Unfortunately
info-types.f90 makes use of a module defined in info-types-2.f90.

This currently doesn't cause a problem if you run all of the Fortran
tests as the info-types.exp test already compiles info-types-2.f90 and
so the module description file 'mod2.mod' will be created, and can
then be found by info-modules.exp during its compile.

If however you try to run just info-modules.exp in a clean build
directory, the test will fail to compile.

Fix this by compiling the source files in the reverse order so that
the module is compiled first, then the test program that uses the
module.

gdb/testsuite/ChangeLog:

	* gdb.fortran/info-modules.exp: Compile source files in correct
	order.

Change-Id: Ic3a1eded0486f6264ebe3066cf1beafbd2534a91
---
 gdb/testsuite/ChangeLog                    | 5 +++++
 gdb/testsuite/gdb.fortran/info-modules.exp | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
index 43570066d2f..c57ac3ff569 100644
--- a/gdb/testsuite/gdb.fortran/info-modules.exp
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -23,7 +23,7 @@ if { [skip_fortran_tests] } { continue }
 standard_testfile info-types.f90 info-types-2.f90
 
 if { [prepare_for_testing "failed to prepare" $testfile \
-	  [list $srcfile $srcfile2] {debug f90}] } {
+	  [list $srcfile2 $srcfile] {debug f90}] } {
     return -1
 }
 
-- 
2.14.5

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-11-27 21:29     ` Andrew Burgess
@ 2019-11-28  9:21       ` Tom de Vries
  2019-11-28 12:18         ` Andrew Burgess
  0 siblings, 1 reply; 13+ messages in thread
From: Tom de Vries @ 2019-11-28  9:21 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

On 27-11-2019 22:29, Andrew Burgess wrote:
>> This test-case fails to compile for me:
>> ...
>> $ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
>> gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:
>>
>>    use mod2
>>       1
>> Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
>> such file or directory
>> compilation terminated.
>>
>>                 === gdb Summary ===
>>
>> # of untested testcases         1

> 
> I've committed the fix below to address this issue.
> 

> diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
> index 43570066d2f..c57ac3ff569 100644
> --- a/gdb/testsuite/gdb.fortran/info-modules.exp
> +++ b/gdb/testsuite/gdb.fortran/info-modules.exp
> @@ -23,7 +23,7 @@ if { [skip_fortran_tests] } { continue }
>  standard_testfile info-types.f90 info-types-2.f90
>  
>  if { [prepare_for_testing "failed to prepare" $testfile \
> -	  [list $srcfile $srcfile2] {debug f90}] } {
> +	  [list $srcfile2 $srcfile] {debug f90}] } {
>      return -1
>  }
>  
> 

Ah, interesting.  I initially tried:
...
-standard_testfile info-types.f90 info-types-2.f90
+standard_testfile info-types-2.f90 info-types.f90
...
which made the test-case compile but caused a bunch of FAILs, but it
didn't occur to me to switch the order in the preparing_for_testing call.

Thanks,
- Tom

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

* Re: [PATCHv2 4/4] gdb: Add new commands to list module variables and functions
  2019-11-28  9:21       ` Tom de Vries
@ 2019-11-28 12:18         ` Andrew Burgess
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Burgess @ 2019-11-28 12:18 UTC (permalink / raw)
  To: Tom de Vries; +Cc: gdb-patches

* Tom de Vries <tdevries@suse.de> [2019-11-28 10:20:59 +0100]:

> On 27-11-2019 22:29, Andrew Burgess wrote:
> >> This test-case fails to compile for me:
> >> ...
> >> $ cd build/gdb; make check RUNTESTFLAGS="gdb.fortran/info-modules.exp"
> >> gdb compile failed, src/gdb/testsuite/gdb.fortran/info-types.f90:39:6:
> >>
> >>    use mod2
> >>       1
> >> Fatal Error: Can't open module file 'mod2.mod' for reading at (1): No
> >> such file or directory
> >> compilation terminated.
> >>
> >>                 === gdb Summary ===
> >>
> >> # of untested testcases         1
> 
> > 
> > I've committed the fix below to address this issue.
> > 
> 
> > diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
> > index 43570066d2f..c57ac3ff569 100644
> > --- a/gdb/testsuite/gdb.fortran/info-modules.exp
> > +++ b/gdb/testsuite/gdb.fortran/info-modules.exp
> > @@ -23,7 +23,7 @@ if { [skip_fortran_tests] } { continue }
> >  standard_testfile info-types.f90 info-types-2.f90
> >  
> >  if { [prepare_for_testing "failed to prepare" $testfile \
> > -	  [list $srcfile $srcfile2] {debug f90}] } {
> > +	  [list $srcfile2 $srcfile] {debug f90}] } {
> >      return -1
> >  }
> >  
> > 
> 
> Ah, interesting.  I initially tried:
> ...
> -standard_testfile info-types.f90 info-types-2.f90
> +standard_testfile info-types-2.f90 info-types.f90
> ...
> which made the test-case compile but caused a bunch of FAILs, but it
> didn't occur to me to switch the order in the preparing_for_testing call.

That change will result in $srcfile and $srcfile2 swapping over.  This
test checks that symbols are being reported as from the correct source
file, so the output patterns make use of the srcfile variables.
That's why this didn't work.

Thanks,
Andre

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

end of thread, other threads:[~2019-11-28 12:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-03 11:29 [PATCHv2 0/4] Fortran info types, info modules, info module Andrew Burgess
2019-10-03 11:29 ` [PATCHv2 2/4] gdb/fortran: Add test for module variables in 'info variables' output Andrew Burgess
2019-10-03 11:29 ` [PATCHv2 3/4] gdb/fortran: Add new 'info modules' command Andrew Burgess
2019-10-03 16:12   ` Eli Zaretskii
2019-10-03 11:29 ` [PATCHv2 4/4] gdb: Add new commands to list module variables and functions Andrew Burgess
2019-10-03 16:16   ` Eli Zaretskii
2019-10-10 15:58   ` Tom Tromey
2019-11-22 12:44   ` Tom de Vries
2019-11-27 21:29     ` Andrew Burgess
2019-11-28  9:21       ` Tom de Vries
2019-11-28 12:18         ` Andrew Burgess
2019-10-03 11:29 ` [PATCHv2 1/4] gdb/testsuite: Allow cc-with-tweaks board file to be used with Fortran Andrew Burgess
2019-10-10 15:59 ` [PATCHv2 0/4] Fortran info types, info modules, info module Tom Tromey

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