gdbsupport: make gdb_open_cloexec return scoped_fd
[binutils-gdb.git] / gdb / stack.c
index 06f10a1c3e90cf9aab99ff1bc3324dbb540e9b1b..7c4cf9491cc28653d5e34954a1f791f9d3d1fabc 100644 (file)
@@ -1,6 +1,6 @@
 /* Print and select stack frames for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -54,6 +54,7 @@
 #include "observable.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.  */
 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[] =
 {
   print_frame_arguments_all,
   print_frame_arguments_scalars,
   print_frame_arguments_none,
+  print_frame_arguments_presence,
   NULL
 };
 
+/* 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.  */
 
@@ -110,8 +140,8 @@ static const gdb::option::option_def frame_print_option_defs[] = {
     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_("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\
@@ -123,8 +153,8 @@ or both.  Note that one or both of these values may be <optimized out>."),
     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"),
+    N_("Set printing of non-scalar frame arguments."),
+    N_("Show printing of non-scalar frame arguments."),
     NULL /* help_doc */
   },
 
@@ -137,15 +167,26 @@ or both.  Note that one or both of these values may be <optimized out>."),
     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
 {
-  int full = 0;
-  int no_filters = 0;
-  int hide = 0;
+  bool full = false;
+  bool no_filters = false;
+  bool hide = false;
 };
 
 using bt_flag_option_def
@@ -183,12 +224,6 @@ static void print_frame (const frame_print_options &opts,
                         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);
 
@@ -200,19 +235,84 @@ static struct frame_info *find_frame_for_address (CORE_ADDR);
 
 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
 
-/* 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)
 {
@@ -227,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);
-      return 0;
+      return false;
     }
 
-  return get_frame_pc (frame) != sal.pc;
+  return get_frame_pc (frame) != sal.pc || !sal.is_stmt;
 }
 
 /* See frame.h.  */
@@ -257,7 +357,7 @@ print_stack_frame (struct frame_info *frame, int print_level,
                   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;
 
@@ -309,7 +409,7 @@ 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
-   iff it should not be printed accoring to user settings.  */
+   iff it should not be printed according to user settings.  */
 
 static void
 print_frame_arg (const frame_print_options &fp_opts,
@@ -327,31 +427,32 @@ print_frame_arg (const frame_print_options &fp_opts,
 
   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);
+  fputs_filtered (arg->sym->print_name (), &stb);
   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),
-                              DMGL_PARAMS | DMGL_ANSI);
+      fputs_filtered (arg->sym->print_name (), &stb);
     }
   if (arg->entry_kind == print_entry_values_only
       || arg->entry_kind == print_entry_values_compact)
     stb.puts ("@entry");
-  uiout->field_stream ("name", stb, ui_out_style_kind::VARIABLE);
+  uiout->field_stream ("name", stb, variable_name_style.style ());
   annotate_arg_name_end ();
   uiout->text ("=");
 
+  ui_file_style style;
   if (!arg->val && !arg->error)
     uiout->text ("...");
   else
     {
       if (arg->error)
-       stb.printf (_("<error reading variable: %s>"), arg->error);
+       {
+         stb.printf (_("<error reading variable: %s>"), arg->error.get ());
+         style = metadata_style.style ();
+       }
       else
        {
          try
@@ -370,7 +471,7 @@ print_frame_arg (const frame_print_options &fp_opts,
              /* 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;
 
@@ -382,17 +483,18 @@ print_frame_arg (const frame_print_options &fp_opts,
              vp_opts.summary
                = fp_opts.print_frame_arguments == print_frame_arguments_scalars;
 
-             common_val_print (arg->val, &stb, 2, &vp_opts, language);
+             common_val_print_checked (arg->val, &stb, 2, &vp_opts, language);
            }
          catch (const gdb_exception_error &except)
            {
              stb.printf (_("<error reading variable: %s>"),
                          except.what ());
+             style = metadata_style.style ();
            }
        }
     }
 
-  uiout->field_stream ("value", stb);
+  uiout->field_stream ("value", stb, style);
 }
 
 /* Read in inferior function local SYM at FRAME into ARGP.  Caller is
@@ -413,18 +515,17 @@ read_frame_local (struct symbol *sym, struct frame_info *frame,
     }
   catch (const gdb_exception_error &except)
     {
-      argp->error = xstrdup (except.what ());
+      argp->error.reset (xstrdup (except.what ()));
     }
 }
 
-/* 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
 read_frame_arg (const frame_print_options &fp_opts,
                symbol *sym, frame_info *frame,
-               struct frame_arg *argp, struct frame_arg *entryargp)
+               struct frame_arg *argp, struct frame_arg *entryargp)
 {
   struct value *val = NULL, *entryval = NULL;
   char *val_error = NULL, *entryval_error = NULL;
@@ -587,7 +688,7 @@ read_frame_arg (const frame_print_options &fp_opts,
 
   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;
   else if ((fp_opts.print_entry_values == print_entry_values_compact
@@ -602,7 +703,7 @@ read_frame_arg (const frame_print_options &fp_opts,
 
   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
@@ -631,9 +732,20 @@ print_frame_args (const frame_print_options &fp_opts,
   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.  */
   bool print_args
-    = fp_opts.print_frame_arguments != print_frame_arguments_none;
+    = (print_names
+       && fp_opts.print_frame_arguments != print_frame_arguments_none);
+
+  /* Temporarily change the selected frame to the given FRAME.
+     This allows routines that rely on the selected frame instead
+     of being given a frame as parameter to use the correct frame.  */
+  scoped_restore_selected_frame restore_selected_frame;
+  select_frame (frame);
 
   if (func)
     {
@@ -642,7 +754,7 @@ print_frame_args (const frame_print_options &fp_opts,
       struct symbol *sym;
 
       ALL_BLOCK_SYMBOLS (b, iter, sym)
-        {
+       {
          struct frame_arg arg, entryarg;
 
          QUIT;
@@ -653,6 +765,13 @@ print_frame_args (const frame_print_options &fp_opts,
          if (!SYMBOL_IS_ARGUMENT (sym))
            continue;
 
+         if (!print_names)
+           {
+             uiout->text ("...");
+             first = 0;
+             break;
+           }
+
          switch (SYMBOL_CLASS (sym))
            {
            case LOC_ARG:
@@ -701,11 +820,11 @@ print_frame_args (const frame_print_options &fp_opts,
             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;
 
-             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
@@ -720,22 +839,22 @@ print_frame_args (const frame_print_options &fp_opts,
                     Reasons for using the LOC_ARG:
 
                     (1) Because find_saved_registers may be slow for
-                        remote debugging.
+                        remote debugging.
 
                     (2) Because registers are often re-used and stack
-                        slots rarely (never?) are.  Therefore using
-                        the stack slot is much less likely to print
-                        garbage.
+                        slots rarely (never?) are.  Therefore using
+                        the stack slot is much less likely to print
+                        garbage.
 
                     Reasons why we might want to use the LOC_REGISTER:
 
                     (1) So that the backtrace prints the same value
-                        as "print foo".  I see no compelling reason
-                        why this needs to be the case; having the
-                        backtrace print the value which was passed
-                        in, and "print foo" print the value as
-                        modified within the called function, makes
-                        perfect sense to me.
+                        as "print foo".  I see no compelling reason
+                        why this needs to be the case; having the
+                        backtrace print the value which was passed
+                        in, and "print foo" print the value as
+                        modified within the called function, makes
+                        perfect sense to me.
 
                     Additional note: It might be nice if "info args"
                     displayed both values.
@@ -759,10 +878,8 @@ print_frame_args (const frame_print_options &fp_opts,
 
          if (!print_args)
            {
-             memset (&arg, 0, sizeof (arg));
              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;
            }
@@ -783,9 +900,6 @@ print_frame_args (const frame_print_options &fp_opts,
              print_frame_arg (fp_opts, &entryarg);
            }
 
-         xfree (arg.error);
-         xfree (entryarg.error);
-
          first = 0;
        }
     }
@@ -801,8 +915,11 @@ print_frame_args (const frame_print_options &fp_opts,
       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);
     }
 }
 
@@ -834,7 +951,7 @@ show_disassemble_next_line (struct ui_file *file, int from_tty,
   fprintf_filtered (file,
                    _("Debugger's willingness to use "
                      "disassemble-next-line is %s.\n"),
-                    value);
+                   value);
 }
 
 /* Use TRY_CATCH to catch the exception from the gdb_disassembly
@@ -859,13 +976,54 @@ do_gdb_disassembly (struct gdbarch *gdbarch,
     }
 }
 
+/* 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
-   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.  */
@@ -881,6 +1039,13 @@ print_frame_info (const frame_print_options &fp_opts,
   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)
@@ -891,37 +1056,36 @@ print_frame_info (const frame_print_options &fp_opts,
                            gdbarch, get_frame_pc (frame));
 
       /* Do this regardless of SOURCE because we don't have any source
-         to list for this frame.  */
+        to list for this frame.  */
       if (print_level)
-        {
-          uiout->text ("#");
-          uiout->field_fmt_signed (2, ui_left, "level",
+       {
+         uiout->text ("#");
+         uiout->field_fmt_signed (2, ui_left, "level",
                                   frame_relative_level (frame));
-        }
+       }
       if (uiout->is_mi_like_p ())
-        {
-          annotate_frame_address ();
-          uiout->field_core_addr ("addr",
-                                 gdbarch, get_frame_pc (frame));
-          annotate_frame_address_end ();
-        }
+       {
+         annotate_frame_address ();
+         print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
+         annotate_frame_address_end ();
+       }
 
       if (get_frame_type (frame) == DUMMY_FRAME)
-        {
-          annotate_function_call ();
-          uiout->field_string ("func", "<function called from gdb>",
-                              ui_out_style_kind::FUNCTION);
+       {
+         annotate_function_call ();
+         uiout->field_string ("func", "<function called from gdb>",
+                              metadata_style.style ());
        }
       else if (get_frame_type (frame) == SIGTRAMP_FRAME)
-        {
+       {
          annotate_signal_handler_caller ();
-          uiout->field_string ("func", "<signal handler called>",
-                              ui_out_style_kind::FUNCTION);
-        }
+         uiout->field_string ("func", "<signal handler called>",
+                              metadata_style.style ());
+       }
       else if (get_frame_type (frame) == ARCH_FRAME)
-        {
-          uiout->field_string ("func", "<cross-architecture call>",
-                              ui_out_style_kind::FUNCTION);
+       {
+         uiout->field_string ("func", "<cross-architecture call>",
+                              metadata_style.style ());
        }
       uiout->text ("\n");
       annotate_frame_end ();
@@ -944,10 +1108,10 @@ print_frame_info (const frame_print_options &fp_opts,
      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 == SRC_AND_LOC);
-
+                   || print_what == SHORT_LOCATION);
   if (location_print || !sal.symtab)
     print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
 
@@ -965,10 +1129,25 @@ print_frame_info (const frame_print_options &fp_opts,
     {
       int mid_statement = ((print_what == SRC_LINE)
                           && frame_show_address (frame, sal));
-      annotate_source_line (sal.symtab, sal.line, mid_statement,
-                           get_frame_pc (frame));
-
-      if (deprecated_print_frame_info_listing_hook)
+      if (annotation_level > 0
+         && annotate_source_line (sal.symtab, sal.line, mid_statement,
+                                  get_frame_pc (frame)))
+       {
+         /* 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
@@ -986,28 +1165,27 @@ print_frame_info (const frame_print_options &fp_opts,
             ability to decide for themselves if it is desired.  */
          if (opts.addressprint && mid_statement)
            {
-             uiout->field_core_addr ("addr",
-                                     gdbarch, get_frame_pc (frame));
+             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
-     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 is set to on and there is line debug
+        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 (set_current_sal)
     {
       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
-       set_last_displayed_sal (0, 0, 0, 0, 0);
+       last_displayed_symtab_info.invalidate ();
     }
 
   annotate_frame_end ();
@@ -1015,103 +1193,67 @@ print_frame_info (const frame_print_options &fp_opts,
   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)
 {
-  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)
 {
-  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)
 {
-  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)
 {
-  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)
 {
-  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)
 {
-  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;
 
-  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;
@@ -1135,14 +1277,14 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
   func = get_frame_function (frame);
   if (func)
     {
-      const char *print_name = SYMBOL_PRINT_NAME (func);
+      const char *print_name = func->print_name ();
 
-      *funlang = SYMBOL_LANGUAGE (func);
+      *funlang = func->language ();
       if (funcp)
        *funcp = func;
       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
@@ -1166,8 +1308,8 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
       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 ();
        }
     }
 
@@ -1213,19 +1355,18 @@ print_frame (const frame_print_options &fp_opts,
        {
          annotate_frame_address ();
          if (pc_p)
-           uiout->field_core_addr ("addr", gdbarch, pc);
+           print_pc (uiout, gdbarch, frame, pc);
          else
            uiout->field_string ("addr", "<unavailable>",
-                                ui_out_style_kind::ADDRESS);
+                                metadata_style.style ());
          annotate_frame_address_end ();
          uiout->text (" in ");
        }
     annotate_frame_function_name ();
 
     string_file stb;
-    fprintf_symbol_filtered (&stb, funname ? funname.get () : "??",
-                            funlang, DMGL_ANSI);
-    uiout->field_stream ("func", stb, ui_out_style_kind::FUNCTION);
+    fputs_filtered (funname ? funname.get () : "??", &stb);
+    uiout->field_stream ("func", stb, function_name_style.style ());
     uiout->wrap_hint ("   ");
     annotate_frame_args ();
 
@@ -1258,7 +1399,7 @@ print_frame (const frame_print_options &fp_opts,
        QUIT;
       }
     uiout->text (")");
-    if (sal.symtab)
+    if (print_what != SHORT_LOCATION && sal.symtab)
       {
        const char *filename_display;
       
@@ -1267,7 +1408,8 @@ print_frame (const frame_print_options &fp_opts,
        uiout->wrap_hint ("   ");
        uiout->text (" at ");
        annotate_frame_source_file ();
-       uiout->field_string ("file", filename_display, ui_out_style_kind::FILE);
+       uiout->field_string ("file", filename_display,
+                            file_name_style.style ());
        if (uiout->is_mi_like_p ())
          {
            const char *fullname = symtab_to_fullname (sal.symtab);
@@ -1281,7 +1423,8 @@ print_frame (const frame_print_options &fp_opts,
        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));
@@ -1291,7 +1434,7 @@ print_frame (const frame_print_options &fp_opts,
            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 ())
@@ -1306,7 +1449,7 @@ print_frame (const frame_print_options &fp_opts,
 /* 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)
@@ -1368,11 +1511,11 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
   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)
        {
-         /* 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
@@ -1390,8 +1533,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)
        {
-         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);
@@ -1411,19 +1554,21 @@ 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
-    fputs_filtered ("<unavailable>", gdb_stdout);
+    fputs_styled ("<unavailable>", metadata_style.style (), gdb_stdout);
 
   wrap_here ("   ");
   if (funname)
     {
       printf_filtered (" in ");
-      fprintf_symbol_filtered (gdb_stdout, funname, funlang,
-                              DMGL_ANSI | DMGL_PARAMS);
+      fputs_filtered (funname, gdb_stdout);
     }
   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);
@@ -1448,8 +1593,9 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
              val_print_not_saved (gdb_stdout);
              break;
            default:
-             fprintf_filtered (gdb_stdout, _("<error: %s>"),
-                               ex.what ());
+             fprintf_styled (gdb_stdout, metadata_style.style (),
+                             _("<error: %s>"),
+                             ex.what ());
              break;
            }
        }
@@ -1610,7 +1756,7 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
          int realnum;
 
          /* Find out the location of the saved register without
-             fetching the corresponding value.  */
+            fetching the corresponding value.  */
          frame_register_unwind (fi, i, &optimized, &unavailable,
                                 &lval, &addr, &realnum, NULL);
          /* For moment, only display registers that were saved on the
@@ -1691,9 +1837,9 @@ trailing_outermost_frame (int count)
 static void
 select_frame_command_core (struct frame_info *fi, bool ignored)
 {
-  struct frame_info *prev_frame = get_selected_frame_if_set ();
+  frame_info *prev_frame = get_selected_frame ();
   select_frame (fi);
-  if (get_selected_frame_if_set () != prev_frame)
+  if (get_selected_frame () != prev_frame)
     gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
 }
 
@@ -1712,10 +1858,9 @@ select_frame_for_mi (struct frame_info *fi)
 static void
 frame_command_core (struct frame_info *fi, bool ignored)
 {
-  struct frame_info *prev_frame = get_selected_frame_if_set ();
-
+  frame_info *prev_frame = get_selected_frame ();
   select_frame (fi);
-  if (get_selected_frame_if_set () != prev_frame)
+  if (get_selected_frame () != prev_frame)
     gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
   else
     print_selected_thread_frame (current_uiout, USER_SELECTED_FRAME);
@@ -1777,7 +1922,7 @@ public:
     struct frame_info *fid;
 
     if (args == NULL)
-    error (_("Missing address argument to view a frame"));
+      error (_("Missing address argument to view a frame"));
 
     gdb_argv argv (args);
 
@@ -1850,7 +1995,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
   int py_start = 0, py_end = 0;
   enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
 
-  if (!target_has_stack)
+  if (!target_has_stack ())
     error (_("No stack."));
 
   if (count_exp)
@@ -1891,8 +2036,12 @@ backtrace_command_1 (const frame_print_options &fp_opts,
        arg_type = CLI_SCALAR_VALUES;
       else if (fp_opts.print_frame_arguments == print_frame_arguments_all)
        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;
+      else
+       gdb_assert (0);
 
       result = apply_ext_lang_frame_filter (get_current_frame (), flags,
                                            arg_type, current_uiout,
@@ -2103,6 +2252,7 @@ iterate_over_block_locals (const struct block *b,
     {
       switch (SYMBOL_CLASS (sym))
        {
+       case LOC_CONST:
        case LOC_LOCAL:
        case LOC_REGISTER:
        case LOC_STATIC:
@@ -2112,7 +2262,7 @@ iterate_over_block_locals (const struct block *b,
            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:
@@ -2122,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.  */
 
@@ -2217,12 +2317,13 @@ do_print_variable_and_value (const char *print_name,
   struct frame_info *frame;
 
   if (p->preg.has_value ()
-      && p->preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
-                       NULL, 0) != 0)
+      && 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;
+  if (language_def (sym->language ())->symbol_printing_suppressed (sym))
+    return;
 
   frame = frame_find_by_id (p->frame_id);
   if (frame == NULL)
@@ -2318,13 +2419,76 @@ print_frame_local_vars (struct frame_info *frame,
     }
 }
 
+/* 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)
 {
   info_print_options opts;
-  extract_info_print_options (&opts, &args);
+  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.")),
                          opts.quiet, args, opts.type_regexp,
@@ -2357,9 +2521,9 @@ 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.  */
 
-         sym2 = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+         sym2 = lookup_symbol_search_name (sym->search_name (),
                                            b, VAR_DOMAIN).symbol;
-         (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
+         (*cb) (sym->print_name (), sym2, cb_data);
        }
     }
 }
@@ -2431,7 +2595,11 @@ void
 info_args_command (const char *args, int from_tty)
 {
   info_print_options opts;
-  extract_info_print_options (&opts, &args);
+  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.")),
                        opts.quiet, args, opts.type_regexp, gdb_stdout);
@@ -2538,9 +2706,9 @@ down_silently_base (const char *count_exp)
   if (count != 0 && count_exp == NULL)
     {
       /* We only do this if COUNT_EXP is not specified.  That way
-         "down" means to really go down (and let me know if that is
-         impossible), but "down 9999" can be used to mean go all the
-         way down without getting an error.  */
+        "down" means to really go down (and let me know if that is
+        impossible), but "down 9999" can be used to mean go all the
+        way down without getting an error.  */
 
       error (_("Bottom (innermost) frame selected; you cannot go down."));
     }
@@ -2590,17 +2758,17 @@ return_command (const char *retval_exp, int from_tty)
       struct type *return_type = NULL;
 
       /* Compute the return value.  Should the computation fail, this
-         call throws an error.  */
+        call throws an error.  */
       return_value = evaluate_expression (retval_expr.get ());
 
       /* Cast return value to the return type of the function.  Should
-         the cast fail, this call throws an error.  */
+        the cast fail, this call throws an error.  */
       if (thisfun != NULL)
        return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
       if (return_type == NULL)
-       {
-         if (retval_expr->elts[0].opcode != UNOP_CAST
-             && retval_expr->elts[0].opcode != UNOP_CAST_TYPE)
+       {
+         if (retval_expr->first_opcode () != UNOP_CAST
+             && retval_expr->first_opcode () != UNOP_CAST_TYPE)
            error (_("Return value type not available for selected "
                     "stack frame.\n"
                     "Please use an explicit cast of the value to return."));
@@ -2610,7 +2778,7 @@ return_command (const char *retval_exp, int from_tty)
       return_value = value_cast (return_type, return_value);
 
       /* Make sure the value is fully evaluated.  It may live in the
-         stack frame we're about to pop.  */
+        stack frame we're about to pop.  */
       if (value_lazy (return_value))
        value_fetch_lazy (return_value);
 
@@ -2618,12 +2786,12 @@ return_command (const char *retval_exp, int from_tty)
        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
-           is discarded, side effects such as "return i++" still
-           occur.  */
+          return-value's location.  However, do still evaluate the
+          return expression so that, even when the expression result
+          is discarded, side effects such as "return i++" still
+          occur.  */
        return_value = NULL;
       else if (thisfun != NULL)
        {
@@ -2655,7 +2823,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,
-                            SYMBOL_PRINT_NAME (thisfun));
+                            thisfun->print_name ());
        }
       if (!confirmed)
        error (_("Not confirmed"));
@@ -2803,15 +2971,15 @@ make_frame_apply_options_def_group (qcs_flags *flags,
    frame apply -3 info frame    Apply 'info frame' to outermost 3 frames.
    frame apply all x/i $pc      Apply 'x/i $pc' cmd to all frames.
    frame apply all -s p local_var_no_idea_in_which_frame
-                If a frame has a local variable called
-                local_var_no_idea_in_which_frame, print frame
-                and value of local_var_no_idea_in_which_frame.
+               If a frame has a local variable called
+               local_var_no_idea_in_which_frame, print frame
+               and value of local_var_no_idea_in_which_frame.
    frame apply all -s -q p local_var_no_idea_in_which_frame
-                Same as before, but only print the variable value.
+               Same as before, but only print the variable value.
    frame apply level 2-5 0 4-7 -s p i = i + 1
-                Adds 1 to the variable i in the specified frames.
-                Note that i will be incremented twice in
-                frames 4 and 5.  */
+               Adds 1 to the variable i in the specified frames.
+               Note that i will be incremented twice in
+               frames 4 and 5.  */
 
 /* Apply a GDB command to COUNT stack frames, starting at TRAILING.
    CMD starts with 0 or more qcs flags followed by the GDB command to apply.
@@ -2992,7 +3160,7 @@ frame_apply_cmd_completer (struct cmd_list_element *ignore,
 static void
 frame_apply_level_command (const char *cmd, int from_tty)
 {
-  if (!target_has_stack)
+  if (!target_has_stack ())
     error (_("No stack."));
 
   bool level_found = false;
@@ -3040,7 +3208,7 @@ frame_apply_level_command (const char *cmd, int from_tty)
 static void
 frame_apply_all_command (const char *cmd, int from_tty)
 {
-  if (!target_has_stack)
+  if (!target_has_stack ())
     error (_("No stack."));
 
   frame_apply_command_count ("frame apply all", cmd, from_tty,
@@ -3055,7 +3223,7 @@ frame_apply_command (const char* cmd, int from_tty)
   int count;
   struct frame_info *trailing;
 
-  if (!target_has_stack)
+  if (!target_has_stack ())
     error (_("No stack."));
 
   if (cmd == NULL)
@@ -3081,6 +3249,8 @@ frame_apply_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);
 }
@@ -3137,8 +3307,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;
 
+void _initialize_stack ();
 void
-_initialize_stack (void)
+_initialize_stack ()
 {
   struct cmd_list_element *cmd;
 
@@ -3155,23 +3326,24 @@ An argument says how many frames up to go."));
 Same as the `up' command, but does not print anything.\n\
 This is useful in command scripts."));
 
-  add_com ("down", class_stack, down_command, _("\
+  cmd_list_element *down_cmd
+    = add_com ("down", class_stack, down_command, _("\
 Select and print stack frame called by this one.\n\
 An argument says how many frames down to go."));
-  add_com_alias ("do", "down", class_stack, 1);
-  add_com_alias ("dow", "down", class_stack, 1);
+  add_com_alias ("do", down_cmd, class_stack, 1);
+  add_com_alias ("dow", down_cmd, class_stack, 1);
   add_com ("down-silently", class_support, down_silently_command, _("\
 Same as the `down' command, but does not print anything.\n\
 This is useful in command scripts."));
 
-  add_prefix_cmd ("frame", class_stack,
-                  &frame_cmd.base_command, _("\
+  cmd_list_element *frame_cmd_el
+    = 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);
+                     &frame_cmd_list, 1, &cmdlist);
+  add_com_alias ("f", frame_cmd_el, class_stack, 1);
 
 #define FRAME_APPLY_OPTION_HELP "\
 Prints the frame location information followed by COMMAND output.\n\
@@ -3185,7 +3357,7 @@ Options:\n\
   const auto frame_apply_opts
     = make_frame_apply_options_def_group (nullptr, nullptr);
 
-  static std::string frame_apply_cmd_help = gdb::option::build_help (N_("\
+  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"
@@ -3194,11 +3366,11 @@ With a negative COUNT argument, applies the command on outermost -COUNT frames.\
 
   cmd = add_prefix_cmd ("apply", class_stack, frame_apply_command,
                        frame_apply_cmd_help.c_str (),
-                       &frame_apply_cmd_list, "frame apply ", 1,
+                       &frame_apply_cmd_list, 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 (N_("\
+  static std::string frame_apply_all_cmd_help = gdb::option::build_help (_("\
 Apply a command to all frames.\n\
 \n\
 Usage: frame apply all [OPTION]... COMMAND\n"
@@ -3210,7 +3382,7 @@ Usage: frame apply all [OPTION]... COMMAND\n"
                 &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 (N_("\
+  static std::string frame_apply_level_cmd_help = gdb::option::build_help (_("\
 Apply a command to a list of frames.\n\
 \n\
 Usage: frame apply level LEVEL... [OPTION]... COMMAND\n\
@@ -3230,17 +3402,9 @@ 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_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);
-
   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);
@@ -3275,7 +3439,7 @@ Usage: frame level LEVEL"),
                      &select_frame_cmd.base_command, _("\
 Select a stack frame without printing anything.\n\
 A single numerical argument specifies the frame to select."),
-                     &select_frame_cmd_list, "select-frame ", 1, &cmdlist,
+                     &select_frame_cmd_list, 1, &cmdlist,
                      &cli_suppress_notification.user_selected_context);
 
   add_cmd_suppress_notification ("address", class_stack,
@@ -3317,12 +3481,13 @@ Usage: select-frame level LEVEL"),
     = make_backtrace_options_def_group (nullptr, nullptr, nullptr);
 
   static std::string backtrace_help
-    = gdb::option::build_help (N_("\
+    = gdb::option::build_help (_("\
 Print backtrace of all stack frames, or innermost COUNT frames.\n\
 Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]\n\
 \n\
 Options:\n\
-%OPTIONS%\
+%OPTIONS%\n\
+\n\
 For backward compatibility, the following qualifiers are supported:\n\
 \n\
    full       - same as -full option.\n\
@@ -3332,25 +3497,27 @@ For backward compatibility, the following qualifiers are supported:\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);
+  cmd_list_element *backtrace_cmd
+    = add_com ("backtrace", class_stack, backtrace_command,
+              backtrace_help.c_str ());
+  set_cmd_completer_handle_brkchars (backtrace_cmd, backtrace_command_completer);
 
-  add_com_alias ("bt", "backtrace", class_stack, 0);
+  add_com_alias ("bt", backtrace_cmd, class_stack, 0);
 
-  add_com_alias ("where", "backtrace", class_alias, 0);
-  add_info ("stack", backtrace_command,
-           _("Backtrace of the stack, or innermost COUNT frames."));
-  add_info_alias ("s", "stack", 1);
+  add_com_alias ("where", backtrace_cmd, class_stack, 0);
+  cmd_list_element *info_stack_cmd
+    = add_info ("stack", backtrace_command,
+               _("Backtrace of the stack, or innermost COUNT frames."));
+  add_info_alias ("s", info_stack_cmd, 1);
 
-  add_prefix_cmd ("frame", class_info, &info_frame_cmd.base_command,
-                 _("All about the selected stack frame.\n\
+  cmd_list_element *info_frame_cmd_el
+    = add_prefix_cmd ("frame", class_info, &info_frame_cmd.base_command,
+                     _("All about the selected stack frame.\n\
 With no arguments, displays information about the currently selected stack\n\
 frame.  Alternatively a frame specification may be provided (See \"frame\")\n\
 the information is then printed about the specified frame."),
-                 &info_frame_cmd_list, "info frame ", 1, &infolist);
-  add_info_alias ("f", "frame", 1);
+                     &info_frame_cmd_list, 1, &infolist);
+  add_info_alias ("f", info_frame_cmd_el, 1);
 
   add_cmd ("address", class_stack, &info_frame_cmd.address,
           _("\
@@ -3387,14 +3554,16 @@ Usage: info frame level LEVEL"),
 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")));
+                                       _("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")));
+                                       _("argument variables"),
+                                       false));
   set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
 
   if (dbx_commands)
@@ -3404,20 +3573,21 @@ Usage: func NAME"));
 
   /* 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_show_commands set_show_frame_args
+    = 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."),
-     NULL, NULL,
-     &setprintrawlist, &showprintrawlist);
-  deprecate_cmd (cmd, "set print raw-frame-arguments");
+       NULL, NULL,
+       &setprintrawlist, &showprintrawlist);
+  deprecate_cmd (set_show_frame_args.set, "set print raw-frame-arguments");
 
   add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
-                               &disassemble_next_line, _("\
+                               &disassemble_next_line, _("\
 Set whether to disassemble next source line or insn when execution stops."),
                                _("\
 Show whether to disassemble next source line or insn when execution stops."),
@@ -3431,9 +3601,9 @@ If AUTO, display disassembly of next instruction only if the source line\n\
 cannot be displayed.\n\
 If OFF (which is the default), never display the disassembly of the next\n\
 source line."),
-                               NULL,
-                               show_disassemble_next_line,
-                               &setlist, &showlist);
+                               NULL,
+                               show_disassemble_next_line,
+                               &setlist, &showlist);
   disassemble_next_line = AUTO_BOOLEAN_FALSE;
 
   gdb::option::add_setshow_cmds_for_options