gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / stack.c
index 9b0e740beb50e597df9eef1c650a76caad4cf020..265e764dc242dca48dda56da9ef5ea69fbf11d79 100644 (file)
@@ -1,6 +1,6 @@
 /* Print and select stack frames for GDB, the GNU debugger.
 
 /* Print and select stack frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #include "linespec.h"
 #include "cli/cli-utils.h"
 #include "objfiles.h"
 #include "linespec.h"
 #include "cli/cli-utils.h"
 #include "objfiles.h"
+#include "annotate.h"
 
 #include "symfile.h"
 #include "extension.h"
 #include "observable.h"
 
 #include "symfile.h"
 #include "extension.h"
 #include "observable.h"
-#include "common/def-vector.h"
+#include "gdbsupport/def-vector.h"
+#include "cli/cli-option.h"
+#include "cli/cli-style.h"
 
 /* The possible choices of "set print frame-arguments", and the value
    of this setting.  */
 
 
 /* The possible choices of "set print frame-arguments", and the value
    of this setting.  */
 
+const char print_frame_arguments_all[] = "all";
+const char print_frame_arguments_scalars[] = "scalars";
+const char print_frame_arguments_none[] = "none";
+const char print_frame_arguments_presence[] = "presence";
+
 static const char *const print_frame_arguments_choices[] =
 static const char *const print_frame_arguments_choices[] =
-  {"all", "scalars", "none", NULL};
-static const char *print_frame_arguments = "scalars";
+{
+  print_frame_arguments_all,
+  print_frame_arguments_scalars,
+  print_frame_arguments_none,
+  print_frame_arguments_presence,
+  NULL
+};
 
 
-/* If non-zero, don't invoke pretty-printers for frame arguments.  */
-static int print_raw_frame_arguments;
+/* The possible choices of "set print frame-info", and the value
+   of this setting.  */
+
+const char print_frame_info_auto[] = "auto";
+const char print_frame_info_source_line[] = "source-line";
+const char print_frame_info_location[] = "location";
+const char print_frame_info_source_and_location[] = "source-and-location";
+const char print_frame_info_location_and_address[] = "location-and-address";
+const char print_frame_info_short_location[] = "short-location";
+
+static const char *const print_frame_info_choices[] =
+{
+  print_frame_info_auto,
+  print_frame_info_source_line,
+  print_frame_info_location,
+  print_frame_info_source_and_location,
+  print_frame_info_location_and_address,
+  print_frame_info_short_location,
+  NULL
+};
+
+/* print_frame_info_print_what[i] maps a choice to the corresponding
+   print_what enum.  */
+static const gdb::optional<enum print_what> print_frame_info_print_what[] =
+  {{}, /* Empty value for "auto".  */
+   SRC_LINE, LOCATION, SRC_AND_LOC, LOC_AND_ADDRESS, SHORT_LOCATION};
 
 /* The possible choices of "set print entry-values", and the value
    of this setting.  */
 
 /* The possible choices of "set print entry-values", and the value
    of this setting.  */
@@ -84,23 +121,109 @@ static const char *const print_entry_values_choices[] =
   print_entry_values_default,
   NULL
 };
   print_entry_values_default,
   NULL
 };
-const char *print_entry_values = print_entry_values_default;
+
+/* See frame.h.  */
+frame_print_options user_frame_print_options;
+
+/* Option definitions for some frame-related "set print ..."
+   settings.  */
+
+using boolean_option_def
+  = gdb::option::boolean_option_def<frame_print_options>;
+using enum_option_def
+  = gdb::option::enum_option_def<frame_print_options>;
+
+static const gdb::option::option_def frame_print_option_defs[] = {
+
+  enum_option_def {
+    "entry-values",
+    print_entry_values_choices,
+    [] (frame_print_options *opt) { return &opt->print_entry_values; },
+    NULL, /* show_cmd_cb */
+    N_("Set printing of function arguments at function entry."),
+    N_("Show printing of function arguments at function entry."),
+    N_("GDB can sometimes determine the values of function arguments at entry,\n\
+in addition to their current values.  This option tells GDB whether\n\
+to print the current value, the value at entry (marked as val@entry),\n\
+or both.  Note that one or both of these values may be <optimized out>."),
+  },
+
+  enum_option_def {
+    "frame-arguments",
+    print_frame_arguments_choices,
+    [] (frame_print_options *opt) { return &opt->print_frame_arguments; },
+    NULL, /* show_cmd_cb */
+    N_("Set printing of non-scalar frame arguments."),
+    N_("Show printing of non-scalar frame arguments."),
+    NULL /* help_doc */
+  },
+
+  boolean_option_def {
+    "raw-frame-arguments",
+    [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },
+    NULL, /* show_cmd_cb */
+    N_("Set whether to print frame arguments in raw form."),
+    N_("Show whether to print frame arguments in raw form."),
+    N_("If set, frame arguments are printed in raw form, bypassing any\n\
+pretty-printers for that value.")
+  },
+
+  enum_option_def {
+    "frame-info",
+    print_frame_info_choices,
+    [] (frame_print_options *opt) { return &opt->print_frame_info; },
+    NULL, /* show_cmd_cb */
+    N_("Set printing of frame information."),
+    N_("Show printing of frame information."),
+    NULL /* help_doc */
+  }
+
+};
+
+/* Options for the "backtrace" command.  */
+
+struct backtrace_cmd_options
+{
+  bool full = false;
+  bool no_filters = false;
+  bool hide = false;
+};
+
+using bt_flag_option_def
+  = gdb::option::flag_option_def<backtrace_cmd_options>;
+
+static const gdb::option::option_def backtrace_command_option_defs[] = {
+  bt_flag_option_def {
+    "full",
+    [] (backtrace_cmd_options *opt) { return &opt->full; },
+    N_("Print values of local variables.")
+  },
+
+  bt_flag_option_def {
+    "no-filters",
+    [] (backtrace_cmd_options *opt) { return &opt->no_filters; },
+    N_("Prohibit frame filters from executing on a backtrace."),
+  },
+
+  bt_flag_option_def {
+    "hide",
+    [] (backtrace_cmd_options *opt) { return &opt->hide; },
+    N_("Causes Python frame filter elided frames to not be printed."),
+  },
+};
 
 /* Prototypes for local functions.  */
 
 
 /* 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,
+static void print_frame (const frame_print_options &opts,
+                        frame_info *frame, int print_level,
                         enum print_what print_what,  int print_args,
                         struct symtab_and_line sal);
 
                         enum print_what print_what,  int print_args,
                         struct symtab_and_line sal);
 
-static void set_last_displayed_sal (int valid,
-                                   struct program_space *pspace,
-                                   CORE_ADDR addr,
-                                   struct symtab *symtab,
-                                   int line);
-
 static struct frame_info *find_frame_for_function (const char *);
 static struct frame_info *find_frame_for_address (CORE_ADDR);
 
 static struct frame_info *find_frame_for_function (const char *);
 static struct frame_info *find_frame_for_address (CORE_ADDR);
 
@@ -112,19 +235,84 @@ static struct frame_info *find_frame_for_address (CORE_ADDR);
 
 int annotation_level = 0;
 
 
 int annotation_level = 0;
 
-/* These variables hold the last symtab and line we displayed to the user.
- * This is where we insert a breakpoint or a skiplist entry by default.  */
-static int last_displayed_sal_valid = 0;
-static struct program_space *last_displayed_pspace = 0;
-static CORE_ADDR last_displayed_addr = 0;
-static struct symtab *last_displayed_symtab = 0;
-static int last_displayed_line = 0;
+/* Class used to manage tracking the last symtab we displayed.  */
+
+class last_displayed_symtab_info_type
+{
+public:
+  /* True if the cached information is valid.  */
+  bool is_valid () const
+  { return m_valid; }
+
+  /* Return the cached program_space.  If the cache is invalid nullptr is
+     returned.  */
+  struct program_space *pspace () const
+  { return m_pspace; }
+
+  /* Return the cached CORE_ADDR address.  If the cache is invalid 0 is
+     returned.  */
+  CORE_ADDR address () const
+  { return m_address; }
+
+  /* Return the cached symtab.  If the cache is invalid nullptr is
+     returned.  */
+  struct symtab *symtab () const
+  { return m_symtab; }
+
+  /* Return the cached line number.  If the cache is invalid 0 is
+     returned.  */
+  int line () const
+  { return m_line; }
+
+  /* Invalidate the cache, reset all the members to their default value.  */
+  void invalidate ()
+  {
+    m_valid = false;
+    m_pspace = nullptr;
+    m_address = 0;
+    m_symtab = nullptr;
+    m_line = 0;
+  }
+
+  /* Store a new set of values in the cache.  */
+  void set (struct program_space *pspace, CORE_ADDR address,
+           struct symtab *symtab, int line)
+  {
+    gdb_assert (pspace != nullptr);
+
+    m_valid = true;
+    m_pspace = pspace;
+    m_address = address;
+    m_symtab = symtab;
+    m_line = line;
+  }
+
+private:
+  /* True when the cache is valid.  */
+  bool m_valid = false;
+
+  /* The last program space displayed.  */
+  struct program_space *m_pspace = nullptr;
+
+  /* The last address displayed.  */
+  CORE_ADDR m_address = 0;
+
+  /* The last symtab displayed.  */
+  struct symtab *m_symtab = nullptr;
+
+  /* The last line number displayed.  */
+  int m_line = 0;
+};
+
+/* An actual instance of the cache, holds information about the last symtab
+   displayed.  */
+static last_displayed_symtab_info_type last_displayed_symtab_info;
+
 \f
 
 \f
 
-/* Return 1 if we should display the address in addition to the location,
-   because we are in the middle of a statement.  */
+/* See stack.h.  */
 
 
-static int
+bool
 frame_show_address (struct frame_info *frame,
                    struct symtab_and_line sal)
 {
 frame_show_address (struct frame_info *frame,
                    struct symtab_and_line sal)
 {
@@ -139,10 +327,10 @@ frame_show_address (struct frame_info *frame,
        gdb_assert (inline_skipped_frames (inferior_thread ()) > 0);
       else
        gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
        gdb_assert (inline_skipped_frames (inferior_thread ()) > 0);
       else
        gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
-      return 0;
+      return false;
     }
 
     }
 
-  return get_frame_pc (frame) != sal.pc;
+  return get_frame_pc (frame) != sal.pc || !sal.is_stmt;
 }
 
 /* See frame.h.  */
 }
 
 /* See frame.h.  */
@@ -169,21 +357,21 @@ print_stack_frame (struct frame_info *frame, int print_level,
                   int set_current_sal)
 {
 
                   int set_current_sal)
 {
 
-  /* For mi, alway print location and address.  */
+  /* For mi, always print location and address.  */
   if (current_uiout->is_mi_like_p ())
     print_what = LOC_AND_ADDRESS;
 
   if (current_uiout->is_mi_like_p ())
     print_what = LOC_AND_ADDRESS;
 
-  TRY
+  try
     {
     {
-      print_frame_info (frame, print_level, print_what, 1 /* print_args */,
+      print_frame_info (user_frame_print_options,
+                       frame, print_level, print_what, 1 /* print_args */,
                        set_current_sal);
       if (set_current_sal)
        set_current_sal_from_frame (frame);
     }
                        set_current_sal);
       if (set_current_sal)
        set_current_sal_from_frame (frame);
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
     }
     {
     }
-  END_CATCH
 }
 
 /* Print nameless arguments of frame FRAME on STREAM, where START is
 }
 
 /* Print nameless arguments of frame FRAME on STREAM, where START is
@@ -221,13 +409,13 @@ print_frame_nameless_args (struct frame_info *frame, long start, int num,
    read in.
 
    Errors are printed as if they would be the parameter value.  Use zeroed ARG
    read in.
 
    Errors are printed as if they would be the parameter value.  Use zeroed ARG
-   iff it should not be printed accoring to user settings.  */
+   iff it should not be printed according to user settings.  */
 
 static void
 
 static void
-print_frame_arg (const struct frame_arg *arg)
+print_frame_arg (const frame_print_options &fp_opts,
+                const struct frame_arg *arg)
 {
   struct ui_out *uiout = current_uiout;
 {
   struct ui_out *uiout = current_uiout;
-  const char *error_message = NULL;
 
   string_file stb;
 
 
   string_file stb;
 
@@ -239,37 +427,41 @@ print_frame_arg (const struct frame_arg *arg)
 
   annotate_arg_emitter arg_emitter;
   ui_out_emit_tuple tuple_emitter (uiout, NULL);
 
   annotate_arg_emitter arg_emitter;
   ui_out_emit_tuple tuple_emitter (uiout, NULL);
-  fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
-                          SYMBOL_LANGUAGE (arg->sym), DMGL_PARAMS | DMGL_ANSI);
+  fprintf_symbol_filtered (&stb, arg->sym->print_name (),
+                          arg->sym->language (), DMGL_PARAMS | DMGL_ANSI);
   if (arg->entry_kind == print_entry_values_compact)
     {
       /* It is OK to provide invalid MI-like stream as with
         PRINT_ENTRY_VALUE_COMPACT we never use MI.  */
       stb.puts ("=");
 
   if (arg->entry_kind == print_entry_values_compact)
     {
       /* It is OK to provide invalid MI-like stream as with
         PRINT_ENTRY_VALUE_COMPACT we never use MI.  */
       stb.puts ("=");
 
-      fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
-                              SYMBOL_LANGUAGE (arg->sym),
+      fprintf_symbol_filtered (&stb, arg->sym->print_name (),
+                              arg->sym->language (),
                               DMGL_PARAMS | DMGL_ANSI);
     }
   if (arg->entry_kind == print_entry_values_only
       || arg->entry_kind == print_entry_values_compact)
     stb.puts ("@entry");
                               DMGL_PARAMS | DMGL_ANSI);
     }
   if (arg->entry_kind == print_entry_values_only
       || arg->entry_kind == print_entry_values_compact)
     stb.puts ("@entry");
-  uiout->field_stream ("name", stb);
+  uiout->field_stream ("name", stb, variable_name_style.style ());
   annotate_arg_name_end ();
   uiout->text ("=");
 
   annotate_arg_name_end ();
   uiout->text ("=");
 
+  ui_file_style style;
   if (!arg->val && !arg->error)
     uiout->text ("...");
   else
     {
       if (arg->error)
   if (!arg->val && !arg->error)
     uiout->text ("...");
   else
     {
       if (arg->error)
-       error_message = arg->error;
+       {
+         stb.printf (_("<error reading variable: %s>"), arg->error.get ());
+         style = metadata_style.style ();
+       }
       else
        {
       else
        {
-         TRY
+         try
            {
              const struct language_defn *language;
            {
              const struct language_defn *language;
-             struct value_print_options opts;
+             struct value_print_options vp_opts;
 
              /* Avoid value_print because it will deref ref parameters.  We
                 just want to print their addresses.  Print ??? for args whose
 
              /* Avoid value_print because it will deref ref parameters.  We
                 just want to print their addresses.  Print ??? for args whose
@@ -282,30 +474,30 @@ print_frame_arg (const struct frame_arg *arg)
              /* Use the appropriate language to display our symbol, unless the
                 user forced the language to a specific language.  */
              if (language_mode == language_mode_auto)
              /* Use the appropriate language to display our symbol, unless the
                 user forced the language to a specific language.  */
              if (language_mode == language_mode_auto)
-               language = language_def (SYMBOL_LANGUAGE (arg->sym));
+               language = language_def (arg->sym->language ());
              else
                language = current_language;
 
              else
                language = current_language;
 
-             get_no_prettyformat_print_options (&opts);
-             opts.deref_ref = 1;
-             opts.raw = print_raw_frame_arguments;
+             get_no_prettyformat_print_options (&vp_opts);
+             vp_opts.deref_ref = 1;
+             vp_opts.raw = fp_opts.print_raw_frame_arguments;
 
              /* True in "summary" mode, false otherwise.  */
 
              /* True in "summary" mode, false otherwise.  */
-             opts.summary = !strcmp (print_frame_arguments, "scalars");
+             vp_opts.summary
+               = fp_opts.print_frame_arguments == print_frame_arguments_scalars;
 
 
-             common_val_print (arg->val, &stb, 2, &opts, language);
+             common_val_print_checked (arg->val, &stb, 2, &vp_opts, language);
            }
            }
-         CATCH (except, RETURN_MASK_ERROR)
+         catch (const gdb_exception_error &except)
            {
            {
-             error_message = except.message;
+             stb.printf (_("<error reading variable: %s>"),
+                         except.what ());
+             style = metadata_style.style ();
            }
            }
-         END_CATCH
        }
        }
-      if (error_message != NULL)
-       stb.printf (_("<error reading variable: %s>"), error_message);
     }
 
     }
 
-  uiout->field_stream ("value", stb);
+  uiout->field_stream ("value", stb, style);
 }
 
 /* Read in inferior function local SYM at FRAME into ARGP.  Caller is
 }
 
 /* Read in inferior function local SYM at FRAME into ARGP.  Caller is
@@ -320,72 +512,69 @@ read_frame_local (struct symbol *sym, struct frame_info *frame,
   argp->val = NULL;
   argp->error = NULL;
 
   argp->val = NULL;
   argp->error = NULL;
 
-  TRY
+  try
     {
       argp->val = read_var_value (sym, NULL, frame);
     }
     {
       argp->val = read_var_value (sym, NULL, frame);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
     {
-      argp->error = xstrdup (except.message);
+      argp->error.reset (xstrdup (except.what ()));
     }
     }
-  END_CATCH
 }
 
 }
 
-/* Read in inferior function parameter SYM at FRAME into ARGP.  Caller is
-   responsible for xfree of ARGP->ERROR.  This function never throws an
-   exception.  */
+/* Read in inferior function parameter SYM at FRAME into ARGP.  This
+   function never throws an exception.  */
 
 void
 
 void
-read_frame_arg (struct symbol *sym, struct frame_info *frame,
+read_frame_arg (const frame_print_options &fp_opts,
+               symbol *sym, frame_info *frame,
                struct frame_arg *argp, struct frame_arg *entryargp)
 {
   struct value *val = NULL, *entryval = NULL;
   char *val_error = NULL, *entryval_error = NULL;
   int val_equal = 0;
 
                struct frame_arg *argp, struct frame_arg *entryargp)
 {
   struct value *val = NULL, *entryval = NULL;
   char *val_error = NULL, *entryval_error = NULL;
   int val_equal = 0;
 
-  if (print_entry_values != print_entry_values_only
-      && print_entry_values != print_entry_values_preferred)
+  if (fp_opts.print_entry_values != print_entry_values_only
+      && fp_opts.print_entry_values != print_entry_values_preferred)
     {
     {
-      TRY
+      try
        {
          val = read_var_value (sym, NULL, frame);
        }
        {
          val = read_var_value (sym, NULL, frame);
        }
-      CATCH (except, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &except)
        {
        {
-         val_error = (char *) alloca (strlen (except.message) + 1);
-         strcpy (val_error, except.message);
+         val_error = (char *) alloca (except.message->size () + 1);
+         strcpy (val_error, except.what ());
        }
        }
-      END_CATCH
     }
 
   if (SYMBOL_COMPUTED_OPS (sym) != NULL
       && SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry != NULL
     }
 
   if (SYMBOL_COMPUTED_OPS (sym) != NULL
       && SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry != NULL
-      && print_entry_values != print_entry_values_no
-      && (print_entry_values != print_entry_values_if_needed
+      && fp_opts.print_entry_values != print_entry_values_no
+      && (fp_opts.print_entry_values != print_entry_values_if_needed
          || !val || value_optimized_out (val)))
     {
          || !val || value_optimized_out (val)))
     {
-      TRY
+      try
        {
          const struct symbol_computed_ops *ops;
 
          ops = SYMBOL_COMPUTED_OPS (sym);
          entryval = ops->read_variable_at_entry (sym, frame);
        }
        {
          const struct symbol_computed_ops *ops;
 
          ops = SYMBOL_COMPUTED_OPS (sym);
          entryval = ops->read_variable_at_entry (sym, frame);
        }
-      CATCH (except, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &except)
        {
          if (except.error != NO_ENTRY_VALUE_ERROR)
            {
        {
          if (except.error != NO_ENTRY_VALUE_ERROR)
            {
-             entryval_error = (char *) alloca (strlen (except.message) + 1);
-             strcpy (entryval_error, except.message);
+             entryval_error = (char *) alloca (except.message->size () + 1);
+             strcpy (entryval_error, except.what ());
            }
        }
            }
        }
-      END_CATCH
 
       if (entryval != NULL && value_optimized_out (entryval))
        entryval = NULL;
 
 
       if (entryval != NULL && value_optimized_out (entryval))
        entryval = NULL;
 
-      if (print_entry_values == print_entry_values_compact
-         || print_entry_values == print_entry_values_default)
+      if (fp_opts.print_entry_values == print_entry_values_compact
+         || fp_opts.print_entry_values == print_entry_values_default)
        {
          /* For MI do not try to use print_entry_values_compact for ARGP.  */
 
        {
          /* For MI do not try to use print_entry_values_compact for ARGP.  */
 
@@ -407,7 +596,7 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
                     value.  If it is a reference still try to verify if
                     dereferenced DW_AT_call_data_value does not differ.  */
 
                     value.  If it is a reference still try to verify if
                     dereferenced DW_AT_call_data_value does not differ.  */
 
-                 TRY
+                 try
                    {
                      struct type *type_deref;
 
                    {
                      struct type *type_deref;
 
@@ -428,7 +617,7 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
                                                TYPE_LENGTH (type_deref)))
                        val_equal = 1;
                    }
                                                TYPE_LENGTH (type_deref)))
                        val_equal = 1;
                    }
-                 CATCH (except, RETURN_MASK_ERROR)
+                 catch (const gdb_exception_error &except)
                    {
                      /* If the dereferenced content could not be
                         fetched do not display anything.  */
                    {
                      /* If the dereferenced content could not be
                         fetched do not display anything.  */
@@ -436,11 +625,11 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
                        val_equal = 1;
                      else if (except.message != NULL)
                        {
                        val_equal = 1;
                      else if (except.message != NULL)
                        {
-                         entryval_error = (char *) alloca (strlen (except.message) + 1);
-                         strcpy (entryval_error, except.message);
+                         entryval_error
+                           = (char *) alloca (except.message->size () + 1);
+                         strcpy (entryval_error, except.what ());
                        }
                    }
                        }
                    }
-                 END_CATCH
 
                  /* Value was not a reference; and its content matches.  */
                  if (val == val_deref)
 
                  /* Value was not a reference; and its content matches.  */
                  if (val == val_deref)
@@ -468,33 +657,32 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
 
   if (entryval == NULL)
     {
 
   if (entryval == NULL)
     {
-      if (print_entry_values == print_entry_values_preferred)
+      if (fp_opts.print_entry_values == print_entry_values_preferred)
        {
          gdb_assert (val == NULL);
 
        {
          gdb_assert (val == NULL);
 
-         TRY
+         try
            {
              val = read_var_value (sym, NULL, frame);
            }
            {
              val = read_var_value (sym, NULL, frame);
            }
-         CATCH (except, RETURN_MASK_ERROR)
+         catch (const gdb_exception_error &except)
            {
            {
-             val_error = (char *) alloca (strlen (except.message) + 1);
-             strcpy (val_error, except.message);
+             val_error = (char *) alloca (except.message->size () + 1);
+             strcpy (val_error, except.what ());
            }
            }
-         END_CATCH
        }
        }
-      if (print_entry_values == print_entry_values_only
-         || print_entry_values == print_entry_values_both
-         || (print_entry_values == print_entry_values_preferred
+      if (fp_opts.print_entry_values == print_entry_values_only
+         || fp_opts.print_entry_values == print_entry_values_both
+         || (fp_opts.print_entry_values == print_entry_values_preferred
              && (!val || value_optimized_out (val))))
        {
          entryval = allocate_optimized_out_value (SYMBOL_TYPE (sym));
          entryval_error = NULL;
        }
     }
              && (!val || value_optimized_out (val))))
        {
          entryval = allocate_optimized_out_value (SYMBOL_TYPE (sym));
          entryval_error = NULL;
        }
     }
-  if ((print_entry_values == print_entry_values_compact
-       || print_entry_values == print_entry_values_if_needed
-       || print_entry_values == print_entry_values_preferred)
+  if ((fp_opts.print_entry_values == print_entry_values_compact
+       || fp_opts.print_entry_values == print_entry_values_if_needed
+       || fp_opts.print_entry_values == print_entry_values_preferred)
       && (!val || value_optimized_out (val)) && entryval != NULL)
     {
       val = NULL;
       && (!val || value_optimized_out (val)) && entryval != NULL)
     {
       val = NULL;
@@ -503,11 +691,12 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
 
   argp->sym = sym;
   argp->val = val;
 
   argp->sym = sym;
   argp->val = val;
-  argp->error = val_error ? xstrdup (val_error) : NULL;
+  argp->error.reset (val_error ? xstrdup (val_error) : NULL);
   if (!val && !val_error)
     argp->entry_kind = print_entry_values_only;
   if (!val && !val_error)
     argp->entry_kind = print_entry_values_only;
-  else if ((print_entry_values == print_entry_values_compact
-          || print_entry_values == print_entry_values_default) && val_equal)
+  else if ((fp_opts.print_entry_values == print_entry_values_compact
+          || fp_opts.print_entry_values == print_entry_values_default)
+          && val_equal)
     {
       argp->entry_kind = print_entry_values_compact;
       gdb_assert (!current_uiout->is_mi_like_p ());
     {
       argp->entry_kind = print_entry_values_compact;
       gdb_assert (!current_uiout->is_mi_like_p ());
@@ -517,7 +706,7 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
 
   entryargp->sym = sym;
   entryargp->val = entryval;
 
   entryargp->sym = sym;
   entryargp->val = entryval;
-  entryargp->error = entryval_error ? xstrdup (entryval_error) : NULL;
+  entryargp->error.reset (entryval_error ? xstrdup (entryval_error) : NULL);
   if (!entryval && !entryval_error)
     entryargp->entry_kind = print_entry_values_no;
   else
   if (!entryval && !entryval_error)
     entryargp->entry_kind = print_entry_values_no;
   else
@@ -534,7 +723,8 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame,
    ints of arguments according to the stack frame".  */
 
 static void
    ints of arguments according to the stack frame".  */
 
 static void
-print_frame_args (struct symbol *func, struct frame_info *frame,
+print_frame_args (const frame_print_options &fp_opts,
+                 struct symbol *func, struct frame_info *frame,
                  int num, struct ui_file *stream)
 {
   struct ui_out *uiout = current_uiout;
                  int num, struct ui_file *stream)
 {
   struct ui_out *uiout = current_uiout;
@@ -545,8 +735,14 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
   long highest_offset = -1;
   /* Number of ints of arguments that we have printed so far.  */
   int args_printed = 0;
   long highest_offset = -1;
   /* Number of ints of arguments that we have printed so far.  */
   int args_printed = 0;
+  /* True if we should print arg names.  If false, we only indicate
+     the presence of arguments by printing ellipsis.  */
+  bool print_names
+    = fp_opts.print_frame_arguments != print_frame_arguments_presence;
   /* True if we should print arguments, false otherwise.  */
   /* True if we should print arguments, false otherwise.  */
-  int print_args = strcmp (print_frame_arguments, "none");
+  bool print_args
+    = (print_names
+       && fp_opts.print_frame_arguments != print_frame_arguments_none);
 
   if (func)
     {
 
   if (func)
     {
@@ -566,6 +762,13 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
          if (!SYMBOL_IS_ARGUMENT (sym))
            continue;
 
          if (!SYMBOL_IS_ARGUMENT (sym))
            continue;
 
+         if (!print_names)
+           {
+             uiout->text ("...");
+             first = 0;
+             break;
+           }
+
          switch (SYMBOL_CLASS (sym))
            {
            case LOC_ARG:
          switch (SYMBOL_CLASS (sym))
            {
            case LOC_ARG:
@@ -614,11 +817,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
             parameter names occur on the RS/6000, for traceback
             tables.  FIXME, should we even print them?  */
 
             parameter names occur on the RS/6000, for traceback
             tables.  FIXME, should we even print them?  */
 
-         if (*SYMBOL_LINKAGE_NAME (sym))
+         if (*sym->linkage_name ())
            {
              struct symbol *nsym;
 
            {
              struct symbol *nsym;
 
-             nsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+             nsym = lookup_symbol_search_name (sym->search_name (),
                                                b, VAR_DOMAIN).symbol;
              gdb_assert (nsym != NULL);
              if (SYMBOL_CLASS (nsym) == LOC_REGISTER
                                                b, VAR_DOMAIN).symbol;
              gdb_assert (nsym != NULL);
              if (SYMBOL_CLASS (nsym) == LOC_REGISTER
@@ -672,18 +875,16 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
 
          if (!print_args)
            {
 
          if (!print_args)
            {
-             memset (&arg, 0, sizeof (arg));
              arg.sym = sym;
              arg.entry_kind = print_entry_values_no;
              arg.sym = sym;
              arg.entry_kind = print_entry_values_no;
-             memset (&entryarg, 0, sizeof (entryarg));
              entryarg.sym = sym;
              entryarg.entry_kind = print_entry_values_no;
            }
          else
              entryarg.sym = sym;
              entryarg.entry_kind = print_entry_values_no;
            }
          else
-           read_frame_arg (sym, frame, &arg, &entryarg);
+           read_frame_arg (fp_opts, sym, frame, &arg, &entryarg);
 
          if (arg.entry_kind != print_entry_values_only)
 
          if (arg.entry_kind != print_entry_values_only)
-           print_frame_arg (&arg);
+           print_frame_arg (fp_opts, &arg);
 
          if (entryarg.entry_kind != print_entry_values_no)
            {
 
          if (entryarg.entry_kind != print_entry_values_no)
            {
@@ -693,12 +894,9 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
                  uiout->wrap_hint ("    ");
                }
 
                  uiout->wrap_hint ("    ");
                }
 
-             print_frame_arg (&entryarg);
+             print_frame_arg (fp_opts, &entryarg);
            }
 
            }
 
-         xfree (arg.error);
-         xfree (entryarg.error);
-
          first = 0;
        }
     }
          first = 0;
        }
     }
@@ -714,8 +912,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
       else
        start = highest_offset;
 
       else
        start = highest_offset;
 
-      print_frame_nameless_args (frame, start, num - args_printed,
-                                first, stream);
+      if (!print_names && !first && num > 0)
+       uiout->text ("...");
+      else
+       print_frame_nameless_args (frame, start, num - args_printed,
+                                  first, stream);
     }
 }
 
     }
 }
 
@@ -758,34 +959,75 @@ do_gdb_disassembly (struct gdbarch *gdbarch,
                    int how_many, CORE_ADDR low, CORE_ADDR high)
 {
 
                    int how_many, CORE_ADDR low, CORE_ADDR high)
 {
 
-  TRY
+  try
     {
       gdb_disassembly (gdbarch, current_uiout,
                       DISASSEMBLY_RAW_INSN, how_many,
                       low, high);
     }
     {
       gdb_disassembly (gdbarch, current_uiout,
                       DISASSEMBLY_RAW_INSN, how_many,
                       low, high);
     }
-  CATCH (exception, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &exception)
     {
       /* If an exception was thrown while doing the disassembly, print
         the error message, to give the user a clue of what happened.  */
       exception_print (gdb_stderr, exception);
     }
     {
       /* If an exception was thrown while doing the disassembly, print
         the error message, to give the user a clue of what happened.  */
       exception_print (gdb_stderr, exception);
     }
-  END_CATCH
+}
+
+/* Converts the PRINT_FRAME_INFO choice to an optional enum print_what.
+   Value not present indicates to the caller to use default values
+   specific to the command being executed.  */
+
+static gdb::optional<enum print_what>
+print_frame_info_to_print_what (const char *print_frame_info)
+{
+  for (int i = 0; print_frame_info_choices[i] != NULL; i++)
+    if (print_frame_info == print_frame_info_choices[i])
+      return print_frame_info_print_what[i];
+
+  internal_error (__FILE__, __LINE__,
+                 "Unexpected print frame-info value `%s'.",
+                 print_frame_info);
+}
+
+/* Print the PC from FRAME, plus any flags, to UIOUT.  */
+
+static void
+print_pc (struct ui_out *uiout, struct gdbarch *gdbarch, frame_info *frame,
+         CORE_ADDR pc)
+{
+  uiout->field_core_addr ("addr", gdbarch, pc);
+
+  std::string flags = gdbarch_get_pc_address_flags (gdbarch, frame, pc);
+  if (!flags.empty ())
+  {
+    uiout->text (" [");
+    uiout->field_string ("addr_flags", flags);
+    uiout->text ("]");
+  }
+}
+
+/* See stack.h.  */
+
+void
+get_user_print_what_frame_info (gdb::optional<enum print_what> *what)
+{
+  *what
+    = print_frame_info_to_print_what
+        (user_frame_print_options.print_frame_info);
 }
 
 /* Print information about frame FRAME.  The output is format according
 }
 
 /* Print information about frame FRAME.  The output is format according
-   to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS.  The meaning of
-   PRINT_WHAT is:
-   
-   SRC_LINE: Print only source line.
-   LOCATION: Print only location.
-   SRC_AND_LOC: Print location and source line.
+   to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS.  For the meaning of
+   PRINT_WHAT, see enum print_what comments in frame.h.
+   Note that PRINT_WHAT is overridden if FP_OPTS.print_frame_info
+   != print_frame_info_auto.
 
    Used in "where" output, and to emit breakpoint or step
    messages.  */
 
 void
 
    Used in "where" output, and to emit breakpoint or step
    messages.  */
 
 void
-print_frame_info (struct frame_info *frame, int print_level,
+print_frame_info (const frame_print_options &fp_opts,
+                 frame_info *frame, int print_level,
                  enum print_what print_what, int print_args,
                  int set_current_sal)
 {
                  enum print_what print_what, int print_args,
                  int set_current_sal)
 {
@@ -794,6 +1036,13 @@ print_frame_info (struct frame_info *frame, int print_level,
   int location_print;
   struct ui_out *uiout = current_uiout;
 
   int location_print;
   struct ui_out *uiout = current_uiout;
 
+  if (!current_uiout->is_mi_like_p ()
+      && fp_opts.print_frame_info != print_frame_info_auto)
+    {
+      /* Use the specific frame information desired by the user.  */
+      print_what = *print_frame_info_to_print_what (fp_opts.print_frame_info);
+    }
+
   if (get_frame_type (frame) == DUMMY_FRAME
       || get_frame_type (frame) == SIGTRAMP_FRAME
       || get_frame_type (frame) == ARCH_FRAME)
   if (get_frame_type (frame) == DUMMY_FRAME
       || get_frame_type (frame) == SIGTRAMP_FRAME
       || get_frame_type (frame) == ARCH_FRAME)
@@ -808,30 +1057,32 @@ print_frame_info (struct frame_info *frame, int print_level,
       if (print_level)
         {
           uiout->text ("#");
       if (print_level)
         {
           uiout->text ("#");
-          uiout->field_fmt_int (2, ui_left, "level",
-                               frame_relative_level (frame));
+          uiout->field_fmt_signed (2, ui_left, "level",
+                                  frame_relative_level (frame));
         }
       if (uiout->is_mi_like_p ())
         {
           annotate_frame_address ();
         }
       if (uiout->is_mi_like_p ())
         {
           annotate_frame_address ();
-          uiout->field_core_addr ("addr",
-                                 gdbarch, get_frame_pc (frame));
+         print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
           annotate_frame_address_end ();
         }
 
       if (get_frame_type (frame) == DUMMY_FRAME)
         {
           annotate_function_call ();
           annotate_frame_address_end ();
         }
 
       if (get_frame_type (frame) == DUMMY_FRAME)
         {
           annotate_function_call ();
-          uiout->field_string ("func", "<function called from gdb>");
+          uiout->field_string ("func", "<function called from gdb>",
+                              metadata_style.style ());
        }
       else if (get_frame_type (frame) == SIGTRAMP_FRAME)
         {
          annotate_signal_handler_caller ();
        }
       else if (get_frame_type (frame) == SIGTRAMP_FRAME)
         {
          annotate_signal_handler_caller ();
-          uiout->field_string ("func", "<signal handler called>");
+          uiout->field_string ("func", "<signal handler called>",
+                              metadata_style.style ());
         }
       else if (get_frame_type (frame) == ARCH_FRAME)
         {
         }
       else if (get_frame_type (frame) == ARCH_FRAME)
         {
-          uiout->field_string ("func", "<cross-architecture call>");
+          uiout->field_string ("func", "<cross-architecture call>",
+                              metadata_style.style ());
        }
       uiout->text ("\n");
       annotate_frame_end ();
        }
       uiout->text ("\n");
       annotate_frame_end ();
@@ -854,12 +1105,12 @@ print_frame_info (struct frame_info *frame, int print_level,
      to get the line containing FRAME->pc.  */
   symtab_and_line sal = find_frame_sal (frame);
 
      to get the line containing FRAME->pc.  */
   symtab_and_line sal = find_frame_sal (frame);
 
-  location_print = (print_what == LOCATION 
+  location_print = (print_what == LOCATION
+                   || print_what == SRC_AND_LOC
                    || print_what == LOC_AND_ADDRESS
                    || print_what == LOC_AND_ADDRESS
-                   || print_what == SRC_AND_LOC);
-
+                   || print_what == SHORT_LOCATION);
   if (location_print || !sal.symtab)
   if (location_print || !sal.symtab)
-    print_frame (frame, print_level, print_what, print_args, sal);
+    print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
 
   source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
 
 
   source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
 
@@ -873,45 +1124,53 @@ print_frame_info (struct frame_info *frame, int print_level,
 
   if (source_print && sal.symtab)
     {
 
   if (source_print && sal.symtab)
     {
-      int done = 0;
       int mid_statement = ((print_what == SRC_LINE)
                           && frame_show_address (frame, sal));
       int mid_statement = ((print_what == SRC_LINE)
                           && frame_show_address (frame, sal));
-
-      if (annotation_level)
-       done = identify_source_line (sal.symtab, sal.line, mid_statement,
-                                    get_frame_pc (frame));
-      if (!done)
+      if (annotation_level > 0
+         && annotate_source_line (sal.symtab, sal.line, mid_statement,
+                                  get_frame_pc (frame)))
        {
        {
-         if (deprecated_print_frame_info_listing_hook)
-           deprecated_print_frame_info_listing_hook (sal.symtab, 
-                                                     sal.line, 
-                                                     sal.line + 1, 0);
-         else
-           {
-             struct value_print_options opts;
-
-             get_user_print_options (&opts);
-             /* We used to do this earlier, but that is clearly
-                wrong.  This function is used by many different
-                parts of gdb, including normal_stop in infrun.c,
-                which uses this to print out the current PC
-                when we stepi/nexti into the middle of a source
-                line.  Only the command line really wants this
-                behavior.  Other UIs probably would like the
-                ability to decide for themselves if it is desired.  */
-             if (opts.addressprint && mid_statement)
-               {
-                 uiout->field_core_addr ("addr",
-                                         gdbarch, get_frame_pc (frame));
-                 uiout->text ("\t");
-               }
+         /* The call to ANNOTATE_SOURCE_LINE already printed the
+            annotation for this source line, so we avoid the two cases
+            below and do not print the actual source line.  The
+            documentation for annotations makes it clear that the source
+            line annotation is printed __instead__ of printing the source
+            line, not as well as.
+
+            However, if we fail to print the source line, which usually
+            means either the source file is missing, or the requested
+            line is out of range of the file, then we don't print the
+            source annotation, and will pass through the "normal" print
+            source line code below, the expectation is that this code
+            will print an appropriate error.  */
+       }
+      else if (deprecated_print_frame_info_listing_hook)
+       deprecated_print_frame_info_listing_hook (sal.symtab, sal.line,
+                                                 sal.line + 1, 0);
+      else
+       {
+         struct value_print_options opts;
 
 
-             print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+         get_user_print_options (&opts);
+         /* We used to do this earlier, but that is clearly
+            wrong.  This function is used by many different
+            parts of gdb, including normal_stop in infrun.c,
+            which uses this to print out the current PC
+            when we stepi/nexti into the middle of a source
+            line.  Only the command line really wants this
+            behavior.  Other UIs probably would like the
+            ability to decide for themselves if it is desired.  */
+         if (opts.addressprint && mid_statement)
+           {
+             print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
+             uiout->text ("\t");
            }
            }
+
+         print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
        }
 
       /* If disassemble-next-line is set to on and there is line debug
        }
 
       /* If disassemble-next-line is set to on and there is line debug
-         messages, output assembly codes for next line.  */
+        messages, output assembly codes for next line.  */
       if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
        do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
     }
       if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
        do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
     }
@@ -921,9 +1180,9 @@ print_frame_info (struct frame_info *frame, int print_level,
       CORE_ADDR pc;
 
       if (get_frame_pc_if_available (frame, &pc))
       CORE_ADDR pc;
 
       if (get_frame_pc_if_available (frame, &pc))
-       set_last_displayed_sal (1, sal.pspace, pc, sal.symtab, sal.line);
+       last_displayed_symtab_info.set (sal.pspace, pc, sal.symtab, sal.line);
       else
       else
-       set_last_displayed_sal (0, 0, 0, 0, 0);
+       last_displayed_symtab_info.invalidate ();
     }
 
   annotate_frame_end ();
     }
 
   annotate_frame_end ();
@@ -931,103 +1190,67 @@ print_frame_info (struct frame_info *frame, int print_level,
   gdb_flush (gdb_stdout);
 }
 
   gdb_flush (gdb_stdout);
 }
 
-/* Remember the last symtab and line we displayed, which we use e.g.
- * as the place to put a breakpoint when the `break' command is
- * invoked with no arguments.  */
-
-static void
-set_last_displayed_sal (int valid, struct program_space *pspace,
-                       CORE_ADDR addr, struct symtab *symtab,
-                       int line)
-{
-  last_displayed_sal_valid = valid;
-  last_displayed_pspace = pspace;
-  last_displayed_addr = addr;
-  last_displayed_symtab = symtab;
-  last_displayed_line = line;
-  if (valid && pspace == NULL)
-    {
-      clear_last_displayed_sal ();
-      internal_error (__FILE__, __LINE__,
-                     _("Trying to set NULL pspace."));
-    }
-}
-
-/* Forget the last sal we displayed.  */
+/* See stack.h.  */
 
 void
 clear_last_displayed_sal (void)
 {
 
 void
 clear_last_displayed_sal (void)
 {
-  last_displayed_sal_valid = 0;
-  last_displayed_pspace = 0;
-  last_displayed_addr = 0;
-  last_displayed_symtab = 0;
-  last_displayed_line = 0;
+  last_displayed_symtab_info.invalidate ();
 }
 
 }
 
-/* Is our record of the last sal we displayed valid?  If not,
- * the get_last_displayed_* functions will return NULL or 0, as
- * appropriate.  */
+/* See stack.h.  */
 
 
-int
+bool
 last_displayed_sal_is_valid (void)
 {
 last_displayed_sal_is_valid (void)
 {
-  return last_displayed_sal_valid;
+  return last_displayed_symtab_info.is_valid ();
 }
 
 }
 
-/* Get the pspace of the last sal we displayed, if it's valid.  */
+/* See stack.h.  */
 
 struct program_space *
 get_last_displayed_pspace (void)
 {
 
 struct program_space *
 get_last_displayed_pspace (void)
 {
-  if (last_displayed_sal_valid)
-    return last_displayed_pspace;
-  return 0;
+  return last_displayed_symtab_info.pspace ();
 }
 
 }
 
-/* Get the address of the last sal we displayed, if it's valid.  */
+/* See stack.h.  */
 
 CORE_ADDR
 get_last_displayed_addr (void)
 {
 
 CORE_ADDR
 get_last_displayed_addr (void)
 {
-  if (last_displayed_sal_valid)
-    return last_displayed_addr;
-  return 0;
+  return last_displayed_symtab_info.address ();
 }
 
 }
 
-/* Get the symtab of the last sal we displayed, if it's valid.  */
+/* See stack.h.  */
 
 struct symtab*
 get_last_displayed_symtab (void)
 {
 
 struct symtab*
 get_last_displayed_symtab (void)
 {
-  if (last_displayed_sal_valid)
-    return last_displayed_symtab;
-  return 0;
+  return last_displayed_symtab_info.symtab ();
 }
 
 }
 
-/* Get the line of the last sal we displayed, if it's valid.  */
+/* See stack.h.  */
 
 int
 get_last_displayed_line (void)
 {
 
 int
 get_last_displayed_line (void)
 {
-  if (last_displayed_sal_valid)
-    return last_displayed_line;
-  return 0;
+  return last_displayed_symtab_info.line ();
 }
 
 }
 
-/* Get the last sal we displayed, if it's valid.  */
+/* See stack.h.  */
 
 symtab_and_line
 get_last_displayed_sal ()
 {
   symtab_and_line sal;
 
 
 symtab_and_line
 get_last_displayed_sal ()
 {
   symtab_and_line sal;
 
-  if (last_displayed_sal_valid)
+  if (last_displayed_symtab_info.is_valid ())
     {
     {
-      sal.pspace = last_displayed_pspace;
-      sal.pc = last_displayed_addr;
-      sal.symtab = last_displayed_symtab;
-      sal.line = last_displayed_line;
+      sal.pspace = last_displayed_symtab_info.pspace ();
+      sal.pc = last_displayed_symtab_info.address ();
+      sal.symtab = last_displayed_symtab_info.symtab ();
+      sal.line = last_displayed_symtab_info.line ();
     }
 
   return sal;
     }
 
   return sal;
@@ -1051,66 +1274,25 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
   func = get_frame_function (frame);
   if (func)
     {
   func = get_frame_function (frame);
   if (func)
     {
-      /* In certain pathological cases, the symtabs give the wrong
-         function (when we are in the first function in a file which
-         is compiled without debugging symbols, the previous function
-         is compiled with debugging symbols, and the "foo.o" symbol
-         that is supposed to tell us where the file with debugging
-         symbols ends has been truncated by ar because it is longer
-         than 15 characters).  This also occurs if the user uses asm()
-         to create a function but not stabs for it (in a file compiled
-         with -g).
-
-         So look in the minimal symbol tables as well, and if it comes
-         up with a larger address for the function use that instead.
-         I don't think this can ever cause any problems; there
-         shouldn't be any minimal symbols in the middle of a function;
-         if this is ever changed many parts of GDB will need to be
-         changed (and we'll create a find_pc_minimal_function or some
-         such).  */
-
-      struct bound_minimal_symbol msymbol;
-
-      /* Don't attempt to do this for inlined functions, which do not
-        have a corresponding minimal symbol.  */
-      if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)))
-       msymbol
-         = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
-      else
-       memset (&msymbol, 0, sizeof (msymbol));
+      const char *print_name = func->print_name ();
 
 
-      if (msymbol.minsym != NULL
-         && (BMSYMBOL_VALUE_ADDRESS (msymbol)
-             > BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func))))
+      *funlang = func->language ();
+      if (funcp)
+       *funcp = func;
+      if (*funlang == language_cplus)
        {
        {
-         /* We also don't know anything about the function besides
-            its address and name.  */
-         func = 0;
-         funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
-         *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+         /* It seems appropriate to use print_name() here,
+            to display the demangled name that we already have
+            stored in the symbol table, but we stored a version
+            with DMGL_PARAMS turned on, and here we don't want to
+            display parameters.  So remove the parameters.  */
+         funname = cp_remove_params (print_name);
        }
        }
-      else
-       {
-         const char *print_name = SYMBOL_PRINT_NAME (func);
-
-         *funlang = SYMBOL_LANGUAGE (func);
-         if (funcp)
-           *funcp = func;
-         if (*funlang == language_cplus)
-           {
-             /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
-                to display the demangled name that we already have
-                stored in the symbol table, but we stored a version
-                with DMGL_PARAMS turned on, and here we don't want to
-                display parameters.  So remove the parameters.  */
-             funname = cp_remove_params (print_name);
-           }
 
 
-         /* If we didn't hit the C++ case above, set *funname
-            here.  */
-         if (funname == NULL)
-           funname.reset (xstrdup (print_name));
-       }
+      /* If we didn't hit the C++ case above, set *funname
+        here.  */
+      if (funname == NULL)
+       funname.reset (xstrdup (print_name));
     }
   else
     {
     }
   else
     {
@@ -1123,8 +1305,8 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
       msymbol = lookup_minimal_symbol_by_pc (pc);
       if (msymbol.minsym != NULL)
        {
       msymbol = lookup_minimal_symbol_by_pc (pc);
       if (msymbol.minsym != NULL)
        {
-         funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
-         *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+         funname.reset (xstrdup (msymbol.minsym->print_name ()));
+         *funlang = msymbol.minsym->language ();
        }
     }
 
        }
     }
 
@@ -1132,7 +1314,8 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
 }
 
 static void
 }
 
 static void
-print_frame (struct frame_info *frame, int print_level,
+print_frame (const frame_print_options &fp_opts,
+            frame_info *frame, int print_level,
             enum print_what print_what, int print_args,
             struct symtab_and_line sal)
 {
             enum print_what print_what, int print_args,
             struct symtab_and_line sal)
 {
@@ -1158,8 +1341,8 @@ print_frame (struct frame_info *frame, int print_level,
     if (print_level)
       {
        uiout->text ("#");
     if (print_level)
       {
        uiout->text ("#");
-       uiout->field_fmt_int (2, ui_left, "level",
-                             frame_relative_level (frame));
+       uiout->field_fmt_signed (2, ui_left, "level",
+                                frame_relative_level (frame));
       }
     get_user_print_options (&opts);
     if (opts.addressprint)
       }
     get_user_print_options (&opts);
     if (opts.addressprint)
@@ -1169,9 +1352,10 @@ print_frame (struct frame_info *frame, int print_level,
        {
          annotate_frame_address ();
          if (pc_p)
        {
          annotate_frame_address ();
          if (pc_p)
-           uiout->field_core_addr ("addr", gdbarch, pc);
+           print_pc (uiout, gdbarch, frame, pc);
          else
          else
-           uiout->field_string ("addr", "<unavailable>");
+           uiout->field_string ("addr", "<unavailable>",
+                                metadata_style.style ());
          annotate_frame_address_end ();
          uiout->text (" in ");
        }
          annotate_frame_address_end ();
          uiout->text (" in ");
        }
@@ -1180,10 +1364,10 @@ print_frame (struct frame_info *frame, int print_level,
     string_file stb;
     fprintf_symbol_filtered (&stb, funname ? funname.get () : "??",
                             funlang, DMGL_ANSI);
     string_file stb;
     fprintf_symbol_filtered (&stb, funname ? funname.get () : "??",
                             funlang, DMGL_ANSI);
-    uiout->field_stream ("func", stb);
+    uiout->field_stream ("func", stb, function_name_style.style ());
     uiout->wrap_hint ("   ");
     annotate_frame_args ();
     uiout->wrap_hint ("   ");
     annotate_frame_args ();
-      
+
     uiout->text (" (");
     if (print_args)
       {
     uiout->text (" (");
     if (print_args)
       {
@@ -1199,14 +1383,13 @@ print_frame (struct frame_info *frame, int print_level,
     
        {
          ui_out_emit_list list_emitter (uiout, "args");
     
        {
          ui_out_emit_list list_emitter (uiout, "args");
-         TRY
+         try
            {
            {
-             print_frame_args (func, frame, numargs, gdb_stdout);
+             print_frame_args (fp_opts, func, frame, numargs, gdb_stdout);
            }
            }
-         CATCH (e, RETURN_MASK_ERROR)
+         catch (const gdb_exception_error &e)
            {
            }
            {
            }
-         END_CATCH
 
            /* FIXME: ARGS must be a list.  If one argument is a string it
               will have " that will not be properly escaped.  */
 
            /* FIXME: ARGS must be a list.  If one argument is a string it
               will have " that will not be properly escaped.  */
@@ -1214,7 +1397,7 @@ print_frame (struct frame_info *frame, int print_level,
        QUIT;
       }
     uiout->text (")");
        QUIT;
       }
     uiout->text (")");
-    if (sal.symtab)
+    if (print_what != SHORT_LOCATION && sal.symtab)
       {
        const char *filename_display;
       
       {
        const char *filename_display;
       
@@ -1223,7 +1406,8 @@ print_frame (struct frame_info *frame, int print_level,
        uiout->wrap_hint ("   ");
        uiout->text (" at ");
        annotate_frame_source_file ();
        uiout->wrap_hint ("   ");
        uiout->text (" at ");
        annotate_frame_source_file ();
-       uiout->field_string ("file", filename_display);
+       uiout->field_string ("file", filename_display,
+                            file_name_style.style ());
        if (uiout->is_mi_like_p ())
          {
            const char *fullname = symtab_to_fullname (sal.symtab);
        if (uiout->is_mi_like_p ())
          {
            const char *fullname = symtab_to_fullname (sal.symtab);
@@ -1233,11 +1417,12 @@ print_frame (struct frame_info *frame, int print_level,
        annotate_frame_source_file_end ();
        uiout->text (":");
        annotate_frame_source_line ();
        annotate_frame_source_file_end ();
        uiout->text (":");
        annotate_frame_source_line ();
-       uiout->field_int ("line", sal.line);
+       uiout->field_signed ("line", sal.line);
        annotate_frame_source_end ();
       }
 
        annotate_frame_source_end ();
       }
 
-    if (pc_p && (funname == NULL || sal.symtab == NULL))
+    if (print_what != SHORT_LOCATION
+       && pc_p && (funname == NULL || sal.symtab == NULL))
       {
        char *lib = solib_name_from_address (get_frame_program_space (frame),
                                             get_frame_pc (frame));
       {
        char *lib = solib_name_from_address (get_frame_program_space (frame),
                                             get_frame_pc (frame));
@@ -1247,7 +1432,7 @@ print_frame (struct frame_info *frame, int print_level,
            annotate_frame_where ();
            uiout->wrap_hint ("  ");
            uiout->text (" from ");
            annotate_frame_where ();
            uiout->wrap_hint ("  ");
            uiout->text (" from ");
-           uiout->field_string ("from", lib);
+           uiout->field_string ("from", lib, file_name_style.style ());
          }
       }
     if (uiout->is_mi_like_p ())
          }
       }
     if (uiout->is_mi_like_p ())
@@ -1262,7 +1447,7 @@ print_frame (struct frame_info *frame, int print_level,
 /* Completion function for "frame function", "info frame function", and
    "select-frame function" commands.  */
 
 /* Completion function for "frame function", "info frame function", and
    "select-frame function" commands.  */
 
-void
+static void
 frame_selection_by_function_completer (struct cmd_list_element *ignore,
                                       completion_tracker &tracker,
                                       const char *text, const char *word)
 frame_selection_by_function_completer (struct cmd_list_element *ignore,
                                       completion_tracker &tracker,
                                       const char *text, const char *word)
@@ -1324,11 +1509,11 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
   gdb::unique_xmalloc_ptr<char> func_only;
   if (func)
     {
   gdb::unique_xmalloc_ptr<char> func_only;
   if (func)
     {
-      funname = SYMBOL_PRINT_NAME (func);
-      funlang = SYMBOL_LANGUAGE (func);
+      funname = func->print_name ();
+      funlang = func->language ();
       if (funlang == language_cplus)
        {
       if (funlang == language_cplus)
        {
-         /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
+         /* It seems appropriate to use print_name() here,
             to display the demangled name that we already have
             stored in the symbol table, but we stored a version
             with DMGL_PARAMS turned on, and here we don't want to
             to display the demangled name that we already have
             stored in the symbol table, but we stored a version
             with DMGL_PARAMS turned on, and here we don't want to
@@ -1346,8 +1531,8 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
       msymbol = lookup_minimal_symbol_by_pc (frame_pc);
       if (msymbol.minsym != NULL)
        {
       msymbol = lookup_minimal_symbol_by_pc (frame_pc);
       if (msymbol.minsym != NULL)
        {
-         funname = MSYMBOL_PRINT_NAME (msymbol.minsym);
-         funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+         funname = msymbol.minsym->print_name ();
+         funlang = msymbol.minsym->language ();
        }
     }
   calling_frame_info = get_prev_frame (fi);
        }
     }
   calling_frame_info = get_prev_frame (fi);
@@ -1367,7 +1552,7 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
   if (frame_pc_p)
     fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
   else
   if (frame_pc_p)
     fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
   else
-    fputs_filtered ("<unavailable>", gdb_stdout);
+    fputs_styled ("<unavailable>", metadata_style.style (), gdb_stdout);
 
   wrap_here ("   ");
   if (funname)
 
   wrap_here ("   ");
   if (funname)
@@ -1378,8 +1563,11 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
     }
   wrap_here ("   ");
   if (sal.symtab)
     }
   wrap_here ("   ");
   if (sal.symtab)
-    printf_filtered (" (%s:%d)", symtab_to_filename_for_display (sal.symtab),
-                    sal.line);
+    printf_filtered
+      (" (%ps:%d)",
+       styled_string (file_name_style.style (),
+                     symtab_to_filename_for_display (sal.symtab)),
+       sal.line);
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s = ", pc_regname);
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s = ", pc_regname);
@@ -1388,12 +1576,12 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
     val_print_not_saved (gdb_stdout);
   else
     {
     val_print_not_saved (gdb_stdout);
   else
     {
-      TRY
+      try
        {
          caller_pc = frame_unwind_caller_pc (fi);
          caller_pc_p = 1;
        }
        {
          caller_pc = frame_unwind_caller_pc (fi);
          caller_pc_p = 1;
        }
-      CATCH (ex, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &ex)
        {
          switch (ex.error)
            {
        {
          switch (ex.error)
            {
@@ -1404,11 +1592,12 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
              val_print_not_saved (gdb_stdout);
              break;
            default:
              val_print_not_saved (gdb_stdout);
              break;
            default:
-             fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
+             fprintf_styled (gdb_stdout, metadata_style.style (),
+                             _("<error: %s>"),
+                             ex.what ());
              break;
            }
        }
              break;
            }
        }
-      END_CATCH
     }
 
   if (caller_pc_p)
     }
 
   if (caller_pc_p)
@@ -1481,7 +1670,8 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
            else
              printf_filtered (" %d args: ", numargs);
          }
            else
              printf_filtered (" %d args: ", numargs);
          }
-       print_frame_args (func, fi, numargs, gdb_stdout);
+       print_frame_args (user_frame_print_options,
+                         func, fi, numargs, gdb_stdout);
        puts_filtered ("\n");
       }
   }
        puts_filtered ("\n");
       }
   }
@@ -1553,8 +1743,7 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
       }
 
     count = 0;
       }
 
     count = 0;
-    numregs = gdbarch_num_regs (gdbarch)
-             + gdbarch_num_pseudo_regs (gdbarch);
+    numregs = gdbarch_num_cooked_regs (gdbarch);
     for (i = 0; i < numregs; i++)
       if (i != sp_regnum
          && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
     for (i = 0; i < numregs; i++)
       if (i != sp_regnum
          && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
@@ -1658,7 +1847,7 @@ select_frame_command_core (struct frame_info *fi, bool ignored)
 void
 select_frame_for_mi (struct frame_info *fi)
 {
 void
 select_frame_for_mi (struct frame_info *fi)
 {
-  select_frame_command_core (fi, FALSE /* Ignored.  */);
+  select_frame_command_core (fi, false /* Ignored.  */);
 }
 
 /* The core of all the "frame" sub-commands.  Select frame FI, and if this
 }
 
 /* The core of all the "frame" sub-commands.  Select frame FI, and if this
@@ -1796,8 +1985,10 @@ static frame_command_helper <select_frame_command_core> select_frame_cmd;
    frames.  */
 
 static void
    frames.  */
 
 static void
-backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
-                    int no_filters, int from_tty)
+backtrace_command_1 (const frame_print_options &fp_opts,
+                    const backtrace_cmd_options &bt_opts,
+                    const char *count_exp, int from_tty)
+
 {
   struct frame_info *fi;
   int count;
 {
   struct frame_info *fi;
   int count;
@@ -1826,7 +2017,14 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
       count = -1;
     }
 
       count = -1;
     }
 
-  if (! no_filters)
+  frame_filter_flags flags = 0;
+
+  if (bt_opts.full)
+    flags |= PRINT_LOCALS;
+  if (bt_opts.hide)
+    flags |= PRINT_HIDE;
+
+  if (!bt_opts.no_filters)
     {
       enum ext_lang_frame_args arg_type;
 
     {
       enum ext_lang_frame_args arg_type;
 
@@ -1834,12 +2032,16 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
       if (from_tty)
        flags |= PRINT_MORE_FRAMES;
 
       if (from_tty)
        flags |= PRINT_MORE_FRAMES;
 
-      if (!strcmp (print_frame_arguments, "scalars"))
+      if (fp_opts.print_frame_arguments == print_frame_arguments_scalars)
        arg_type = CLI_SCALAR_VALUES;
        arg_type = CLI_SCALAR_VALUES;
-      else if (!strcmp (print_frame_arguments, "all"))
+      else if (fp_opts.print_frame_arguments == print_frame_arguments_all)
        arg_type = CLI_ALL_VALUES;
        arg_type = CLI_ALL_VALUES;
-      else
+      else if (fp_opts.print_frame_arguments == print_frame_arguments_presence)
+       arg_type = CLI_PRESENCE;
+      else if (fp_opts.print_frame_arguments == print_frame_arguments_none)
        arg_type = NO_VALUES;
        arg_type = NO_VALUES;
+      else
+       gdb_assert (0);
 
       result = apply_ext_lang_frame_filter (get_current_frame (), flags,
                                            arg_type, current_uiout,
 
       result = apply_ext_lang_frame_filter (get_current_frame (), flags,
                                            arg_type, current_uiout,
@@ -1847,8 +2049,8 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
     }
 
   /* Run the inbuilt backtrace if there are no filters registered, or
     }
 
   /* Run the inbuilt backtrace if there are no filters registered, or
-     "no-filters" has been specified from the command.  */
-  if (no_filters ||  result == EXT_LANG_BT_NO_FILTERS)
+     "-no-filters" has been specified from the command.  */
+  if (bt_opts.no_filters || result == EXT_LANG_BT_NO_FILTERS)
     {
       struct frame_info *trailing;
 
     {
       struct frame_info *trailing;
 
@@ -1874,12 +2076,12 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
             hand, perhaps the code does or could be fixed to make sure
             the frame->prev field gets set to NULL in that case).  */
 
             hand, perhaps the code does or could be fixed to make sure
             the frame->prev field gets set to NULL in that case).  */
 
-         print_frame_info (fi, 1, LOCATION, 1, 0);
+         print_frame_info (fp_opts, fi, 1, LOCATION, 1, 0);
          if ((flags & PRINT_LOCALS) != 0)
            {
              struct frame_id frame_id = get_frame_id (fi);
 
          if ((flags & PRINT_LOCALS) != 0)
            {
              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);
 
              /* print_frame_local_vars invalidates FI.  */
              fi = frame_find_by_id (frame_id);
@@ -1913,43 +2115,126 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
     }
 }
 
     }
 }
 
-static void
-backtrace_command (const char *arg, int from_tty)
+/* Create an option_def_group array grouping all the "backtrace"
+   options, with FP_OPTS, BT_CMD_OPT, SET_BT_OPTS as contexts.  */
+
+static inline std::array<gdb::option::option_def_group, 3>
+make_backtrace_options_def_group (frame_print_options *fp_opts,
+                                 backtrace_cmd_options *bt_cmd_opts,
+                                 set_backtrace_options *set_bt_opts)
 {
 {
-  bool filters = true;
-  frame_filter_flags flags = 0;
+  return {{
+    { {frame_print_option_defs}, fp_opts },
+    { {set_backtrace_option_defs}, set_bt_opts },
+    { {backtrace_command_option_defs}, bt_cmd_opts }
+  }};
+}
+
+/* Parse the backtrace command's qualifiers.  Returns ARG advanced
+   past the qualifiers, if any.  BT_CMD_OPTS, if not null, is used to
+   store the parsed qualifiers.  */
 
 
-  if (arg)
+static const char *
+parse_backtrace_qualifiers (const char *arg,
+                           backtrace_cmd_options *bt_cmd_opts = nullptr)
+{
+  while (true)
     {
     {
-      bool done = false;
+      const char *save_arg = arg;
+      std::string this_arg = extract_arg (&arg);
 
 
-      while (!done)
+      if (this_arg.empty ())
+       return arg;
+
+      if (subset_compare (this_arg.c_str (), "no-filters"))
+       {
+         if (bt_cmd_opts != nullptr)
+           bt_cmd_opts->no_filters = true;
+       }
+      else if (subset_compare (this_arg.c_str (), "full"))
+       {
+         if (bt_cmd_opts != nullptr)
+           bt_cmd_opts->full = true;
+       }
+      else if (subset_compare (this_arg.c_str (), "hide"))
+       {
+         if (bt_cmd_opts != nullptr)
+           bt_cmd_opts->hide = true;
+       }
+      else
        {
        {
-         const char *save_arg = arg;
-         std::string this_arg = extract_arg (&arg);
+         /* Not a recognized qualifier, so stop.  */
+         return save_arg;
+       }
+    }
+}
 
 
-         if (this_arg.empty ())
-           break;
+static void
+backtrace_command (const char *arg, int from_tty)
+{
+  frame_print_options fp_opts = user_frame_print_options;
+  backtrace_cmd_options bt_cmd_opts;
+  set_backtrace_options set_bt_opts = user_set_backtrace_options;
 
 
-         if (subset_compare (this_arg.c_str (), "no-filters"))
-           filters = false;
-         else if (subset_compare (this_arg.c_str (), "full"))
-           flags |= PRINT_LOCALS;
-         else if (subset_compare (this_arg.c_str (), "hide"))
-           flags |= PRINT_HIDE;
-         else
-           {
-             /* Not a recognized argument, so stop.  */
-             arg = save_arg;
-             done = true;
-           }
-       }
+  auto grp
+    = make_backtrace_options_def_group (&fp_opts, &bt_cmd_opts, &set_bt_opts);
+  gdb::option::process_options
+    (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
 
 
+  /* Parse non-'-'-prefixed qualifiers, for backwards
+     compatibility.  */
+  if (arg != NULL)
+    {
+      arg = parse_backtrace_qualifiers (arg, &bt_cmd_opts);
       if (*arg == '\0')
        arg = NULL;
     }
 
       if (*arg == '\0')
        arg = NULL;
     }
 
-  backtrace_command_1 (arg, flags, !filters /* no frame-filters */, from_tty);
+  /* These options are handled quite deep in the unwind machinery, so
+     we get to pass them down by swapping globals.  */
+  scoped_restore restore_set_backtrace_options
+    = make_scoped_restore (&user_set_backtrace_options, set_bt_opts);
+
+  backtrace_command_1 (fp_opts, bt_cmd_opts, arg, from_tty);
+}
+
+/* Completer for the "backtrace" command.  */
+
+static void
+backtrace_command_completer (struct cmd_list_element *ignore,
+                            completion_tracker &tracker,
+                            const char *text, const char */*word*/)
+{
+  const auto group
+    = make_backtrace_options_def_group (nullptr, nullptr, nullptr);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
+
+  if (*text != '\0')
+    {
+      const char *p = skip_to_space (text);
+      if (*p == '\0')
+       {
+         static const char *const backtrace_cmd_qualifier_choices[] = {
+           "full", "no-filters", "hide", nullptr,
+         };
+         complete_on_enum (tracker, backtrace_cmd_qualifier_choices,
+                           text, text);
+
+         if (tracker.have_completions ())
+           return;
+       }
+      else
+       {
+         const char *cmd = parse_backtrace_qualifiers (text);
+         tracker.advance_custom_word_point_by (cmd - text);
+         text = cmd;
+       }
+    }
+
+  const char *word = advance_to_expression_complete_word_point (tracker, text);
+  expression_completer (ignore, tracker, text, word);
 }
 
 /* Iterate over the local variables of a block B, calling CB with
 }
 
 /* Iterate over the local variables of a block B, calling CB with
@@ -1967,6 +2252,7 @@ iterate_over_block_locals (const struct block *b,
     {
       switch (SYMBOL_CLASS (sym))
        {
     {
       switch (SYMBOL_CLASS (sym))
        {
+       case LOC_CONST:
        case LOC_LOCAL:
        case LOC_REGISTER:
        case LOC_STATIC:
        case LOC_LOCAL:
        case LOC_REGISTER:
        case LOC_STATIC:
@@ -1976,7 +2262,7 @@ iterate_over_block_locals (const struct block *b,
            break;
          if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
            break;
            break;
          if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
            break;
-         (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
+         (*cb) (sym->print_name (), sym, cb_data);
          break;
 
        default:
          break;
 
        default:
@@ -1986,56 +2272,6 @@ iterate_over_block_locals (const struct block *b,
     }
 }
 
     }
 }
 
-
-/* Same, but print labels.  */
-
-#if 0
-/* Commented out, as the code using this function has also been
-   commented out.  FIXME:brobecker/2009-01-13: Find out why the code
-   was commented out in the first place.  The discussion introducing
-   this change (2007-12-04: Support lexical blocks and function bodies
-   that occupy non-contiguous address ranges) did not explain why
-   this change was made.  */
-static int
-print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
-                         int *have_default, struct ui_file *stream)
-{
-  struct block_iterator iter;
-  struct symbol *sym;
-  int values_printed = 0;
-
-  ALL_BLOCK_SYMBOLS (b, iter, sym)
-    {
-      if (strcmp (SYMBOL_LINKAGE_NAME (sym), "default") == 0)
-       {
-         if (*have_default)
-           continue;
-         *have_default = 1;
-       }
-      if (SYMBOL_CLASS (sym) == LOC_LABEL)
-       {
-         struct symtab_and_line sal;
-         struct value_print_options opts;
-
-         sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
-         values_printed = 1;
-         fputs_filtered (SYMBOL_PRINT_NAME (sym), stream);
-         get_user_print_options (&opts);
-         if (opts.addressprint)
-           {
-             fprintf_filtered (stream, " ");
-             fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (sym)),
-                             stream);
-           }
-         fprintf_filtered (stream, " in file %s, line %d\n",
-                           sal.symtab->filename, sal.line);
-       }
-    }
-
-  return values_printed;
-}
-#endif
-
 /* Iterate over all the local variables in block B, including all its
    superblocks, stopping when the top-level block is reached.  */
 
 /* Iterate over all the local variables in block B, including all its
    superblocks, stopping when the top-level block is reached.  */
 
@@ -2061,6 +2297,8 @@ iterate_over_block_local_vars (const struct block *block,
 
 struct print_variable_and_value_data
 {
 
 struct print_variable_and_value_data
 {
+  gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
   struct frame_id frame_id;
   int num_tabs;
   struct ui_file *stream;
   struct frame_id frame_id;
   int num_tabs;
   struct ui_file *stream;
@@ -2078,6 +2316,13 @@ do_print_variable_and_value (const char *print_name,
     = (struct print_variable_and_value_data *) cb_data;
   struct frame_info *frame;
 
     = (struct print_variable_and_value_data *) cb_data;
   struct frame_info *frame;
 
+  if (p->preg.has_value ()
+      && p->preg->exec (sym->natural_name (), 0, NULL, 0) != 0)
+    return;
+  if (p->treg.has_value ()
+      && !treg_matches_sym_type_name (*p->treg, sym))
+    return;
+
   frame = frame_find_by_id (p->frame_id);
   if (frame == NULL)
     {
   frame = frame_find_by_id (p->frame_id);
   if (frame == NULL)
     {
@@ -2093,14 +2338,38 @@ do_print_variable_and_value (const char *print_name,
   p->values_printed = 1;
 }
 
   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.
 /* 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
 
    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;
 {
   struct print_variable_and_value_data cb_data;
   const struct block *block;
@@ -2108,18 +2377,22 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
 
   if (!get_frame_pc_if_available (frame, &pc))
     {
 
   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)
     {
       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;
     }
 
       return;
     }
 
+  prepare_reg (regexp, &cb_data.preg);
+  prepare_reg (t_regexp, &cb_data.treg);
   cb_data.frame_id = get_frame_id (frame);
   cb_data.num_tabs = 4 * num_tabs;
   cb_data.stream = stream;
   cb_data.frame_id = get_frame_id (frame);
   cb_data.num_tabs = 4 * num_tabs;
   cb_data.stream = stream;
@@ -2135,14 +2408,88 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
                                 do_print_variable_and_value,
                                 &cb_data);
 
                                 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"));
+    }
 }
 
 }
 
+/* Structure to hold the values of the options used by the 'info
+   variables' command and other similar commands.  These correspond to the
+   -q and -t options.  */
+
+struct info_print_options
+{
+  bool quiet = false;
+  char *type_regexp = nullptr;
+
+  ~info_print_options ()
+  {
+    xfree (type_regexp);
+  }
+};
+
+/* The options used by the 'info locals' and 'info args' commands.  */
+
+static const gdb::option::option_def info_print_options_defs[] = {
+  gdb::option::boolean_option_def<info_print_options> {
+    "q",
+    [] (info_print_options *opt) { return &opt->quiet; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_print_options> {
+    "t",
+    [] (info_print_options *opt) { return &opt->type_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  }
+};
+
+/* Returns the option group used by 'info locals' and 'info args'
+   commands.  */
+
+static gdb::option::option_def_group
+make_info_print_options_def_group (info_print_options *opts)
+{
+  return {{info_print_options_defs}, opts};
+}
+
+/* Command completer for 'info locals' and 'info args'.  */
+
+static void
+info_print_command_completer (struct cmd_list_element *ignore,
+                             completion_tracker &tracker,
+                             const char *text, const char * /* word */)
+{
+  const auto group
+    = make_info_print_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);
+}
+
+/* Implement the 'info locals' command.  */
+
 void
 info_locals_command (const char *args, int from_tty)
 {
 void
 info_locals_command (const char *args, int from_tty)
 {
+  info_print_options opts;
+  auto grp = make_info_print_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
   print_frame_local_vars (get_selected_frame (_("No frame selected.")),
   print_frame_local_vars (get_selected_frame (_("No frame selected.")),
+                         opts.quiet, args, opts.type_regexp,
                          0, gdb_stdout);
 }
 
                          0, gdb_stdout);
 }
 
@@ -2172,38 +2519,54 @@ iterate_over_block_arg_vars (const struct block *b,
             float).  There are also LOC_ARG/LOC_REGISTER pairs which
             are not combined in symbol-reading.  */
 
             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),
+         sym2 = lookup_symbol_search_name (sym->search_name (),
                                            b, VAR_DOMAIN).symbol;
                                            b, VAR_DOMAIN).symbol;
-         (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
+         (*cb) (sym->print_name (), sym2, cb_data);
        }
     }
 }
 
 /* Print all argument variables of the function of FRAME.
    Print them with values to STREAM.
        }
     }
 }
 
 /* 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
 
    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;
 {
   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))
     {
 
   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)
     {
       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;
     }
 
       return;
     }
 
+  prepare_reg (regexp, &cb_data.preg);
+  prepare_reg (t_regexp, &cb_data.treg);
   cb_data.frame_id = get_frame_id (frame);
   cb_data.num_tabs = 0;
   cb_data.stream = stream;
   cb_data.frame_id = get_frame_id (frame);
   cb_data.num_tabs = 0;
   cb_data.stream = stream;
@@ -2215,15 +2578,29 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
   /* do_print_variable_and_value invalidates FRAME.  */
   frame = NULL;
 
   /* 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"));
+    }
 }
 
 }
 
+/* Implement the 'info args' command.  */
+
 void
 void
-info_args_command (const char *ignore, int from_tty)
+info_args_command (const char *args, int from_tty)
 {
 {
+  info_print_options opts;
+  auto grp = make_info_print_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
   print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
   print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
-                       gdb_stdout);
+                       opts.quiet, args, opts.type_regexp, gdb_stdout);
 }
 \f
 /* Return the symbol-block in which the selected frame is executing.
 }
 \f
 /* Return the symbol-block in which the selected frame is executing.
@@ -2407,7 +2784,7 @@ return_command (const char *retval_exp, int from_tty)
        function = read_var_value (thisfun, NULL, thisframe);
 
       rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
        function = read_var_value (thisfun, NULL, thisframe);
 
       rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
-      if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
+      if (return_type->code () == TYPE_CODE_VOID)
        /* If the return-type is "void", don't try to find the
            return-value's location.  However, do still evaluate the
            return expression so that, even when the expression result
        /* If the return-type is "void", don't try to find the
            return-value's location.  However, do still evaluate the
            return expression so that, even when the expression result
@@ -2444,7 +2821,7 @@ return_command (const char *retval_exp, int from_tty)
          if (TYPE_NO_RETURN (thisfun->type))
            warning (_("Function does not return normally to caller."));
          confirmed = query (_("%sMake %s return now? "), query_prefix,
          if (TYPE_NO_RETURN (thisfun->type))
            warning (_("Function does not return normally to caller."));
          confirmed = query (_("%sMake %s return now? "), query_prefix,
-                            SYMBOL_PRINT_NAME (thisfun));
+                            thisfun->print_name ());
        }
       if (!confirmed)
        error (_("Not confirmed"));
        }
       if (!confirmed)
        error (_("Not confirmed"));
@@ -2548,6 +2925,42 @@ func_command (const char *arg, int from_tty)
     }
 }
 
     }
 }
 
+/* The qcs command line flags for the "frame apply" commands.  Keep
+   this in sync with the "thread apply" commands.  */
+
+using qcs_flag_option_def
+  = gdb::option::flag_option_def<qcs_flags>;
+
+static const gdb::option::option_def fr_qcs_flags_option_defs[] = {
+  qcs_flag_option_def {
+    "q", [] (qcs_flags *opt) { return &opt->quiet; },
+    N_("Disables printing the frame location information."),
+  },
+
+  qcs_flag_option_def {
+    "c", [] (qcs_flags *opt) { return &opt->cont; },
+    N_("Print any error raised by COMMAND and continue."),
+  },
+
+  qcs_flag_option_def {
+    "s", [] (qcs_flags *opt) { return &opt->silent; },
+    N_("Silently ignore any errors or empty output produced by COMMAND."),
+  },
+};
+
+/* Create an option_def_group array for all the "frame apply" options,
+   with FLAGS and SET_BT_OPTS as context.  */
+
+static inline std::array<gdb::option::option_def_group, 2>
+make_frame_apply_options_def_group (qcs_flags *flags,
+                                   set_backtrace_options *set_bt_opts)
+{
+  return {{
+    { {fr_qcs_flags_option_defs}, flags },
+    { {set_backtrace_option_defs}, set_bt_opts },
+  }};
+}
+
 /* Apply a GDB command to all stack frames, or a set of identified frames,
    or innermost COUNT frames.
    With a negative COUNT, apply command on outermost -COUNT frames.
 /* Apply a GDB command to all stack frames, or a set of identified frames,
    or innermost COUNT frames.
    With a negative COUNT, apply command on outermost -COUNT frames.
@@ -2577,10 +2990,13 @@ frame_apply_command_count (const char *which_command,
                           struct frame_info *trailing, int count)
 {
   qcs_flags flags;
                           struct frame_info *trailing, int count)
 {
   qcs_flags flags;
-  struct frame_info *fi;
+  set_backtrace_options set_bt_opts = user_set_backtrace_options;
+
+  auto group = make_frame_apply_options_def_group (&flags, &set_bt_opts);
+  gdb::option::process_options
+    (&cmd, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group);
 
 
-  while (cmd != NULL && parse_flags_qcs (which_command, &cmd, &flags))
-    ;
+  validate_flags_qcs (which_command, &flags);
 
   if (cmd == NULL || *cmd == '\0')
     error (_("Please specify a command to apply on the selected frames"));
 
   if (cmd == NULL || *cmd == '\0')
     error (_("Please specify a command to apply on the selected frames"));
@@ -2591,12 +3007,17 @@ frame_apply_command_count (const char *which_command,
      these also.  */
   scoped_restore_current_thread restore_thread;
 
      these also.  */
   scoped_restore_current_thread restore_thread;
 
-  for (fi = trailing; fi && count--; fi = get_prev_frame (fi))
+  /* These options are handled quite deep in the unwind machinery, so
+     we get to pass them down by swapping globals.  */
+  scoped_restore restore_set_backtrace_options
+    = make_scoped_restore (&user_set_backtrace_options, set_bt_opts);
+
+  for (frame_info *fi = trailing; fi && count--; fi = get_prev_frame (fi))
     {
       QUIT;
 
       select_frame (fi);
     {
       QUIT;
 
       select_frame (fi);
-      TRY
+      try
        {
          std::string cmd_result;
          {
        {
          std::string cmd_result;
          {
@@ -2605,7 +3026,8 @@ frame_apply_command_count (const char *which_command,
               set to the selected frame.  */
            scoped_restore_current_thread restore_fi_current_frame;
 
               set to the selected frame.  */
            scoped_restore_current_thread restore_fi_current_frame;
 
-           cmd_result = execute_command_to_string (cmd, from_tty);
+           cmd_result = execute_command_to_string
+             (cmd, from_tty, gdb_stdout->term_out ());
          }
          fi = get_selected_frame (_("frame apply "
                                     "unable to get selected frame."));
          }
          fi = get_selected_frame (_("frame apply "
                                     "unable to get selected frame."));
@@ -2616,7 +3038,7 @@ frame_apply_command_count (const char *which_command,
              printf_filtered ("%s", cmd_result.c_str ());
            }
        }
              printf_filtered ("%s", cmd_result.c_str ());
            }
        }
-      CATCH (ex, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &ex)
        {
          fi = get_selected_frame (_("frame apply "
                                     "unable to get selected frame."));
        {
          fi = get_selected_frame (_("frame apply "
                                     "unable to get selected frame."));
@@ -2625,15 +3047,112 @@ frame_apply_command_count (const char *which_command,
              if (!flags.quiet)
                print_stack_frame (fi, 1, LOCATION, 0);
              if (flags.cont)
              if (!flags.quiet)
                print_stack_frame (fi, 1, LOCATION, 0);
              if (flags.cont)
-               printf_filtered ("%s\n", ex.message);
+               printf_filtered ("%s\n", ex.what ());
              else
              else
-               throw_exception (ex);
+               throw;
            }
        }
            }
        }
-      END_CATCH;
     }
 }
 
     }
 }
 
+/* Completer for the "frame apply ..." commands.  */
+
+static void
+frame_apply_completer (completion_tracker &tracker, const char *text)
+{
+  const auto group = make_frame_apply_options_def_group (nullptr, nullptr);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
+
+  complete_nested_command_line (tracker, text);
+}
+
+/* Completer for the "frame apply" commands.  */
+
+static void
+frame_apply_level_cmd_completer (struct cmd_list_element *ignore,
+                                completion_tracker &tracker,
+                                const char *text, const char */*word*/)
+{
+  /* Do this explicitly because there's an early return below.  */
+  tracker.set_use_custom_word_point (true);
+
+  number_or_range_parser levels (text);
+
+  /* Skip the LEVEL list to find the options and command args.  */
+  try
+    {
+      while (!levels.finished ())
+       {
+         /* Call for effect.  */
+         levels.get_number ();
+
+         if (levels.in_range ())
+           levels.skip_range ();
+       }
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      /* get_number throws if it parses a negative number, for
+        example.  But a seemingly negative number may be the start of
+        an option instead.  */
+    }
+
+  const char *cmd = levels.cur_tok ();
+
+  if (cmd == text)
+    {
+      /* No level list yet.  */
+      return;
+    }
+
+  /* Check if we're past a valid LEVEL already.  */
+  if (levels.finished ()
+      && cmd > text && !isspace (cmd[-1]))
+    return;
+
+  /* We're past LEVELs, advance word point.  */
+  tracker.advance_custom_word_point_by (cmd - text);
+  text = cmd;
+
+  frame_apply_completer (tracker, text);
+}
+
+/* Completer for the "frame apply all" command.  */
+
+void
+frame_apply_all_cmd_completer (struct cmd_list_element *ignore,
+                              completion_tracker &tracker,
+                              const char *text, const char */*word*/)
+{
+  frame_apply_completer (tracker, text);
+}
+
+/* Completer for the "frame apply COUNT" command.  */
+
+static void
+frame_apply_cmd_completer (struct cmd_list_element *ignore,
+                          completion_tracker &tracker,
+                          const char *text, const char */*word*/)
+{
+  const char *cmd = text;
+
+  int count = get_number_trailer (&cmd, 0);
+  if (count == 0)
+    return;
+
+  /* Check if we're past a valid COUNT already.  */
+  if (cmd > text && !isspace (cmd[-1]))
+    return;
+
+  /* We're past COUNT, advance word point.  */
+  tracker.advance_custom_word_point_by (cmd - text);
+  text = cmd;
+
+  frame_apply_completer (tracker, text);
+}
+
 /* Implementation of the "frame apply level" command.  */
 
 static void
 /* Implementation of the "frame apply level" command.  */
 
 static void
@@ -2728,6 +3247,8 @@ frame_apply_command (const char* cmd, int from_tty)
 static void
 faas_command (const char *cmd, int from_tty)
 {
 static void
 faas_command (const char *cmd, int from_tty)
 {
+  if (cmd == NULL || *cmd == '\0')
+    error (_("Please specify a command to apply on all frames"));
   std::string expanded = std::string ("frame apply all -s ") + cmd;
   execute_command (expanded.c_str (), from_tty);
 }
   std::string expanded = std::string ("frame apply all -s ") + cmd;
   execute_command (expanded.c_str (), from_tty);
 }
@@ -2784,8 +3305,9 @@ static struct cmd_list_element *select_frame_cmd_list = NULL;
 /* Commands with a prefix of `info frame'.  */
 static struct cmd_list_element *info_frame_cmd_list = NULL;
 
 /* Commands with a prefix of `info frame'.  */
 static struct cmd_list_element *info_frame_cmd_list = NULL;
 
+void _initialize_stack ();
 void
 void
-_initialize_stack (void)
+_initialize_stack ()
 {
   struct cmd_list_element *cmd;
 
 {
   struct cmd_list_element *cmd;
 
@@ -2817,59 +3339,68 @@ Select and print a stack frame.\n\
 With no argument, print the selected stack frame.  (See also \"info frame\").\n\
 A single numerical argument specifies the frame to select."),
                   &frame_cmd_list, "frame ", 1, &cmdlist);
 With no argument, print the selected stack frame.  (See also \"info frame\").\n\
 A single numerical argument specifies the frame to select."),
                   &frame_cmd_list, "frame ", 1, &cmdlist);
-
   add_com_alias ("f", "frame", class_stack, 1);
 
   add_com_alias ("f", "frame", class_stack, 1);
 
-#define FRAME_APPLY_FLAGS_HELP "\
+#define FRAME_APPLY_OPTION_HELP "\
 Prints the frame location information followed by COMMAND output.\n\
 Prints the frame location information followed by COMMAND output.\n\
-FLAG arguments are -q (quiet), -c (continue), -s (silent).\n\
-Flag -q disables printing the frame location information.\n\
-By default, if a COMMAND raises an error, frame apply is aborted.\n\
-Flag -c indicates to print the error and continue.\n\
-Flag -s indicates to silently ignore a COMMAND that raises an error\n\
-or produces no output."
-
-  add_prefix_cmd ("apply", class_stack, frame_apply_command,
-                 _("Apply a command to a number of frames.\n\
-Usage: frame apply COUNT [FLAG]... COMMAND\n\
+\n\
+By default, an error raised during the execution of COMMAND\n\
+aborts \"frame apply\".\n\
+\n\
+Options:\n\
+%OPTIONS%"
+
+  const auto frame_apply_opts
+    = make_frame_apply_options_def_group (nullptr, nullptr);
+
+  static std::string frame_apply_cmd_help = gdb::option::build_help (_("\
+Apply a command to a number of frames.\n\
+Usage: frame apply COUNT [OPTION]... COMMAND\n\
 With a negative COUNT argument, applies the command on outermost -COUNT frames.\n"
 With a negative COUNT argument, applies the command on outermost -COUNT frames.\n"
-FRAME_APPLY_FLAGS_HELP),
-                 &frame_apply_cmd_list, "frame apply ", 1, &frame_cmd_list);
+                                 FRAME_APPLY_OPTION_HELP),
+                              frame_apply_opts);
 
 
-  add_cmd ("all", class_stack, frame_apply_all_command,
-          _("\
+  cmd = add_prefix_cmd ("apply", class_stack, frame_apply_command,
+                       frame_apply_cmd_help.c_str (),
+                       &frame_apply_cmd_list, "frame apply ", 1,
+                       &frame_cmd_list);
+  set_cmd_completer_handle_brkchars (cmd, frame_apply_cmd_completer);
+
+  static std::string frame_apply_all_cmd_help = gdb::option::build_help (_("\
 Apply a command to all frames.\n\
 \n\
 Apply a command to all frames.\n\
 \n\
-Usage: frame apply all [FLAG]... COMMAND\n"
-FRAME_APPLY_FLAGS_HELP),
-          &frame_apply_cmd_list);
+Usage: frame apply all [OPTION]... COMMAND\n"
+                                 FRAME_APPLY_OPTION_HELP),
+                              frame_apply_opts);
 
 
-  add_cmd ("level", class_stack, frame_apply_level_command,
-          _("\
+  cmd = add_cmd ("all", class_stack, frame_apply_all_command,
+                frame_apply_all_cmd_help.c_str (),
+                &frame_apply_cmd_list);
+  set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer);
+
+  static std::string frame_apply_level_cmd_help = gdb::option::build_help (_("\
 Apply a command to a list of frames.\n\
 \n\
 Apply a command to a list of frames.\n\
 \n\
-Usage: frame apply level LEVEL... [FLAG]... COMMAND\n\
-ID is a space-separated list of LEVELs of frames to apply COMMAND on.\n"
-FRAME_APPLY_FLAGS_HELP),
+Usage: frame apply level LEVEL... [OPTION]... COMMAND\n\
+LEVEL is a space-separated list of levels of frames to apply COMMAND on.\n"
+                                 FRAME_APPLY_OPTION_HELP),
+                              frame_apply_opts);
+
+  cmd = add_cmd ("level", class_stack, frame_apply_level_command,
+          frame_apply_level_cmd_help.c_str (),
           &frame_apply_cmd_list);
           &frame_apply_cmd_list);
+  set_cmd_completer_handle_brkchars (cmd, frame_apply_level_cmd_completer);
 
 
-  add_com ("faas", class_stack, faas_command, _("\
+  cmd = add_com ("faas", class_stack, faas_command, _("\
 Apply a command to all frames (ignoring errors and empty output).\n\
 Apply a command to all frames (ignoring errors and empty output).\n\
-Usage: faas COMMAND\n\
-shortcut for 'frame apply all -s COMMAND'"));
-
-
-  add_prefix_cmd ("frame", class_stack,
-                 &frame_cmd.base_command, _("\
-Select and print a stack frame.\n\
-With no argument, print the selected stack frame.  (See also \"info frame\").\n\
-A single numerical argument specifies the frame to select."),
-                 &frame_cmd_list, "frame ", 1, &cmdlist);
-  add_com_alias ("f", "frame", class_stack, 1);
+Usage: faas [OPTION]... COMMAND\n\
+shortcut for 'frame apply all -s [OPTION]... COMMAND'\n\
+See \"help frame apply all\" for available options."));
+  set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer);
 
   add_cmd ("address", class_stack, &frame_cmd.address,
           _("\
 
   add_cmd ("address", class_stack, &frame_cmd.address,
           _("\
-Select and print a stack frame by stack address\n\
+Select and print a stack frame by stack address.\n\
 \n\
 Usage: frame address STACK-ADDRESS"),
           &frame_cmd_list);
 \n\
 Usage: frame address STACK-ADDRESS"),
           &frame_cmd_list);
@@ -2942,16 +3473,34 @@ Usage: select-frame level LEVEL"),
                         &select_frame_cmd_list,
                         &cli_suppress_notification.user_selected_context);
 
                         &select_frame_cmd_list,
                         &cli_suppress_notification.user_selected_context);
 
-  add_com ("backtrace", class_stack, backtrace_command, _("\
+  const auto backtrace_opts
+    = make_backtrace_options_def_group (nullptr, nullptr, nullptr);
+
+  static std::string backtrace_help
+    = gdb::option::build_help (_("\
 Print backtrace of all stack frames, or innermost COUNT frames.\n\
 Print backtrace of all stack frames, or innermost COUNT frames.\n\
-Usage: backtrace [QUALIFIERS]... [COUNT]\n\
-With a negative argument, print outermost -COUNT frames.\n\
-Use of the 'full' qualifier also prints the values of the local variables.\n\
-Use of the 'no-filters' qualifier prohibits frame filters from executing\n\
-on this backtrace."));
+Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]\n\
+\n\
+Options:\n\
+%OPTIONS%\n\
+\n\
+For backward compatibility, the following qualifiers are supported:\n\
+\n\
+   full       - same as -full option.\n\
+   no-filters - same as -no-filters option.\n\
+   hide       - same as -hide.\n\
+\n\
+With a negative COUNT, print outermost -COUNT frames."),
+                              backtrace_opts);
+
+  cmd_list_element *c = add_com ("backtrace", class_stack,
+                                backtrace_command,
+                                backtrace_help.c_str ());
+  set_cmd_completer_handle_brkchars (c, backtrace_command_completer);
+
   add_com_alias ("bt", "backtrace", class_stack, 0);
 
   add_com_alias ("bt", "backtrace", class_stack, 0);
 
-  add_com_alias ("where", "backtrace", class_alias, 0);
+  add_com_alias ("where", "backtrace", class_stack, 0);
   add_info ("stack", backtrace_command,
            _("Backtrace of the stack, or innermost COUNT frames."));
   add_info_alias ("s", "stack", 1);
   add_info ("stack", backtrace_command,
            _("Backtrace of the stack, or innermost COUNT frames."));
   add_info_alias ("s", "stack", 1);
@@ -2994,30 +3543,41 @@ Print information about a stack frame selected by level.\n\
 Usage: info frame level LEVEL"),
           &info_frame_cmd_list);
 
 Usage: info frame level LEVEL"),
           &info_frame_cmd_list);
 
-  add_info ("locals", info_locals_command,
-           _("Local variables of current stack frame."));
-  add_info ("args", info_args_command,
-           _("Argument variables of current stack frame."));
+  cmd = add_info ("locals", info_locals_command,
+                 info_print_args_help (_("\
+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"),
+                                       _("local variables"),
+                                       false));
+  set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
+  cmd = add_info ("args", info_args_command,
+                 info_print_args_help (_("\
+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"),
+                                       _("argument variables"),
+                                       false));
+  set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
 
   if (dbx_commands)
     add_com ("func", class_stack, func_command, _("\
 Select the stack frame that contains NAME.\n\
 Usage: func NAME"));
 
 
   if (dbx_commands)
     add_com ("func", class_stack, func_command, _("\
 Select the stack frame that contains NAME.\n\
 Usage: func NAME"));
 
-  add_setshow_enum_cmd ("frame-arguments", class_stack,
-                       print_frame_arguments_choices, &print_frame_arguments,
-                       _("Set printing of non-scalar frame arguments"),
-                       _("Show printing of non-scalar frame arguments"),
-                       NULL, NULL, NULL, &setprintlist, &showprintlist);
-
-  add_setshow_boolean_cmd ("frame-arguments", no_class,
-                          &print_raw_frame_arguments, _("\
+  /* Install "set print raw frame-arguments", a deprecated spelling of
+     "set print raw-frame-arguments".  */
+  cmd = add_setshow_boolean_cmd
+    ("frame-arguments", no_class,
+     &user_frame_print_options.print_raw_frame_arguments,
+     _("\
 Set whether to print frame arguments in raw form."), _("\
 Show whether to print frame arguments in raw form."), _("\
 If set, frame arguments are printed in raw form, bypassing any\n\
 pretty-printers for that value."),
 Set whether to print frame arguments in raw form."), _("\
 Show whether to print frame arguments in raw form."), _("\
 If set, frame arguments are printed in raw form, bypassing any\n\
 pretty-printers for that value."),
-                          NULL, NULL,
-                          &setprintrawlist, &showprintrawlist);
+     NULL, NULL,
+     &setprintrawlist, &showprintrawlist);
+  deprecate_cmd (cmd, "set print raw-frame-arguments");
 
   add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
                                &disassemble_next_line, _("\
 
   add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
                                &disassemble_next_line, _("\
@@ -3039,16 +3599,7 @@ source line."),
                                &setlist, &showlist);
   disassemble_next_line = AUTO_BOOLEAN_FALSE;
 
                                &setlist, &showlist);
   disassemble_next_line = AUTO_BOOLEAN_FALSE;
 
-  add_setshow_enum_cmd ("entry-values", class_stack,
-                       print_entry_values_choices, &print_entry_values,
-                       _("Set printing of function arguments at function "
-                         "entry"),
-                       _("Show printing of function arguments at function "
-                         "entry"),
-                       _("\
-GDB can sometimes determine the values of function arguments at entry,\n\
-in addition to their current values.  This option tells GDB whether\n\
-to print the current value, the value at entry (marked as val@entry),\n\
-or both.  Note that one or both of these values may be <optimized out>."),
-                       NULL, NULL, &setprintlist, &showprintlist);
+  gdb::option::add_setshow_cmds_for_options
+    (class_stack, &user_frame_print_options,
+     frame_print_option_defs, &setprintlist, &showprintlist);
 }
 }
This page took 0.054385 seconds and 4 git commands to generate.