public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC 1/5] New cli-utils.h/.c function extract_info_print_args
  2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (3 preceding siblings ...)
  2018-07-01 21:07 ` [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-01 21:07 ` Philippe Waroquiers
  4 siblings, 0 replies; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

New cli-utils.h/.c function extract_info_print_args factorises
the extraction of the args '[-q] [-t TYPEREGEXP] [NAMEREGEXP]'.

This function is used by the commands
  info [args|functions|locals|variables]

cli-utils.c has a new static function extract_arg_maybe_quoted
that extracts an argument, possibly single quoted.
---
 gdb/cli/cli-utils.c | 113 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/cli/cli-utils.h |  20 ++++++++
 2 files changed, 133 insertions(+)

diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index c55b5035e4..3f33c18a06 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -23,6 +23,9 @@
 
 #include <ctype.h>
 
+static std::string
+extract_arg_maybe_quoted (const char **arg);
+
 /* See documentation in cli-utils.h.  */
 
 int
@@ -125,6 +128,56 @@ get_number (char **pp)
   return result;
 }
 
+/* See documentation in cli-utils.h.  */
+
+void
+extract_info_print_args (const char* command,
+			 const char **args,
+			 bool *quiet,
+			 std::string *regexp,
+			 std::string *t_regexp)
+{
+  *quiet = false;
+  *regexp = "";
+  *t_regexp = "";
+
+  while (*args != NULL)
+    {
+      if (check_for_argument (args, "--", 2))
+	{
+	  *args = skip_spaces (*args);
+	  break;
+	}
+
+      if (check_for_argument (args, "-t", 2))
+	{
+	  *t_regexp = extract_arg_maybe_quoted (args);
+	  *args = skip_spaces (*args);
+	  continue;
+	}
+
+      if (check_for_argument (args, "-q", 2))
+	{
+	  *quiet = true;
+	  *args = skip_spaces (*args);
+	  continue;
+	}
+
+      if (**args != '-')
+	break;
+
+      std::string option = extract_arg (args);
+      error (_("Unrecognized option '%s' to %s command.  "
+	       "Try \"help %s\"."), option.c_str (),
+	     command, command);
+    }
+
+  if (*args != NULL && **args != '\000')
+    *regexp = extract_arg (args);
+
+}
+
+
 /* See documentation in cli-utils.h.  */
 
 number_or_range_parser::number_or_range_parser (const char *string)
@@ -253,6 +306,66 @@ remove_trailing_whitespace (const char *start, const char *s)
   return s;
 }
 
+/* A helper function to extract an argument from *ARG.  An argument is
+   delimited by whitespace, but it can also be optionally quoted using
+   single quote characters.  The return value is empty if no argument
+   was found.  */
+
+static std::string
+extract_arg_maybe_quoted (const char **arg)
+{
+  if (!*arg)
+    return std::string ();
+
+  /* Find the start of the argument.  */
+  *arg = skip_spaces (*arg);
+  if (!**arg)
+    return std::string ();
+
+  if (**arg == '\'')
+    {
+      /* Quoted argument.  */
+      const char *orig_arg = *arg;
+      std::string result;
+      const char *p;
+
+      (*arg)++; /* Skip starting quote.  */
+
+      /* Find the end of the quoted argument.  */
+      for (p = *arg; *p != '\0'; p++)
+	{
+	  if (*p == '\'')
+	    {
+	      (*arg)++; /* Skip ending quote.  */
+	      return result;
+	    }
+
+	  if (*p == '\\' && p[1] == '\'')
+	    {
+	      /* Escaped quote.  */
+	      p++;      /* Skip escape char.  */
+	      (*arg)++; /* Skip escape char.  */
+	    }
+
+	  result = result + *p;
+	  (*arg)++;
+	}
+      error (_("Unterminated quoted argument in %s"), orig_arg);
+    }
+  else
+    {
+      const char *result = *arg;
+
+      /* Find the end of the argument.  */
+      *arg = skip_to_space (*arg + 1);
+
+      if (result == *arg)
+	return std::string ();
+
+      return std::string (result, *arg - result);
+    }
+}
+
 /* See documentation in cli-utils.h.  */
 
 std::string
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index e34ee0df37..f756f0d331 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -39,6 +39,26 @@ extern int get_number (const char **);
 
 extern int get_number (char **);
 
+/* Extract from args the arguments [-q] [-t TYPEREGEXP] [--] NAMEREGEXP.
+   Only the above flags are accepted. any other flag will raise an error.
+   COMMAND is used to produce the error message if an invalid flag is
+   given.  */
+extern void extract_info_print_args (const char* command,
+				     const char **args,
+				     bool *quiet,
+				     std::string *regexp,
+				     std::string *t_regexp);
+
+#define INFO_PRINT_ARGS_HELP(entity_kind) \
+"If NAMEREGEXP is provided, only prints the " entity_kind " whose name\n\
+matches NAMEREGEXP.\n\
+If -t TYPEREGEXP is provided, only prints the " entity_kind " whose type\n\
+matches TYPEREGEXP. Note that the matching is done with the type\n\
+printed by the 'whatis' command.\n\
+By default, the command might produce headers and/or messages indicating\n\
+why no " entity_kind " can be printed.\n\
+The flag -q disables the production of these headers and messages."
+
 /* Parse a number or a range.
    A number will be of the form handled by get_number.
    A range will be of the form <number1> - <number2>, and
-- 
2.17.1

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

* [RFC 4/5] Document changes to info [args|functions|locals|variables]
  2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-01 21:07 ` Philippe Waroquiers
  2018-07-02 15:02   ` Eli Zaretskii
  2018-07-01 21:07 ` [RFC 2/5] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Document changes to info [args|functions|locals|variables]
---
 gdb/doc/gdb.texinfo | 98 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 88 insertions(+), 10 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7fb6ac5636..789d54a3b2 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7705,15 +7705,60 @@ architectures) that you specify in the @code{frame} command.
 @xref{Selection, ,Selecting a Frame}.
 
 @kindex info args
-@item info args
+@item info args [-q]
 Print the arguments of the selected frame, each on a separate line.
 
+Flag @code{-q}, which stands for @samp{quiet}, disables printing
+header information and messages explaining why no argument have been
+printed.
+
+@item info args [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @kbd{info args}, but only print the arguments
+that matches the provided regexp(s).
+
+If @var{regexp} is provided, prints only the arguments whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, prints only the arguments whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the variable type as printed with the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+
+
 @item info locals
-@kindex info locals
+@kindex info locals [-q]
 Print the local variables of the selected frame, each on a separate
 line.  These are all variables (declared either static or automatic)
 accessible at the point of execution of the selected frame.
 
+Flag @code{-q}, which stands for @samp{quiet}, disables printing
+header information and messages explaining why no local variables have been
+printed.
+
+@item info locals [-q] [-t @var{type_regexp}] [@var{regexp}]
+Like @kbd{info locals}, but only print the local variables
+that matches the provided regexp(s).
+
+If @var{regexp} is provided, prints only the local variables whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, prints only the local variables whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the local variable type as printed with the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+
+The command @samp{info locals -q -t @var{type_regexp}} can usefully be
+combined with the commands @samp{frame apply} and @samp{thread apply}.
+For example, if you have an RAII type @code{lock_something_t},
+you can list all locks in your program by doing
+@samp{thread apply all -s frame apply all -s
+info locals -q -t lock_something_t}, or the equivalent shorter form
+@samp{tfaas i lo -q -t lock_something_t}.
+
 @end table
 
 @node Frame Filter Management
@@ -17665,32 +17710,65 @@ debugging information, organized into two lists: files whose symbols
 have already been read, and files whose symbols will be read when needed.
 
 @kindex info functions
-@item info functions
+@item info functions [-q]
 Print the names and data types of all defined functions.
 Similarly to @samp{info types}, this command groups its output by source
 files and annotates each function definition with its source line
 number.
 
-@item info functions @var{regexp}
+Flag @code{-q}, which stands for @samp{quiet}, disables printing
+header information and messages explaining why no functions have been
+printed.
+
+@item info functions [-q] [-t @var{type_regexp}] [@var{regexp}]
 Like @samp{info functions}, but only print the names and data types of
-functions whose names contain a match for regular expression
-@var{regexp}.  Thus, @samp{info fun step} finds all functions whose
+the functions that matches the provided regexp(s).
+
+If @var{regexp} is provided, prints only the functions whose names
+contain a match for regular expression @var{regexp}.
+Thus, @samp{info fun step} finds all functions whose
 names include @code{step}; @samp{info fun ^step} finds those whose names
 start with @code{step}.  If a function name contains characters that
 conflict with the regular expression language (e.g.@:
 @samp{operator*()}), they may be quoted with a backslash.
 
+If @var{type_regexp} is provided, prints only the functions whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the function type as printed with the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
+Thus, @samp{info fun -t '^int ('} finds the functions that return
+an integer; @samp{info fun -t '(.*int.*'} finds the functions that
+have an argument type containing int; @samp{info fun -t '^int (' ^step}
+finds the functions whose names start with @code{step} and that are returning
+an int.
+
+
 @kindex info variables
-@item info variables
+@item info variables [-q]
 Print the names and data types of all variables that are defined
 outside of functions (i.e.@: excluding local variables).
 The printed variables are grouped by source files and annotated with
 their respective source line numbers.
 
-@item info variables @var{regexp}
+Flag @code{-q}, which stands for @samp{quiet}, disables printing
+header information and messages explaining why no variables have been
+printed.
+
+@item info variables [-q] [-t @var{type_regexp}] [@var{regexp}]
 Like @kbd{info variables}, but only print the names and data types of
-non-local variables whose names contain a match for regular expression
-@var{regexp}.
+non-local variables that matches the provided regexp(s).
+
+If @var{regexp} is provided, prints only the variables whose names
+contain a match for regular expression @var{regexp}.
+
+If @var{type_regexp} is provided, prints only the variables whose
+types contain a match for regular expression @var{type_regexp}.
+The matching is done with the variable type as printed with the
+@code{whatis} command.
+If @var{type_regexp} contains space(s), it should be enclosed in single
+quote characters.
 
 @kindex info classes
 @cindex Objective-C, classes and selectors
-- 
2.17.1

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

* [RFC 2/5] Make struct type_print_options default_ptype_flags non static.
  2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 4/5] Document changes " Philippe Waroquiers
@ 2018-07-01 21:07 ` Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers
  4 siblings, 0 replies; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Make struct type_print_options default_ptype_flags non static,
as this is needed in the type matching logic of
info [args|functions|locals|variables],
to ensure the type matching uses the same setting as the whatis command.
---
 gdb/typeprint.c | 5 +++--
 gdb/typeprint.h | 4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 7a0b7627ed..20925b7dcc 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -49,9 +49,10 @@ const struct type_print_options type_print_raw_options =
   NULL				/* global_printers */
 };
 
-/* The default flags for 'ptype' and 'whatis'.  */
 
-static struct type_print_options default_ptype_flags =
+/* See typeprint.h.  */
+
+struct type_print_options default_ptype_flags =
 {
   0,				/* raw */
   1,				/* print_methods */
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
index edd8c396c8..e098782cf4 100644
--- a/gdb/typeprint.h
+++ b/gdb/typeprint.h
@@ -105,6 +105,10 @@ struct type_print_options
 
 extern const struct type_print_options type_print_raw_options;
 
+/* The default flags for 'ptype' and 'whatis'.  */
+
+extern struct type_print_options default_ptype_flags;
+
 /* A hash table holding typedef_field objects.  This is more
    complicated than an ordinary hash because it must also track the
    lifetime of some -- but not all -- of the contained objects.  */
-- 
2.17.1

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

* [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]
@ 2018-07-01 21:07 Philippe Waroquiers
  2018-07-01 21:07 ` [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches

[RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]

This patch series adds flags and/or arguments
[-q] [-t TYPEREGEXP] [NAMEREGEXP] to the commands
  info [args|functions|locals|variables]

The additional arguments allow to more precisely specify what to print.
This patch series does not depend on
[RFA_v3 0/8] Implement 'frame apply COMMAND', enhance 'thread apply COMMAND'.
However, the new features above can usefully be combined with
frame apply and thread apply.
So, the documentation gives examples combining the above
and the 'thread apply' and 'frame apply' commands.

Some examples:
* print functions returning an int:
    info functions -t '^int ('
* print local variables having pthread_t type
    info locals -t pthread_t
* print global variables having type 'struct addrinfo'
    info var -t 'struct addrinfo'
* print args that are likely file descriptors
    info arg -t int .*fd.*

Below examples depends on the 'thread/frame apply' patch series.

* Assuming lock_something_t is an RAII type, show all locks:
  thread apply all -s frame apply all -s info locals -q -t lock_something_t
 or shorter equivalent:
  tfaas i lo -q -t lock_something_t

* show frames and args having an arg with type matchin std::.*map
  so likely  std::map or std::unordered_map
  frame apply all -s info args -q std::.*map


The code, documentation and NEWS is (supposed to be) complete.
ChangeLog and tests are still to be done.


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

* [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables]
  2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
                   ` (2 preceding siblings ...)
  2018-07-01 21:07 ` [RFC 2/5] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
@ 2018-07-01 21:07 ` Philippe Waroquiers
  2018-07-02 14:51   ` Eli Zaretskii
  2018-07-01 21:07 ` [RFC 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers
  4 siblings, 1 reply; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Announce changes in NEWS to info [args|functions|locals|variables]
---
 gdb/NEWS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 839466e7e0..74471b6a02 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -56,6 +56,17 @@ maint show check-libthread-db
   debugging libraries as they are loaded.  The default is not to
   perform such checks.
 
+* Changed commands
+
+info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
+  These commands can now print only the searched entities
+  matching the provided regexp(s), giving a condition
+  on the entity names or entity types.  The flag -q
+  disables printing headers or informations messages.
+
 * Python API
 
   ** Type alignment is now exposed via the "align" attribute of a gdb.Type.
-- 
2.17.1

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

* [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]
  2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
@ 2018-07-01 21:07 ` Philippe Waroquiers
  2018-07-02 15:06   ` Eli Zaretskii
  2018-07-01 21:07 ` [RFC 4/5] Document changes " Philippe Waroquiers
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-01 21:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Philippe Waroquiers

Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]

* stack.h: add two regexp args to iterate_over_block_arg_vars
  and iterate_over_block_local_vars, and update all impacted files/callers.

* symtab.h: add a new function bool treg_matches_sym_type_name, that
  factories type matching logic.

* symbtab.c: add type/name matching logic to 'info functions|variables'.

* stack.c : add type/name matching logic to 'info args|locals'.
---
 gdb/linespec.c        |   1 +
 gdb/mi/mi-cmd-stack.c |   1 +
 gdb/python/py-frame.c |   1 +
 gdb/python/python.c   |   4 +-
 gdb/skip.c            |   1 +
 gdb/stack.c           | 162 ++++++++++++++++++++++++++++++++++-------
 gdb/stack.h           |   4 +
 gdb/symfile.c         |   1 +
 gdb/symtab.c          | 165 ++++++++++++++++++++++++++++++++++++------
 gdb/symtab.h          |   8 +-
 gdb/tracepoint.c      |   8 +-
 11 files changed, 300 insertions(+), 56 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 2a4189278e..2503ec77ab 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -42,6 +42,7 @@
 #include "cli/cli-utils.h"
 #include "filenames.h"
 #include "ada-lang.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "location.h"
 #include "common/function-view.h"
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 52660bdd49..f109353a34 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -25,6 +25,7 @@
 #include "ui-out.h"
 #include "symtab.h"
 #include "block.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "dictionary.h"
 #include "language.h"
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index ec456e9e77..b566149f76 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -22,6 +22,7 @@
 #include "block.h"
 #include "frame.h"
 #include "symtab.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "value.h"
 #include "python-internal.h"
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 20fc674f20..b80c874c47 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -766,11 +766,11 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
     {
       const char **files = symtab_paths.vec.data ();
 
-      symbols = search_symbols (regex, FUNCTIONS_DOMAIN,
+      symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
 				symtab_paths.vec.size (), files);
     }
   else
-    symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL);
+    symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL);
 
   /* Count the number of symbols (both symbols and optionally minimal
      symbols) so we can correctly check the throttle limit.  */
diff --git a/gdb/skip.c b/gdb/skip.c
index 7a6f2e712b..b7f7b10167 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -24,6 +24,7 @@
 #include "gdbcmd.h"
 #include "command.h"
 #include "completer.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "cli/cli-utils.h"
 #include "arch-utils.h"
diff --git a/gdb/stack.c b/gdb/stack.c
index 13d8cf22b5..4ac7c739a0 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "frame.h"
 #include "gdbcmd.h"
+#include "gdb_regex.h"
 #include "gdbcore.h"
 #include "target.h"
 #include "source.h"
@@ -89,8 +90,10 @@ const char *print_entry_values = print_entry_values_default;
 
 /* Prototypes for local functions.  */
 
-static void print_frame_local_vars (struct frame_info *, int,
-				    struct ui_file *);
+static void print_frame_local_vars (struct frame_info *frame,
+				    bool quiet,
+				    const char *regexp, const char *t_regexp,
+				    int num_tabs, struct ui_file *stream);
 
 static void print_frame (struct frame_info *frame, int print_level,
 			 enum print_what print_what,  int print_args,
@@ -1792,7 +1795,7 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
 	    {
 	      struct frame_id frame_id = get_frame_id (fi);
 
-	      print_frame_local_vars (fi, 1, gdb_stdout);
+	      print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout);
 
 	      /* print_frame_local_vars invalidates FI.  */
 	      fi = frame_find_by_id (frame_id);
@@ -1866,10 +1869,14 @@ backtrace_command (const char *arg, int from_tty)
 }
 
 /* Iterate over the local variables of a block B, calling CB with
-   CB_DATA.  */
+   CB_DATA.
+   Only local variables with name/type matching PREG/TREG are iterated
+   on.  */
 
 static void
 iterate_over_block_locals (const struct block *b,
+			   const gdb::optional<compiled_regex> &preg,
+			   const gdb::optional<compiled_regex> &treg,
 			   iterate_over_block_arg_local_vars_cb cb,
 			   void *cb_data)
 {
@@ -1889,6 +1896,13 @@ iterate_over_block_locals (const struct block *b,
 	    break;
 	  if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
 	    break;
+	  if (preg
+	      && preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+			     NULL, 0) != 0)
+	    break;
+	  if (treg
+	      && !treg_matches_sym_type_name (*treg, sym))
+	    break;
 	  (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
 	  break;
 
@@ -1950,16 +1964,20 @@ print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
 #endif
 
 /* Iterate over all the local variables in block B, including all its
-   superblocks, stopping when the top-level block is reached.  */
+   superblocks, stopping when the top-level block is reached.
+   Only local variables with name/type matching PREG/TREG are iterated
+   on.  */
 
 void
 iterate_over_block_local_vars (const struct block *block,
+			       const gdb::optional<compiled_regex> &preg,
+			       const gdb::optional<compiled_regex> &treg,
 			       iterate_over_block_arg_local_vars_cb cb,
 			       void *cb_data)
 {
   while (block)
     {
-      iterate_over_block_locals (block, cb, cb_data);
+      iterate_over_block_locals (block, preg, treg, cb, cb_data);
       /* After handling the function's top-level block, stop.  Don't
 	 continue to its superblock, the block of per-file
 	 symbols.  */
@@ -2006,30 +2024,57 @@ do_print_variable_and_value (const char *print_name,
   p->values_printed = 1;
 }
 
+/* Prepares the regular expression REG from REGEXP.
+   If REGEXP is NULL, it results in an empty regular expression.  */
+static void
+prepare_reg (const char *regexp, gdb::optional<compiled_regex> &reg)
+{
+  if (regexp != NULL)
+    {
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+				? REG_ICASE : 0);
+      reg.emplace (regexp, cflags, _("Invalid regexp"));
+    }
+  else
+    reg.reset ();
+}
+
 /* Print all variables from the innermost up to the function block of FRAME.
    Print them with values to STREAM indented by NUM_TABS.
+   If REGEXP is not NULL, only print local variables whose name
+   matches REGEXP.
+   If T_REGEXP is not NULL, only print local variables whose type
+   matches T_REGEXP.
+   If no local variables have been printed and !QUIET, prints a message
+   explaining why no local variables could be printed.
 
    This function will invalidate FRAME.  */
 
 static void
-print_frame_local_vars (struct frame_info *frame, int num_tabs,
-			struct ui_file *stream)
+print_frame_local_vars (struct frame_info *frame,
+			bool quiet,
+			const char *regexp, const char *t_regexp,
+			int num_tabs, struct ui_file *stream)
 {
   struct print_variable_and_value_data cb_data;
   const struct block *block;
   CORE_ADDR pc;
+  gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   if (!get_frame_pc_if_available (frame, &pc))
     {
-      fprintf_filtered (stream,
-			_("PC unavailable, cannot determine locals.\n"));
+      if (!quiet)
+	fprintf_filtered (stream,
+			  _("PC unavailable, cannot determine locals.\n"));
       return;
     }
 
   block = get_frame_block (frame, 0);
   if (block == 0)
     {
-      fprintf_filtered (stream, "No symbol table info available.\n");
+      if (!quiet)
+	fprintf_filtered (stream, "No symbol table info available.\n");
       return;
     }
 
@@ -2038,31 +2083,53 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
   cb_data.stream = stream;
   cb_data.values_printed = 0;
 
+  prepare_reg (regexp, preg);
+  prepare_reg (t_regexp, treg);
+
   /* Temporarily change the selected frame to the given FRAME.
      This allows routines that rely on the selected frame instead
      of being given a frame as parameter to use the correct frame.  */
   scoped_restore_selected_frame restore_selected_frame;
   select_frame (frame);
 
-  iterate_over_block_local_vars (block,
+  iterate_over_block_local_vars (block, preg, treg,
 				 do_print_variable_and_value,
 				 &cb_data);
 
-  if (!cb_data.values_printed)
-    fprintf_filtered (stream, _("No locals.\n"));
+  if (!cb_data.values_printed && !quiet)
+    {
+    if (regexp == NULL && t_regexp == NULL)
+      fprintf_filtered (stream, _("No locals.\n"));
+    else
+      fprintf_filtered (stream, _("No matching locals.\n"));
+    }
 }
 
 void
 info_locals_command (const char *args, int from_tty)
 {
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info locals", &args, &quiet, &regexp, &t_regexp);
   print_frame_local_vars (get_selected_frame (_("No frame selected.")),
+			  quiet,
+			  regexp.empty () ? NULL : regexp.c_str (),
+			  t_regexp.empty () ? NULL : t_regexp.c_str (),
 			  0, gdb_stdout);
 }
 
-/* Iterate over all the argument variables in block B.  */
+/* Iterate over all the argument variables in block B.
+   If PREG has a value, only prints the argument variables
+   with name matching PREG.
+   If TREG has a value, only prints the argument variables
+   with type matching TREG.  */
 
 void
 iterate_over_block_arg_vars (const struct block *b,
+			     const gdb::optional<compiled_regex> &preg,
+			     const gdb::optional<compiled_regex> &treg,
 			     iterate_over_block_arg_local_vars_cb cb,
 			     void *cb_data)
 {
@@ -2072,7 +2139,12 @@ iterate_over_block_arg_vars (const struct block *b,
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
       /* Don't worry about things which aren't arguments.  */
-      if (SYMBOL_IS_ARGUMENT (sym))
+      if (SYMBOL_IS_ARGUMENT (sym)
+	  && (!preg
+	      || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+			     NULL, 0) == 0)
+	  && (!treg
+	      || treg_matches_sym_type_name (*treg, sym)))
 	{
 	  /* We have to look up the symbol because arguments can have
 	     two entries (one a parameter, one a local) and the one we
@@ -2084,7 +2156,6 @@ iterate_over_block_arg_vars (const struct block *b,
 	     symbol is double and the type of the LOC_LOCAL symbol is
 	     float).  There are also LOC_ARG/LOC_REGISTER pairs which
 	     are not combined in symbol-reading.  */
-
 	  sym2 = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
 					    b, VAR_DOMAIN).symbol;
 	  (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
@@ -2094,26 +2165,40 @@ iterate_over_block_arg_vars (const struct block *b,
 
 /* Print all argument variables of the function of FRAME.
    Print them with values to STREAM.
+   If REGEXP is not NULL, only print argument variables whose name
+   matches REGEXP.
+   If T_REGEXP is not NULL, only print argument variables whose type
+   matches T_REGEXP.
+   If no argument variables have been printed and !QUIET, prints a message
+   explaining why no argument variables could be printed.
 
    This function will invalidate FRAME.  */
 
 static void
-print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+print_frame_arg_vars (struct frame_info *frame,
+		      bool quiet,
+		      const char *regexp, const char *t_regexp,
+		      struct ui_file *stream)
 {
   struct print_variable_and_value_data cb_data;
   struct symbol *func;
   CORE_ADDR pc;
+  gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   if (!get_frame_pc_if_available (frame, &pc))
     {
-      fprintf_filtered (stream, _("PC unavailable, cannot determine args.\n"));
+      if (!quiet)
+	fprintf_filtered (stream,
+			  _("PC unavailable, cannot determine args.\n"));
       return;
     }
 
   func = get_frame_function (frame);
   if (func == NULL)
     {
-      fprintf_filtered (stream, _("No symbol table info available.\n"));
+      if (!quiet)
+	fprintf_filtered (stream, _("No symbol table info available.\n"));
       return;
     }
 
@@ -2122,20 +2207,37 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
   cb_data.stream = stream;
   cb_data.values_printed = 0;
 
+  prepare_reg (regexp, preg);
+  prepare_reg (t_regexp, treg);
+
   iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
+			       preg, treg,
 			       do_print_variable_and_value, &cb_data);
 
   /* do_print_variable_and_value invalidates FRAME.  */
   frame = NULL;
 
-  if (!cb_data.values_printed)
-    fprintf_filtered (stream, _("No arguments.\n"));
+  if (!cb_data.values_printed && !quiet)
+    {
+      if (regexp == NULL && t_regexp == NULL)
+	fprintf_filtered (stream, _("No arguments.\n"));
+      else
+	fprintf_filtered (stream, _("No matching arguments.\n"));
+    }
 }
 
 void
-info_args_command (const char *ignore, int from_tty)
+info_args_command (const char *args, int from_tty)
 {
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info args", &args, &quiet, &regexp, &t_regexp);
   print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
+			quiet,
+			regexp.empty () ? NULL : regexp.c_str (),
+			t_regexp.empty () ? NULL : t_regexp.c_str (),
 			gdb_stdout);
 }
 \f
@@ -2549,10 +2651,16 @@ on this backtrace."));
   add_info ("frame", info_frame_command,
 	    _("All about selected stack frame, or frame at ADDR."));
   add_info_alias ("f", "frame", 1);
-  add_info ("locals", info_locals_command,
-	    _("Local variables of current stack frame."));
-  add_info ("args", info_args_command,
-	    _("Argument variables of current stack frame."));
+  add_info ("locals", info_locals_command, _("\
+All local variables of current stack frame or those matching REGEXPs.\n\
+Usage: info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the local variables of the current stack frame.\n"
+INFO_PRINT_ARGS_HELP ("local variables")));
+  add_info ("args", info_args_command, _("\
+All argument variables of current stack frame or those matching REGEXPs.\n\
+Usage: info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the argument variables of the current stack frame.\n"
+INFO_PRINT_ARGS_HELP ("argument variables")));
 
   if (dbx_commands)
     add_com ("func", class_stack, func_command, _("\
diff --git a/gdb/stack.h b/gdb/stack.h
index ca190efa9c..c6924d5237 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -31,10 +31,14 @@ typedef void (*iterate_over_block_arg_local_vars_cb) (const char *print_name,
 						      void *cb_data);
 
 void iterate_over_block_arg_vars (const struct block *block,
+				  const gdb::optional<compiled_regex> &preg,
+				  const gdb::optional<compiled_regex> &treg,
 				  iterate_over_block_arg_local_vars_cb cb,
 				  void *cb_data);
 
 void iterate_over_block_local_vars (const struct block *block,
+				    const gdb::optional<compiled_regex> &preg,
+				    const gdb::optional<compiled_regex> &treg,
 				    iterate_over_block_arg_local_vars_cb cb,
 				    void *cb_data);
 
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 48eca5cc0e..cf200ec164 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -53,6 +53,7 @@
 #include "elf-bfd.h"
 #include "solib.h"
 #include "remote.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "gdb_bfd.h"
 #include "cli/cli-utils.h"
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d8a7a16e07..e998597135 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -43,6 +43,7 @@
 #include "cli/cli-utils.h"
 #include "fnmatch.h"
 #include "hashtab.h"
+#include "typeprint.h"
 
 #include "gdb_obstack.h"
 #include "block.h"
@@ -4265,6 +4266,51 @@ symbol_search::compare_search_syms (const symbol_search &sym_a,
 		 SYMBOL_PRINT_NAME (sym_b.symbol));
 }
 
+/* Returns true if the type_name of symbol_type of SYM matches TREG.
+   If SYM has no symbol_type or symbol_name, returns false.  */
+
+bool
+treg_matches_sym_type_name (const compiled_regex &treg,
+			    const struct symbol *sym)
+{
+  struct type *sym_type;
+  const char *sym_type_name;
+  string_file printed_sym_type_name;
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+			  "treg_matches_sym_type_name\n     sym %s\n",
+			  SYMBOL_NATURAL_NAME (sym));
+    }
+
+  sym_type = SYMBOL_TYPE (sym);
+  if (sym_type == NULL)
+    return false;
+
+  if (language_mode == language_mode_auto)
+    language_def (SYMBOL_LANGUAGE (sym))->la_print_type
+      (sym_type, "", &printed_sym_type_name,
+       -1, 0, &default_ptype_flags);
+  else
+    LA_PRINT_TYPE (sym_type, "", &printed_sym_type_name,
+		   -1, 0, &default_ptype_flags);
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+			  "     sym_type_name %s\n",
+			  printed_sym_type_name.c_str ());
+    }
+
+
+  if (printed_sym_type_name.empty ())
+    return false;
+
+  return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0;
+}
+
+
 /* Sort the symbols in RESULT and remove duplicates.  */
 
 static void
@@ -4280,7 +4326,9 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
    Only symbols of KIND are searched:
    VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
-                      and constants (enums)
+                      and constants (enums).
+		      if T_REGEXP is not NULL, only returns var that have
+		      a type matching regular expression T_REGEXP.
    FUNCTIONS_DOMAIN - search all functions
    TYPES_DOMAIN     - search all type names
    ALL_DOMAIN       - an internal error for this function
@@ -4291,6 +4339,7 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
 std::vector<symbol_search>
 search_symbols (const char *regexp, enum search_domain kind,
+		const char *t_regexp,
 		int nfiles, const char *files[])
 {
   struct compunit_symtab *cust;
@@ -4316,6 +4365,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   enum minimal_symbol_type ourtype4;
   std::vector<symbol_search> result;
   gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   gdb_assert (kind <= TYPES_DOMAIN);
 
@@ -4365,6 +4415,13 @@ search_symbols (const char *regexp, enum search_domain kind,
       preg.emplace (regexp, cflags, _("Invalid regexp"));
     }
 
+  if (t_regexp != NULL)
+    {
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+				? REG_ICASE : 0);
+      treg.emplace (t_regexp, cflags, _("Invalid regexp"));
+    }
+
   /* Search through the partial symtabs *first* for all symbols
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below.  */
@@ -4463,9 +4520,13 @@ search_symbols (const char *regexp, enum search_domain kind,
 			    We only want to skip enums here.  */
 			 && !(SYMBOL_CLASS (sym) == LOC_CONST
 			      && (TYPE_CODE (SYMBOL_TYPE (sym))
-				  == TYPE_CODE_ENUM)))
-			|| (kind == FUNCTIONS_DOMAIN 
-			    && SYMBOL_CLASS (sym) == LOC_BLOCK)
+				  == TYPE_CODE_ENUM))
+			 && (!treg
+			     || treg_matches_sym_type_name (*treg, sym)))
+			|| (kind == FUNCTIONS_DOMAIN
+			    && SYMBOL_CLASS (sym) == LOC_BLOCK
+			    && (!treg
+				|| treg_matches_sym_type_name (*treg, sym)))
 			|| (kind == TYPES_DOMAIN
 			    && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
 	      {
@@ -4496,8 +4557,12 @@ search_symbols (const char *regexp, enum search_domain kind,
 	    || MSYMBOL_TYPE (msymbol) == ourtype3
 	    || MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
-				     NULL, 0) == 0)
+	    /* If the user wants to see var matching a type regexp,
+	       then never give a minimal symbol.  */
+	    if (kind != VARIABLES_DOMAIN
+		&& !treg /* a minimal symbol has never a type ???? */
+		&& (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+					 NULL, 0) == 0))
 	      {
 		/* For functions we can do a quick check of whether the
 		   symbol might be found via find_pc_symtab.  */
@@ -4598,7 +4663,9 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
    matches.  */
 
 static void
-symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
+symtab_symbol_info (bool quiet,
+		    const char *regexp, enum search_domain kind,
+		    const char *t_regexp, int from_tty)
 {
   static const char * const classnames[] =
     {"variable", "function", "type"};
@@ -4608,13 +4675,33 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
   gdb_assert (kind <= TYPES_DOMAIN);
 
   /* Must make sure that if we're interrupted, symbols gets freed.  */
-  std::vector<symbol_search> symbols = search_symbols (regexp, kind, 0, NULL);
+  std::vector<symbol_search> symbols = search_symbols (regexp, kind,
+						       t_regexp, 0, NULL);
 
-  if (regexp != NULL)
-    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
-		     classnames[kind], regexp);
-  else
-    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+  if (!quiet)
+    {
+      if (regexp != NULL)
+	{
+	  if (t_regexp != NULL)
+	    printf_filtered
+	      (_("All %ss matching regular expression \"%s\""
+		 " with type matching regulation expression \"%s\" :\n"),
+	       classnames[kind], regexp, t_regexp);
+	  else
+	    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
+			     classnames[kind], regexp);
+	}
+      else
+	{
+	  if (t_regexp != NULL)
+	    printf_filtered
+	      (_("All defined %ss"
+		 " with type matching regulation expression \"%s\" :\n"),
+	       classnames[kind], t_regexp);
+	  else
+	    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+	}
+    }
 
   for (const symbol_search &p : symbols)
     {
@@ -4624,7 +4711,8 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 	{
 	  if (first)
 	    {
-	      printf_filtered (_("\nNon-debugging symbols:\n"));
+	      if (!quiet)
+		printf_filtered (_("\nNon-debugging symbols:\n"));
 	      first = 0;
 	    }
 	  print_msymbol_info (p.msymbol);
@@ -4642,22 +4730,41 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 }
 
 static void
-info_variables_command (const char *regexp, int from_tty)
+info_variables_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info variables", &args, &quiet, &regexp, &t_regexp);
+  symtab_symbol_info (quiet,
+		      regexp.empty () ? NULL : regexp.c_str (),
+		      VARIABLES_DOMAIN,
+		      t_regexp.empty () ? NULL : t_regexp.c_str (),
+		      from_tty);
 }
 
+
 static void
-info_functions_command (const char *regexp, int from_tty)
+info_functions_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet;
+
+  extract_info_print_args ("info functions", &args, &quiet, &regexp, &t_regexp);
+  symtab_symbol_info (quiet,
+		      regexp.empty () ? NULL : regexp.c_str (),
+		      FUNCTIONS_DOMAIN,
+		      t_regexp.empty () ? NULL : t_regexp.c_str (),
+		      from_tty);
 }
 
 
 static void
 info_types_command (const char *regexp, int from_tty)
 {
-  symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty);
+  symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty);
 }
 
 /* Breakpoint all functions matching regular expression.  */
@@ -4700,6 +4807,7 @@ rbreak_command (const char *regexp, int from_tty)
 
   std::vector<symbol_search> symbols = search_symbols (regexp,
 						       FUNCTIONS_DOMAIN,
+						       NULL,
 						       nfiles, files);
 
   scoped_rbreak_breakpoints finalize;
@@ -5902,13 +6010,22 @@ _initialize_symtab (void)
     = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup);
 
   add_info ("variables", info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
+All global and static variable names or those matching REGEXPs.\n\
+Usage: info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"
+INFO_PRINT_ARGS_HELP ("global and static variables")));
   if (dbx_commands)
     add_com ("whereis", class_info, info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
-
-  add_info ("functions", info_functions_command,
-	    _("All function names, or those matching REGEXP."));
+All global and static variable names, or those matching REGEXPs.\n\
+Usage: whereis [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"
+INFO_PRINT_ARGS_HELP ("global and static variables")));
+
+  add_info ("functions", info_functions_command, _("\
+All function names or those matching REGEXPs.\n\
+Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the functions.\n"
+INFO_PRINT_ARGS_HELP ("functions")));
 
   /* FIXME:  This command has at least the following problems:
      1.  It prints builtin types (in a very strange and confusing fashion).
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 0b155d0659..b7ead5b5c4 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -25,6 +25,7 @@
 #include <string>
 #include "gdb_vecs.h"
 #include "gdbtypes.h"
+#include "gdb_regex.h"
 #include "common/enum-flags.h"
 #include "common/function-view.h"
 #include "common/gdb_optional.h"
@@ -2012,8 +2013,13 @@ private:
 };
 
 extern std::vector<symbol_search> search_symbols (const char *,
-						  enum search_domain, int,
+						  enum search_domain,
+						  const char *,
+						  int,
 						  const char **);
+extern bool
+treg_matches_sym_type_name (const compiled_regex &treg,
+			    const struct symbol *sym);
 
 /* The name of the ``main'' function.
    FIXME: cagney/2001-03-20: Can't make main_name() const since some
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 5af3cfe202..646e5a15c4 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -43,6 +43,7 @@
 #include "objfiles.h"
 #include "filenames.h"
 #include "gdbthread.h"
+#include "gdb_regex.h"
 #include "stack.h"
 #include "remote.h"
 #include "source.h"
@@ -1038,6 +1039,7 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 {
   const struct block *block;
   struct add_local_symbols_data cb_data;
+  const gdb::optional<compiled_regex> nullreg;
 
   cb_data.collect = this;
   cb_data.gdbarch = gdbarch;
@@ -1057,7 +1059,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 	  return;
 	}
 
-      iterate_over_block_local_vars (block, do_collect_symbol, &cb_data);
+      iterate_over_block_local_vars (block, nullreg, nullreg,
+				     do_collect_symbol, &cb_data);
       if (cb_data.count == 0)
 	warning (_("No locals found in scope."));
     }
@@ -1071,7 +1074,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
 	  return;
 	}
 
-      iterate_over_block_arg_vars (block, do_collect_symbol, &cb_data);
+      iterate_over_block_arg_vars (block, nullreg, nullreg,
+				   do_collect_symbol, &cb_data);
       if (cb_data.count == 0)
 	warning (_("No args found in scope."));
     }
-- 
2.17.1

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

* Re: [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables]
  2018-07-01 21:07 ` [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-02 14:51   ` Eli Zaretskii
  0 siblings, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2018-07-02 14:51 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Sun,  1 Jul 2018 23:07:34 +0200
> 
> Announce changes in NEWS to info [args|functions|locals|variables]
> ---
>  gdb/NEWS | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 839466e7e0..74471b6a02 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -56,6 +56,17 @@ maint show check-libthread-db
>    debugging libraries as they are loaded.  The default is not to
>    perform such checks.
>  
> +* Changed commands
> +
> +info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]
> +info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]
> +info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]
> +info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
> +  These commands can now print only the searched entities
> +  matching the provided regexp(s), giving a condition
> +  on the entity names or entity types.  The flag -q
> +  disables printing headers or informations messages.
> +
>  * Python API
>  
>    ** Type alignment is now exposed via the "align" attribute of a gdb.Type.

Thanks, this is OK.

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

* Re: [RFC 4/5] Document changes to info [args|functions|locals|variables]
  2018-07-01 21:07 ` [RFC 4/5] Document changes " Philippe Waroquiers
@ 2018-07-02 15:02   ` Eli Zaretskii
  2018-07-02 20:46     ` Philippe Waroquiers
  0 siblings, 1 reply; 11+ messages in thread
From: Eli Zaretskii @ 2018-07-02 15:02 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Sun,  1 Jul 2018 23:07:33 +0200
> 
> Document changes to info [args|functions|locals|variables]

Thanks, I have a few comments:

>  gdb/doc/gdb.texinfo | 98 ++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 88 insertions(+), 10 deletions(-)

Please provide a ChangeLog entry for gdb/doc/ChangeLog.

> -@item info args
> +@item info args [-q]
>  Print the arguments of the selected frame, each on a separate line.
>  
> +Flag @code{-q}, which stands for @samp{quiet}, disables printing
> +header information and messages explaining why no argument have been
> +printed.

This sentence sounds awkward.  Suggest to rephrase the beginning:

  The optional flag @samp{-q}, which stands for @samp{quiet},
  disables printing ...

> +@item info args [-q] [-t @var{type_regexp}] [@var{regexp}]
> +Like @kbd{info args}, but only print the arguments
> +that matches the provided regexp(s).
        ^^^^^^^
"match", in plural.

> +If @var{regexp} is provided, prints only the arguments whose names
                                ^^^^^^
Please be consistent: or "print" everywhere, or "prints" everywhere.

> +If @var{type_regexp} is provided, prints only the arguments whose
> +types contain a match for regular expression @var{type_regexp}.

Is there any significance in "contain a match" vs just "match" above?
If not, I suggest to use the same wording.

Also, the above begs the question: what if I specify both REGEXP and
TYPE_REGEXP?  Is that allowed?

> +The matching is done with the variable type as printed with the
> +@code{whatis} command.                                 ^^^^

"by"

> +If @var{type_regexp} contains space(s), it should be enclosed in single
> +quote characters.

Only single quotes?  Double quotes are not supported?  Should they be?

Same comments to all the other commands where you introduce these
optional arguments.

> +The command @samp{info locals -q -t @var{type_regexp}} can usefully be
               ^^^^^
@kbd, not @samp.  You are showing a command that the user would type.

> +combined with the commands @samp{frame apply} and @samp{thread apply}.

Likewise.

> +For example, if you have an RAII type @code{lock_something_t},

Do we have "RAII" explained anywhere in the manual?  I don't think so,
in which case we should have here what it stands for.

> +you can list all locks in your program by doing
> +@samp{thread apply all -s frame apply all -s
> +info locals -q -t lock_something_t}, or the equivalent shorter form
> +@samp{tfaas i lo -q -t lock_something_t}.

It is best to show such long commands as @smallexample, broken into
several lines as needed.

Thanks.

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

* Re: [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]
  2018-07-01 21:07 ` [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
@ 2018-07-02 15:06   ` Eli Zaretskii
  0 siblings, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2018-07-02 15:06 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Sun,  1 Jul 2018 23:07:32 +0200
> 
> +  if (!cb_data.values_printed && !quiet)
> +    {
> +    if (regexp == NULL && t_regexp == NULL)
> +      fprintf_filtered (stream, _("No locals.\n"));
> +    else
> +      fprintf_filtered (stream, _("No matching locals.\n"));
> +    }

I believe this is not our indentation style.

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

* Re: [RFC 4/5] Document changes to info [args|functions|locals|variables]
  2018-07-02 15:02   ` Eli Zaretskii
@ 2018-07-02 20:46     ` Philippe Waroquiers
  2018-07-04 16:44       ` Eli Zaretskii
  0 siblings, 1 reply; 11+ messages in thread
From: Philippe Waroquiers @ 2018-07-02 20:46 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On Mon, 2018-07-02 at 18:02 +0300, Eli Zaretskii wrote:
Thanks for your comments.
Find some feedback below (no feedback means the comment
was handled as you suggested).
I will resubmit the whole doc for review for the first RFA,
handling your
additional comments on the below, if you have some.

> > From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> > Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> > Date: Sun,  1 Jul 2018 23:07:33 +0200
> > 
> > Document changes to info [args|functions|locals|variables]
> 
> Thanks, I have a few comments:
> 
> >  gdb/doc/gdb.texinfo | 98 ++++++++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 88 insertions(+), 10 deletions(-)
> 
> Please provide a ChangeLog entry for gdb/doc/ChangeLog.
Will do for the RFA.


> Is there any significance in "contain a match" vs just "match" above?
> If not, I suggest to use the same wording.
Yes, I think that 'contain a match' is the precise condition verified.
Here is the (full) doc for the 'info locals', where I have reworded
the explanation. The other commands have been changed in the same
way.

@item info locals
@kindex info locals [-q]
Print the local variables of the selected frame, each on a separate
line.  These are all variables (declared either static or automatic)
accessible at the point of execution of the selected frame.

The optional flag @samp{-q}, which stands for @samp{quiet}, disables
printing header information and messages explaining why no local variables
have been printed.

@item info locals [-q] [-t @var{type_regexp}] [@var{regexp}]
Like @kbd{info locals}, but only print the local variables selected
with the provided regexp(s).

If @var{regexp} is provided, print only the local variables whose names
contain a match for regular expression @var{regexp}.

If @var{type_regexp} is provided, print only the local variables whose
types contain a match for regular expression @var{type_regexp}.
The matching is done with the local variable type as printed by the
@code{whatis} command.
If @var{type_regexp} contains space(s), it should be enclosed in single
quote characters.

If both @var{regexp} and @var{type_regexp} are provided, a local variable
is printed only if it respects the two regexps.

The command @kbd{info locals -q -t @var{type_regexp}} can usefully be
combined with the commands @kbd{frame apply} and @kbd{thread apply}.
For example, your program might use Resource Acquisition Is
Initialization types (RAII) such as @code{lock_something_t} : each
local variable of type @code{lock_something_t} automatically places a
lock that is destroyed when the variable goes out of scope.  You can
then list all acquired locks in your program by doing
@smallexample
thread apply all -s frame apply all -s info locals -q -t lock_something_t
@end smallexample
or the equivalent shorter form
@smallexample
tfaas i lo -q -t lock_something_t
@end smallexample

> 
> Also, the above begs the question: what if I specify both REGEXP and
> TYPE_REGEXP?  Is that allowed?
Yes, it is allowed. The doc above now explicitly describes the behaviour
when both REGEXP are provided.

> > +If @var{type_regexp} contains space(s), it should be enclosed in single
> > +quote characters.
> 
> Only single quotes?  Double quotes are not supported?  Should they be?
I do not think there is a need to support double quotes.
E.g. completer.c also only uses single quote to quote completion strings.

> 
> Do we have "RAII" explained anywhere in the manual?  I don't think so,
> in which case we should have here what it stands for.
I have tried to explain RAII in the doc above, but wondering if that
is clear enough.
If not, we might maybe put a reference to e.g. the wikipedia article 
https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
if such references are deemed ok in the GDB manual.

Thanks again for the review

Philippe

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

* Re: [RFC 4/5] Document changes to info [args|functions|locals|variables]
  2018-07-02 20:46     ` Philippe Waroquiers
@ 2018-07-04 16:44       ` Eli Zaretskii
  0 siblings, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2018-07-04 16:44 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: gdb-patches@sourceware.org
> Date: Mon, 02 Jul 2018 22:45:28 +0200
> 
> If both @var{regexp} and @var{type_regexp} are provided, a local variable
> is printed only if it respects the two regexps.

I'd use "matches", not "respects".

> The command @kbd{info locals -q -t @var{type_regexp}} can usefully be
> combined with the commands @kbd{frame apply} and @kbd{thread apply}.
> For example, your program might use Resource Acquisition Is
> Initialization types (RAII) such as @code{lock_something_t} : each
> local variable of type @code{lock_something_t} automatically places a
> lock that is destroyed when the variable goes out of scope.  You can
> then list all acquired locks in your program by doing
> @smallexample
> thread apply all -s frame apply all -s info locals -q -t lock_something_t
> @end smallexample
> or the equivalent shorter form

You want @noindent on a separate line before the "or the equivalent",
otherwise the printed manual will have that indented as if it were a
new paragraph (which it isn't).

> I have tried to explain RAII in the doc above, but wondering if that
> is clear enough.

I think it's enough, they can google it if they want to know more.

Thanks, I have no more comments to the new text except the above few
nits.

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

end of thread, other threads:[~2018-07-04 16:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-01 21:07 [RFC 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers
2018-07-01 21:07 ` [RFC 3/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers
2018-07-02 15:06   ` Eli Zaretskii
2018-07-01 21:07 ` [RFC 4/5] Document changes " Philippe Waroquiers
2018-07-02 15:02   ` Eli Zaretskii
2018-07-02 20:46     ` Philippe Waroquiers
2018-07-04 16:44       ` Eli Zaretskii
2018-07-01 21:07 ` [RFC 2/5] Make struct type_print_options default_ptype_flags non static Philippe Waroquiers
2018-07-01 21:07 ` [RFC 5/5] Announce changes in NEWS to info [args|functions|locals|variables] Philippe Waroquiers
2018-07-02 14:51   ` Eli Zaretskii
2018-07-01 21:07 ` [RFC 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers

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