/* Print and select stack frames for GDB, the GNU debugger.

   Copyright (C) 1986-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "event-top.h"
#include "exceptions.h"
#include "extract-store-integer.h"
#include "top.h"
#include "value.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "language.h"
#include "frame.h"
#include "cli/cli-cmds.h"
#include "gdbcore.h"
#include "target.h"
#include "source.h"
#include "breakpoint.h"
#include "demangle.h"
#include "inferior.h"
#include "annotate.h"
#include "ui-out.h"
#include "block.h"
#include "stack.h"
#include "dictionary.h"
#include "reggroups.h"
#include "regcache.h"
#include "solib.h"
#include "valprint.h"
#include "gdbthread.h"
#include "cp-support.h"
#include "disasm.h"
#include "inline-frame.h"
#include "linespec.h"
#include "cli/cli-utils.h"
#include "objfiles.h"

#include "symfile.h"
#include "extension.h"
#include "observable.h"
#include "gdbsupport/def-vector.h"
#include "cli/cli-option.h"
#include "cli/cli-style.h"
#include "gdbsupport/buildargv.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 std::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.  */

const char print_entry_values_no[] = "no";
const char print_entry_values_only[] = "only";
const char print_entry_values_preferred[] = "preferred";
const char print_entry_values_if_needed[] = "if-needed";
const char print_entry_values_both[] = "both";
const char print_entry_values_compact[] = "compact";
const char print_entry_values_default[] = "default";
static const char *const print_entry_values_choices[] =
{
  print_entry_values_no,
  print_entry_values_only,
  print_entry_values_preferred,
  print_entry_values_if_needed,
  print_entry_values_both,
  print_entry_values_compact,
  print_entry_values_default,
  NULL
};

/* 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.  */

static void print_frame_local_vars (const frame_info_ptr &frame,
				    bool quiet,
				    const char *regexp, const char *t_regexp,
				    int num_tabs, struct ui_file *stream);

static void print_frame (struct ui_out *uiout,
			 const frame_print_options &opts,
			 const frame_info_ptr &frame, int print_level,
			 enum print_what print_what,  int print_args,
			 struct symtab_and_line sal);

static frame_info_ptr find_frame_for_function (const char *);
static frame_info_ptr find_frame_for_address (CORE_ADDR);

/* 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;



/* See stack.h.  */

bool
frame_show_address (const frame_info_ptr &frame,
		    struct symtab_and_line sal)
{
  /* If there is a line number, but no PC, then there is no location
     information associated with this sal.  The only way that should
     happen is for the call sites of inlined functions (SAL comes from
     find_frame_sal).  Otherwise, we would have some PC range if the
     SAL came from a line table.  */
  if (sal.line != 0 && sal.pc == 0 && sal.end == 0)
    {
      if (get_next_frame (frame) == NULL)
	gdb_assert (inline_skipped_frames (inferior_thread ()) > 0);
      else
	gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
      return false;
    }

  return get_frame_pc (frame) != sal.pc || !sal.is_stmt;
}

/* See frame.h.  */

void
print_stack_frame_to_uiout (struct ui_out *uiout, const frame_info_ptr &frame,
			    int print_level, enum print_what print_what,
			    int set_current_sal)
{
  scoped_restore save_uiout = make_scoped_restore (&current_uiout, uiout);

  print_stack_frame (frame, print_level, print_what, set_current_sal);
}

/* Show or print a stack frame FRAME briefly.  The output is formatted
   according to PRINT_LEVEL and PRINT_WHAT printing the frame's
   relative level, function name, argument list, and file name and
   line number.  If the frame's PC is not at the beginning of the
   source line, the actual PC is printed at the beginning.  */

void
print_stack_frame (const frame_info_ptr &frame, int print_level,
		   enum print_what print_what,
		   int set_current_sal)
{

  /* For mi, always print location and address.  */
  if (current_uiout->is_mi_like_p ())
    print_what = LOC_AND_ADDRESS;

  try
    {
      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);
    }
  catch (const gdb_exception_error &e)
    {
    }
}

/* Print nameless arguments of frame FRAME on STREAM, where START is
   the offset of the first nameless argument, and NUM is the number of
   nameless arguments to print.  FIRST is nonzero if this is the first
   argument (not just the first nameless argument).  */

static void
print_frame_nameless_args (const frame_info_ptr &frame, long start, int num,
			   int first, struct ui_file *stream)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int i;
  CORE_ADDR argsaddr;
  long arg_value;

  for (i = 0; i < num; i++)
    {
      QUIT;
      argsaddr = get_frame_args_address (frame);
      if (!argsaddr)
	return;
      arg_value = read_memory_integer (argsaddr + start,
				       sizeof (int), byte_order);
      if (!first)
	gdb_printf (stream, ", ");
      gdb_printf (stream, "%ld", arg_value);
      first = 0;
      start += sizeof (int);
    }
}

/* Print single argument of inferior function.  ARG must be already
   read in.

   Errors are printed as if they would be the parameter value.  Use zeroed ARG
   iff it should not be printed according to user settings.  */

static void
print_frame_arg (const frame_print_options &fp_opts,
		 const struct frame_arg *arg)
{
  struct ui_out *uiout = current_uiout;

  string_file stb;

  gdb_assert (!arg->val || !arg->error);
  gdb_assert (arg->entry_kind == print_entry_values_no
	      || arg->entry_kind == print_entry_values_only
	      || (!uiout->is_mi_like_p ()
		  && arg->entry_kind == print_entry_values_compact));

  annotate_arg_emitter arg_emitter;
  ui_out_emit_tuple tuple_emitter (uiout, NULL);
  gdb_puts (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 ("=");

      gdb_puts (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, 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.get ());
	  style = metadata_style.style ();
	}
      else
	{
	  try
	    {
	      const struct language_defn *language;
	      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
		 address we do not know.  We pass 2 as "recurse" to val_print
		 because our standard indentation here is 4 spaces, and
		 val_print indents 2 for each recurse.  */ 

	      annotate_arg_value (arg->val->type ());

	      /* 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 (arg->sym->language ());
	      else
		language = current_language;

	      get_no_prettyformat_print_options (&vp_opts);
	      vp_opts.deref_ref = true;
	      vp_opts.raw = fp_opts.print_raw_frame_arguments;

	      /* True in "summary" mode, false otherwise.  */
	      vp_opts.summary
		= fp_opts.print_frame_arguments == print_frame_arguments_scalars;

	      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, style);
}

/* Read in inferior function local SYM at FRAME into ARGP.  Caller is
   responsible for xfree of ARGP->ERROR.  This function never throws an
   exception.  */

void
read_frame_local (struct symbol *sym, const frame_info_ptr &frame,
		  struct frame_arg *argp)
{
  argp->sym = sym;
  argp->val = NULL;
  argp->error = NULL;

  try
    {
      argp->val = read_var_value (sym, NULL, frame);
    }
  catch (const gdb_exception_error &except)
    {
      argp->error.reset (xstrdup (except.what ()));
    }
}

/* 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, const frame_info_ptr &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;

  if (fp_opts.print_entry_values != print_entry_values_only
      && fp_opts.print_entry_values != print_entry_values_preferred)
    {
      try
	{
	  val = read_var_value (sym, NULL, frame);
	}
      catch (const gdb_exception_error &except)
	{
	  val_error = (char *) alloca (except.message->size () + 1);
	  strcpy (val_error, except.what ());
	}
    }

  if (const symbol_computed_ops *computed_ops = sym->computed_ops ();
      (computed_ops != nullptr
       && computed_ops->read_variable_at_entry != nullptr
       && fp_opts.print_entry_values != print_entry_values_no
       && (fp_opts.print_entry_values != print_entry_values_if_needed || !val
	   || val->optimized_out ())))
    {
      try
	{
	  entryval = computed_ops->read_variable_at_entry (sym, frame);
	}
      catch (const gdb_exception_error &except)
	{
	  if (except.error != NO_ENTRY_VALUE_ERROR)
	    {
	      entryval_error = (char *) alloca (except.message->size () + 1);
	      strcpy (entryval_error, except.what ());
	    }
	}

      if (entryval != NULL && entryval->optimized_out ())
	entryval = NULL;

      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.  */

	  if (val && entryval && !current_uiout->is_mi_like_p ())
	    {
	      struct type *type = val->type ();

	      if (val->lazy ())
		val->fetch_lazy ();
	      if (entryval->lazy ())
		entryval->fetch_lazy ();

	      if (val->contents_eq (0, entryval, 0, type->length ()))
		{
		  /* Initialize it just to avoid a GCC false warning.  */
		  struct value *val_deref = NULL, *entryval_deref;

		  /* DW_AT_call_value does match with the current
		     value.  If it is a reference still try to verify if
		     dereferenced DW_AT_call_data_value does not differ.  */

		  try
		    {
		      struct type *type_deref;

		      val_deref = coerce_ref (val);
		      if (val_deref->lazy ())
			val_deref->fetch_lazy ();
		      type_deref = val_deref->type ();

		      entryval_deref = coerce_ref (entryval);
		      if (entryval_deref->lazy ())
			entryval_deref->fetch_lazy ();

		      /* If the reference addresses match but dereferenced
			 content does not match print them.  */
		      if (val != val_deref
			  && val_deref->contents_eq (0,
						     entryval_deref, 0,
						     type_deref->length ()))
			val_equal = 1;
		    }
		  catch (const gdb_exception_error &except)
		    {
		      /* If the dereferenced content could not be
			 fetched do not display anything.  */
		      if (except.error == NO_ENTRY_VALUE_ERROR)
			val_equal = 1;
		      else if (except.message != NULL)
			{
			  entryval_error
			    = (char *) alloca (except.message->size () + 1);
			  strcpy (entryval_error, except.what ());
			}
		    }

		  /* Value was not a reference; and its content matches.  */
		  if (val == val_deref)
		    val_equal = 1;

		  if (val_equal)
		    entryval = NULL;
		}
	    }

	  /* Try to remove possibly duplicate error message for ENTRYARGP even
	     in MI mode.  */

	  if (val_error && entryval_error
	      && strcmp (val_error, entryval_error) == 0)
	    {
	      entryval_error = NULL;

	      /* Do not se VAL_EQUAL as the same error message may be shown for
		 the entry value even if no entry values are present in the
		 inferior.  */
	    }
	}
    }

  if (entryval == NULL)
    {
      if (fp_opts.print_entry_values == print_entry_values_preferred)
	{
	  gdb_assert (val == NULL);

	  try
	    {
	      val = read_var_value (sym, NULL, frame);
	    }
	  catch (const gdb_exception_error &except)
	    {
	      val_error = (char *) alloca (except.message->size () + 1);
	      strcpy (val_error, except.what ());
	    }
	}
      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 || val->optimized_out ())))
	{
	  entryval = value::allocate_optimized_out (sym->type ());
	  entryval_error = NULL;
	}
    }
  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 || val->optimized_out ()) && entryval != NULL)
    {
      val = NULL;
      val_error = NULL;
    }

  argp->sym = sym;
  argp->val = val;
  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
	   || 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 ());
    }
  else
    argp->entry_kind = print_entry_values_no;

  entryargp->sym = sym;
  entryargp->val = entryval;
  entryargp->error.reset (entryval_error ? xstrdup (entryval_error) : NULL);
  if (!entryval && !entryval_error)
    entryargp->entry_kind = print_entry_values_no;
  else
    entryargp->entry_kind = print_entry_values_only;
}

/* Print the arguments of frame FRAME on STREAM, given the function
   FUNC running in that frame (as a symbol), where NUM is the number
   of arguments according to the stack frame (or -1 if the number of
   arguments is unknown).  */

/* Note that currently the "number of arguments according to the
   stack frame" is only known on VAX where i refers to the "number of
   ints of arguments according to the stack frame".  */

static void
print_frame_args (const frame_print_options &fp_opts,
		  struct symbol *func, const frame_info_ptr &frame,
		  int num, struct ui_file *stream)
{
  struct ui_out *uiout = current_uiout;
  int first = 1;
  /* Offset of next stack argument beyond the one we have seen that is
     at the highest offset, or -1 if we haven't come to a stack
     argument yet.  */
  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
    = (print_names
       && fp_opts.print_frame_arguments != print_frame_arguments_none);

  if (func)
    {
      const struct block *b = func->value_block ();

      for (struct symbol *sym : block_iterator_range (b))
	{
	  struct frame_arg arg, entryarg;

	  QUIT;

	  /* Keep track of the highest stack argument offset seen, and
	     skip over any kinds of symbols we don't care about.  */

	  if (!sym->is_argument ())
	    continue;

	  if (!print_names)
	    {
	      uiout->text ("...");
	      first = 0;
	      break;
	    }

	  switch (sym->aclass ())
	    {
	    case LOC_ARG:
	    case LOC_REF_ARG:
	      {
		long current_offset = sym->value_longest ();
		int arg_size = sym->type ()->length ();

		/* Compute address of next argument by adding the size of
		   this argument and rounding to an int boundary.  */
		current_offset =
		  ((current_offset + arg_size + sizeof (int) - 1)
		   & ~(sizeof (int) - 1));

		/* If this is the highest offset seen yet, set
		   highest_offset.  */
		if (highest_offset == -1
		    || (current_offset > highest_offset))
		  highest_offset = current_offset;

		/* Add the number of ints we're about to print to
		   args_printed.  */
		args_printed += (arg_size + sizeof (int) - 1) / sizeof (int);
	      }

	      /* We care about types of symbols, but don't need to
		 keep track of stack offsets in them.  */
	    case LOC_REGISTER:
	    case LOC_REGPARM_ADDR:
	    case LOC_COMPUTED:
	    case LOC_OPTIMIZED_OUT:
	    default:
	      break;
	    }

	  /* We have to look up the symbol because arguments can have
	     two entries (one a parameter, one a local) and the one we
	     want is the local, which lookup_symbol will find for us.
	     This includes gcc1 (not gcc2) on SPARC when passing a
	     small structure and gcc2 when the argument type is float
	     and it is passed as a double and converted to float by
	     the prologue (in the latter case the type of the LOC_ARG
	     symbol is double and the type of the LOC_LOCAL symbol is
	     float).  */
	  /* But if the parameter name is null, don't try it.  Null
	     parameter names occur on the RS/6000, for traceback
	     tables.  FIXME, should we even print them?  */

	  if (*sym->linkage_name ())
	    {
	      struct symbol *nsym;

	      nsym = lookup_symbol_search_name (sym->search_name (),
						b, SEARCH_VAR_DOMAIN).symbol;
	      gdb_assert (nsym != NULL);
	      if (nsym->aclass () == LOC_REGISTER
		  && !nsym->is_argument ())
		{
		  /* There is a LOC_ARG/LOC_REGISTER pair.  This means
		     that it was passed on the stack and loaded into a
		     register, or passed in a register and stored in a
		     stack slot.  GDB 3.x used the LOC_ARG; GDB
		     4.0-4.11 used the LOC_REGISTER.

		     Reasons for using the LOC_ARG:

		     (1) Because find_saved_registers may be slow for
			 remote debugging.

		     (2) Because registers are often reused and stack
			 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.

		     Additional note: It might be nice if "info args"
		     displayed both values.

		     One more note: There is a case with SPARC
		     structure passing where we need to use the
		     LOC_REGISTER, but this is dealt with by creating
		     a single LOC_REGPARM in symbol reading.  */

		  /* Leave sym (the LOC_ARG) alone.  */
		  ;
		}
	      else
		sym = nsym;
	    }

	  /* Print the current arg.  */
	  if (!first)
	    uiout->text (", ");
	  uiout->wrap_hint (4);

	  if (!print_args)
	    {
	      arg.sym = sym;
	      arg.entry_kind = print_entry_values_no;
	      entryarg.sym = sym;
	      entryarg.entry_kind = print_entry_values_no;
	    }
	  else
	    read_frame_arg (fp_opts, sym, frame, &arg, &entryarg);

	  if (arg.entry_kind != print_entry_values_only)
	    print_frame_arg (fp_opts, &arg);

	  if (entryarg.entry_kind != print_entry_values_no)
	    {
	      if (arg.entry_kind != print_entry_values_only)
		{
		  uiout->text (", ");
		  uiout->wrap_hint (4);
		}

	      print_frame_arg (fp_opts, &entryarg);
	    }

	  first = 0;
	}
    }

  /* Don't print nameless args in situations where we don't know
     enough about the stack to find them.  */
  if (num != -1)
    {
      long start;

      if (highest_offset == -1)
	start = gdbarch_frame_args_skip (get_frame_arch (frame));
      else
	start = highest_offset;

      if (!print_names && !first && num > 0)
	uiout->text ("...");
      else
	print_frame_nameless_args (frame, start, num - args_printed,
				   first, stream);
    }
}

/* Set the current source and line to the location given by frame
   FRAME, if possible.  When CENTER is true, adjust so the relevant
   line is in the center of the next 'list'.  */

void
set_current_sal_from_frame (const frame_info_ptr &frame)
{
  symtab_and_line sal = find_frame_sal (frame);
  if (sal.symtab != NULL)
    set_current_source_symtab_and_line (sal);
}

/* If ON, GDB will display disassembly of the next source line when
   execution of the program being debugged stops.
   If AUTO (which is the default), or there's no line info to determine
   the source line of the next instruction, display disassembly of next
   instruction instead.  */

static enum auto_boolean disassemble_next_line;

static void
show_disassemble_next_line (struct ui_file *file, int from_tty,
				 struct cmd_list_element *c,
				 const char *value)
{
  gdb_printf (file,
	      _("Debugger's willingness to use "
		"disassemble-next-line is %s.\n"),
	      value);
}

/* Use TRY_CATCH to catch the exception from the gdb_disassembly
   because it will be broken by filter sometime.  */

static void
do_gdb_disassembly (struct gdbarch *gdbarch,
		    int how_many, CORE_ADDR low, CORE_ADDR high)
{

  try
    {
      gdb_disassembly (gdbarch, current_uiout,
		       DISASSEMBLY_RAW_INSN, how_many,
		       low, high);
    }
  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);
    }
}

/* 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 std::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 ("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, const frame_info_ptr &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 (std::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.  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.  */

static void
do_print_frame_info (struct ui_out *uiout, const frame_print_options &fp_opts,
		     const frame_info_ptr &frame, int print_level,
		     enum print_what print_what, int print_args,
		     int set_current_sal)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  int source_print;
  int location_print;

  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)
    {
      ui_out_emit_tuple tuple_emitter (uiout, "frame");

      annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
			    gdbarch, get_frame_pc (frame));

      /* Do this regardless of SOURCE because we don't have any source
	 to list for this frame.  */
      if (print_level)
	{
	  uiout->text ("#");
	  uiout->field_fmt_signed (2, ui_left, "level",
				   frame_relative_level (frame));
	}
      if (uiout->is_mi_like_p ())
	{
	  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>",
			       metadata_style.style ());
	}
      else if (get_frame_type (frame) == SIGTRAMP_FRAME)
	{
	  annotate_signal_handler_caller ();
	  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>",
			       metadata_style.style ());
	}
      uiout->text ("\n");
      annotate_frame_end ();

      /* If disassemble-next-line is set to auto or on output the next
	 instruction.  */
      if (disassemble_next_line == AUTO_BOOLEAN_AUTO
	  || disassemble_next_line == AUTO_BOOLEAN_TRUE)
	do_gdb_disassembly (get_frame_arch (frame), 1,
			    get_frame_pc (frame), get_frame_pc (frame) + 1);

      return;
    }

  /* If FRAME is not the innermost frame, that normally means that
     FRAME->pc points to *after* the call instruction, and we want to
     get the line containing the call, never the next line.  But if
     the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
     next frame was not entered as the result of a call, and we want
     to get the line containing FRAME->pc.  */
  symtab_and_line sal = find_frame_sal (frame);

  location_print = (print_what == LOCATION
		    || print_what == SRC_AND_LOC
		    || print_what == LOC_AND_ADDRESS
		    || print_what == SHORT_LOCATION);
  if (location_print || !sal.symtab)
    print_frame (uiout, fp_opts, frame, print_level,
		 print_what, print_args, sal);

  source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);

  /* If disassemble-next-line is set to auto or on and doesn't have
     the line debug messages for $pc, output the next instruction.  */
  if ((disassemble_next_line == AUTO_BOOLEAN_AUTO
       || disassemble_next_line == AUTO_BOOLEAN_TRUE)
      && source_print && !sal.symtab)
    do_gdb_disassembly (get_frame_arch (frame), 1,
			get_frame_pc (frame), get_frame_pc (frame) + 1);

  if (source_print && sal.symtab)
    {
      int mid_statement = ((print_what == SRC_LINE)
			   && frame_show_address (frame, sal));
      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
	{
	  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)
	    {
	      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 (set_current_sal)
    {
      CORE_ADDR pc;

      if (get_frame_pc_if_available (frame, &pc))
	last_displayed_symtab_info.set (sal.pspace, pc, sal.symtab, sal.line);
      else
	last_displayed_symtab_info.invalidate ();
    }

  annotate_frame_end ();

  gdb_flush (gdb_stdout);
}

/* Redirect output to a temporary buffer for the duration
   of do_print_frame_info.  */

void
print_frame_info (const frame_print_options &fp_opts,
		  const frame_info_ptr &frame, int print_level,
		  enum print_what print_what, int print_args,
		  int set_current_sal)
{
  do_with_buffered_output (do_print_frame_info, current_uiout,
			   fp_opts, frame, print_level, print_what,
			   print_args, set_current_sal);
}

/* See stack.h.  */

void
clear_last_displayed_sal (void)
{
  last_displayed_symtab_info.invalidate ();
}

/* See stack.h.  */

bool
last_displayed_sal_is_valid (void)
{
  return last_displayed_symtab_info.is_valid ();
}

/* See stack.h.  */

struct program_space *
get_last_displayed_pspace (void)
{
  return last_displayed_symtab_info.pspace ();
}

/* See stack.h.  */

CORE_ADDR
get_last_displayed_addr (void)
{
  return last_displayed_symtab_info.address ();
}

/* See stack.h.  */

struct symtab*
get_last_displayed_symtab (void)
{
  return last_displayed_symtab_info.symtab ();
}

/* See stack.h.  */

int
get_last_displayed_line (void)
{
  return last_displayed_symtab_info.line ();
}

/* See stack.h.  */

symtab_and_line
get_last_displayed_sal ()
{
  symtab_and_line sal;

  if (last_displayed_symtab_info.is_valid ())
    {
      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;
}


/* Attempt to obtain the name, FUNLANG and optionally FUNCP of the function
   corresponding to FRAME.  */

gdb::unique_xmalloc_ptr<char>
find_frame_funname (const frame_info_ptr &frame, enum language *funlang,
		    struct symbol **funcp)
{
  struct symbol *func;
  gdb::unique_xmalloc_ptr<char> funname;

  *funlang = language_unknown;
  if (funcp)
    *funcp = NULL;

  func = get_frame_function (frame);
  if (func)
    {
      const char *print_name = func->print_name ();

      *funlang = func->language ();
      if (funcp)
	*funcp = func;
      if (*funlang == language_cplus)
	{
	  /* 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);
	}

      /* If we didn't hit the C++ case above, set *funname
	 here.  */
      if (funname == NULL)
	funname.reset (xstrdup (print_name));
    }
  else
    {
      CORE_ADDR pc;

      if (!get_frame_address_in_block_if_available (frame, &pc))
	return funname;

      bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
      if (msymbol.minsym != NULL)
	{
	  funname.reset (xstrdup (msymbol.minsym->print_name ()));
	  *funlang = msymbol.minsym->language ();
	}
    }

  return funname;
}

static void
print_frame (struct ui_out *uiout,
	     const frame_print_options &fp_opts,
	     const frame_info_ptr &frame, int print_level,
	     enum print_what print_what, int print_args,
	     struct symtab_and_line sal)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum language funlang = language_unknown;
  struct value_print_options opts;
  struct symbol *func;
  CORE_ADDR pc = 0;
  int pc_p;

  pc_p = get_frame_pc_if_available (frame, &pc);

  gdb::unique_xmalloc_ptr<char> funname
    = find_frame_funname (frame, &funlang, &func);

  annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
			gdbarch, pc);

  {
    ui_out_emit_tuple tuple_emitter (uiout, "frame");

    if (print_level)
      {
	uiout->text ("#");
	uiout->field_fmt_signed (2, ui_left, "level",
				 frame_relative_level (frame));
      }
    get_user_print_options (&opts);
    if (opts.addressprint)
      if (!sal.symtab
	  || frame_show_address (frame, sal)
	  || print_what == LOC_AND_ADDRESS)
	{
	  annotate_frame_address ();
	  if (pc_p)
	    print_pc (uiout, gdbarch, frame, pc);
	  else
	    uiout->field_string ("addr", "<unavailable>",
				 metadata_style.style ());
	  annotate_frame_address_end ();
	  uiout->text (" in ");
	}
    annotate_frame_function_name ();

    string_file stb;
    gdb_puts (funname ? funname.get () : "??", &stb);
    uiout->field_stream ("func", stb, function_name_style.style ());
    uiout->wrap_hint (3);
    annotate_frame_args ();

    uiout->text (" (");
    if (print_args)
      {
	int numargs;

	if (gdbarch_frame_num_args_p (gdbarch))
	  {
	    numargs = gdbarch_frame_num_args (gdbarch, frame);
	    gdb_assert (numargs >= 0);
	  }
	else
	  numargs = -1;
    
	{
	  ui_out_emit_list list_emitter (uiout, "args");
	  try
	    {
	      print_frame_args (fp_opts, func, frame, numargs, gdb_stdout);
	    }
	  catch (const gdb_exception_error &e)
	    {
	    }

	    /* FIXME: ARGS must be a list.  If one argument is a string it
	       will have " that will not be properly escaped.  */
	    }
	QUIT;
      }
    uiout->text (")");
    if (print_what != SHORT_LOCATION && sal.symtab)
      {
	const char *filename_display;
      
	filename_display = symtab_to_filename_for_display (sal.symtab);
	annotate_frame_source_begin ();
	uiout->wrap_hint (3);
	uiout->text (" at ");
	annotate_frame_source_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);

	    uiout->field_string ("fullname", fullname);
	  }
	annotate_frame_source_file_end ();
	uiout->text (":");
	annotate_frame_source_line ();
	uiout->field_signed ("line", sal.line, line_number_style.style ());
	annotate_frame_source_end ();
      }

    if (print_what != SHORT_LOCATION
	&& pc_p && (funname == NULL || sal.symtab == NULL))
      {
	const char *lib
	  = solib_name_from_address (get_frame_program_space (frame),
				     get_frame_address_in_block (frame));

	if (lib)
	  {
	    annotate_frame_where ();
	    uiout->wrap_hint (2);
	    uiout->text (" from ");
	    uiout->field_string ("from", lib, file_name_style.style ());
	  }
      }
    if (uiout->is_mi_like_p ())
      uiout->field_string ("arch",
			   (gdbarch_bfd_arch_info (gdbarch))->printable_name);
  }

  uiout->text ("\n");
}


/* Completion function for "frame function", "info frame function", and
   "select-frame function" commands.  */

static void
frame_selection_by_function_completer (struct cmd_list_element *ignore,
				       completion_tracker &tracker,
				       const char *text, const char *word)
{
  /* This is used to complete function names within a stack.  It would be
     nice if we only offered functions that were actually in the stack.
     However, this would mean unwinding the stack to completion, which
     could take too long, or on a corrupted stack, possibly not end.
     Instead, we offer all symbol names as a safer choice.  */
  collect_symbol_completion_matches (tracker,
				     complete_symbol_mode::EXPRESSION,
				     symbol_name_match_type::EXPRESSION,
				     text, word);
}

/* Core of all the "info frame" sub-commands.  Print information about a
   frame FI.  If SELECTED_FRAME_P is true then the user didn't provide a
   frame specification, they just entered 'info frame'.  If the user did
   provide a frame specification (for example 'info frame 0', 'info frame
   level 1') then SELECTED_FRAME_P will be false.  */

static void
info_frame_command_core (const frame_info_ptr &fi, bool selected_frame_p)
{
  struct symbol *func;
  struct symtab *s;
  frame_info_ptr calling_frame_info;
  int numregs;
  const char *funname = 0;
  enum language funlang = language_unknown;
  const char *pc_regname;
  struct gdbarch *gdbarch;
  CORE_ADDR frame_pc;
  int frame_pc_p;
  /* Initialize it to avoid "may be used uninitialized" warning.  */
  CORE_ADDR caller_pc = 0;
  int caller_pc_p = 0;

  gdbarch = get_frame_arch (fi);

  /* Name of the value returned by get_frame_pc().  Per comments, "pc"
     is not a good name.  */
  if (gdbarch_pc_regnum (gdbarch) >= 0)
    /* OK, this is weird.  The gdbarch_pc_regnum hardware register's value can
       easily not match that of the internal value returned by
       get_frame_pc().  */
    pc_regname = gdbarch_register_name (gdbarch, gdbarch_pc_regnum (gdbarch));
  else
    /* But then, this is weird to.  Even without gdbarch_pc_regnum, an
       architectures will often have a hardware register called "pc",
       and that register's value, again, can easily not match
       get_frame_pc().  */
    pc_regname = "pc";

  frame_pc_p = get_frame_pc_if_available (fi, &frame_pc);
  func = get_frame_function (fi);
  symtab_and_line sal = find_frame_sal (fi);
  s = sal.symtab;
  gdb::unique_xmalloc_ptr<char> func_only;
  if (func)
    {
      funname = func->print_name ();
      funlang = func->language ();
      if (funlang == language_cplus)
	{
	  /* 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.  */
	  func_only = cp_remove_params (funname);

	  if (func_only)
	    funname = func_only.get ();
	}
    }
  else if (frame_pc_p)
    {
      bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (frame_pc);
      if (msymbol.minsym != NULL)
	{
	  funname = msymbol.minsym->print_name ();
	  funlang = msymbol.minsym->language ();
	}
    }
  calling_frame_info = get_prev_frame (fi);

  if (selected_frame_p && frame_relative_level (fi) >= 0)
    {
      gdb_printf (_("Stack level %d, frame at "),
		  frame_relative_level (fi));
    }
  else
    {
      gdb_printf (_("Stack frame at "));
    }
  gdb_puts (paddress (gdbarch, get_frame_base (fi)));
  gdb_printf (":\n");
  gdb_printf (" %s = ", pc_regname);
  if (frame_pc_p)
    gdb_puts (paddress (gdbarch, get_frame_pc (fi)));
  else
    fputs_styled ("<unavailable>", metadata_style.style (), gdb_stdout);

  gdb_stdout->wrap_here (3);
  if (funname)
    {
      gdb_printf (" in ");
      gdb_puts (funname);
    }
  gdb_stdout->wrap_here (3);
  if (sal.symtab)
    gdb_printf
      (" (%ps:%d)",
       styled_string (file_name_style.style (),
		      symtab_to_filename_for_display (sal.symtab)),
       sal.line);
  gdb_puts ("; ");
  gdb_stdout->wrap_here (4);
  gdb_printf ("saved %s = ", pc_regname);

  if (!frame_id_p (frame_unwind_caller_id (fi)))
    val_print_not_saved (gdb_stdout);
  else
    {
      try
	{
	  caller_pc = frame_unwind_caller_pc (fi);
	  caller_pc_p = 1;
	}
      catch (const gdb_exception_error &ex)
	{
	  switch (ex.error)
	    {
	    case NOT_AVAILABLE_ERROR:
	      val_print_unavailable (gdb_stdout);
	      break;
	    case OPTIMIZED_OUT_ERROR:
	      val_print_not_saved (gdb_stdout);
	      break;
	    default:
	      fprintf_styled (gdb_stdout, metadata_style.style (),
			      _("<error: %s>"),
			      ex.what ());
	      break;
	    }
	}
    }

  if (caller_pc_p)
    gdb_puts (paddress (gdbarch, caller_pc));
  gdb_printf ("\n");

  if (calling_frame_info == NULL)
    {
      enum unwind_stop_reason reason;

      reason = get_frame_unwind_stop_reason (fi);
      if (reason != UNWIND_NO_REASON)
	gdb_printf (_(" Outermost frame: %s\n"),
		    frame_stop_reason_string (fi));
    }
  else if (get_frame_type (fi) == TAILCALL_FRAME)
    gdb_puts (" tail call frame");
  else if (get_frame_type (fi) == INLINE_FRAME)
    gdb_printf (" inlined into frame %d",
		frame_relative_level (get_prev_frame (fi)));
  else
    {
      gdb_printf (" called by frame at ");
      gdb_puts (paddress (gdbarch, get_frame_base (calling_frame_info)));
    }
  if (get_next_frame (fi) && calling_frame_info)
    gdb_puts (",");
  gdb_stdout->wrap_here (3);
  if (get_next_frame (fi))
    {
      gdb_printf (" caller of frame at ");
      gdb_puts (paddress (gdbarch, get_frame_base (get_next_frame (fi))));
    }
  if (get_next_frame (fi) || calling_frame_info)
    gdb_puts ("\n");

  if (s)
    gdb_printf (" source language %s.\n",
		language_str (s->language ()));

  {
    /* Address of the argument list for this frame, or 0.  */
    CORE_ADDR arg_list = get_frame_args_address (fi);
    /* Number of args for this frame, or -1 if unknown.  */
    int numargs;

    if (arg_list == 0)
      gdb_printf (" Arglist at unknown address.\n");
    else
      {
	gdb_printf (" Arglist at ");
	gdb_puts (paddress (gdbarch, arg_list));
	gdb_printf (",");

	if (!gdbarch_frame_num_args_p (gdbarch))
	  {
	    numargs = -1;
	    gdb_puts (" args: ");
	  }
	else
	  {
	    numargs = gdbarch_frame_num_args (gdbarch, fi);
	    gdb_assert (numargs >= 0);
	    if (numargs == 0)
	      gdb_puts (" no args.");
	    else if (numargs == 1)
	      gdb_puts (" 1 arg: ");
	    else
	      gdb_printf (" %d args: ", numargs);
	  }

	print_frame_args (user_frame_print_options,
			  func, fi, numargs, gdb_stdout);
	gdb_puts ("\n");
      }
  }
  {
    /* Address of the local variables for this frame, or 0.  */
    CORE_ADDR arg_list = get_frame_locals_address (fi);

    if (arg_list == 0)
      gdb_printf (" Locals at unknown address,");
    else
      {
	gdb_printf (" Locals at ");
	gdb_puts (paddress (gdbarch, arg_list));
	gdb_printf (",");
      }
  }

  /* Print as much information as possible on the location of all the
     registers.  */
  {
    int count;
    int i;
    int need_nl = 1;
    int sp_regnum = gdbarch_sp_regnum (gdbarch);

    /* The sp is special; what's displayed isn't the save address, but
       the value of the previous frame's sp.  This is a legacy thing,
       at one stage the frame cached the previous frame's SP instead
       of its address, hence it was easiest to just display the cached
       value.  */
    if (sp_regnum >= 0)
      {
	struct value *value = frame_unwind_register_value (fi, sp_regnum);
	gdb_assert (value != NULL);

	if (!value->optimized_out () && value->entirely_available ())
	  {
	    if (value->lval () == not_lval)
	      {
		CORE_ADDR sp;
		enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
		int sp_size = register_size (gdbarch, sp_regnum);

		sp = extract_unsigned_integer
		  (value->contents_all ().data (), sp_size, byte_order);

		gdb_printf (" Previous frame's sp is ");
		gdb_puts (paddress (gdbarch, sp));
		gdb_printf ("\n");
	      }
	    else if (value->lval () == lval_memory)
	      {
		gdb_printf (" Previous frame's sp at ");
		gdb_puts (paddress (gdbarch, value->address ()));
		gdb_printf ("\n");
	      }
	    else if (value->lval () == lval_register)
	      gdb_printf (" Previous frame's sp in %s\n",
			  gdbarch_register_name (gdbarch, value->regnum ()));

	    release_value (value);
	    need_nl = 0;
	  }
	/* else keep quiet.  */
      }

    count = 0;
    numregs = gdbarch_num_cooked_regs (gdbarch);
    for (i = 0; i < numregs; i++)
      if (i != sp_regnum
	  && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
	{
	  enum lval_type lval;
	  int optimized;
	  int unavailable;
	  CORE_ADDR addr;
	  int realnum;

	  /* Find out the location of the saved register without
	     fetching the corresponding value.  */
	  frame_register_unwind (fi, i, &optimized, &unavailable,
				 &lval, &addr, &realnum);
	  /* For moment, only display registers that were saved on the
	     stack.  */
	  if (!optimized && !unavailable && lval == lval_memory)
	    {
	      if (count == 0)
		gdb_puts (" Saved registers:\n ");
	      else
		gdb_puts (",");
	      gdb_stdout->wrap_here (1);
	      gdb_printf (" %s at ",
			  gdbarch_register_name (gdbarch, i));
	      gdb_puts (paddress (gdbarch, addr));
	      count++;
	    }
	}
    if (count || need_nl)
      gdb_puts ("\n");
  }
}

/* Return the innermost frame at level LEVEL.  */

static frame_info_ptr
leading_innermost_frame (int level)
{
  frame_info_ptr leading;

  leading = get_current_frame ();

  gdb_assert (level >= 0);

  while (leading != nullptr && level)
    {
      QUIT;
      leading = get_prev_frame (leading);
      level--;
    }

  return leading;
}

/* Return the starting frame needed to handle COUNT outermost frames.  */

static frame_info_ptr
trailing_outermost_frame (int count)
{
  frame_info_ptr current;
  frame_info_ptr trailing;

  trailing = get_current_frame ();

  gdb_assert (count > 0);

  current = trailing;
  while (current != nullptr && count--)
    {
      QUIT;
      current = get_prev_frame (current);
    }

  /* Will stop when CURRENT reaches the top of the stack.
     TRAILING will be COUNT below it.  */
  while (current != nullptr)
    {
      QUIT;
      trailing = get_prev_frame (trailing);
      current = get_prev_frame (current);
    }

  return trailing;
}

/* The core of all the "select-frame" sub-commands.  Just wraps a call to
   SELECT_FRAME.  */

static void
select_frame_command_core (const frame_info_ptr &fi, bool ignored)
{
  frame_info_ptr prev_frame = get_selected_frame ();
  select_frame (fi);
  if (get_selected_frame () != prev_frame)
    notify_user_selected_context_changed (USER_SELECTED_FRAME);
}

/* The core of all the "frame" sub-commands.  Select frame FI, and if this
   means we change frame send out a change notification (otherwise, just
   reprint the current frame summary).   */

static void
frame_command_core (const frame_info_ptr &fi, bool ignored)
{
  frame_info_ptr prev_frame = get_selected_frame ();
  select_frame (fi);
  if (get_selected_frame () != prev_frame)
    notify_user_selected_context_changed (USER_SELECTED_FRAME);
  else
    print_selected_thread_frame (current_uiout, USER_SELECTED_FRAME);
}

/* The three commands 'frame', 'select-frame', and 'info frame' all have a
   common set of sub-commands that allow a specific frame to be selected.
   All of the sub-command functions are static methods within this class
   template which is then instantiated below.  The template parameter is a
   callback used to implement the functionality of the base command
   ('frame', 'select-frame', or 'info frame').

   In the template parameter FI is the frame being selected.  The
   SELECTED_FRAME_P flag is true if the frame being selected was done by
   default, which happens when the user uses the base command with no
   arguments.  For example the commands 'info frame', 'select-frame',
   'frame' will all cause SELECTED_FRAME_P to be true.  In all other cases
   SELECTED_FRAME_P is false.  */

template <void (*FPTR) (const frame_info_ptr &fi, bool selected_frame_p)>
class frame_command_helper
{
public:

  /* The "frame level" family of commands.  The ARG is an integer that is
     the frame's level in the stack.  */
  static void
  level (const char *arg, int from_tty)
  {
    int level = value_as_long (parse_and_eval (arg));
    frame_info_ptr fid
      = find_relative_frame (get_current_frame (), &level);
    if (level != 0)
      error (_("No frame at level %s."), arg);
    FPTR (fid, false);
  }

  /* The "frame address" family of commands.  ARG is a stack-pointer
     address for an existing frame.  This command does not allow new
     frames to be created.  */

  static void
  address (const char *arg, int from_tty)
  {
    CORE_ADDR addr = value_as_address (parse_and_eval (arg));
    frame_info_ptr fid = find_frame_for_address (addr);
    if (fid == NULL)
      error (_("No frame at address %s."), arg);
    FPTR (fid, false);
  }

  /* The "frame view" family of commands.  ARG is one or two addresses and
     is used to view a frame that might be outside the current backtrace.
     The addresses are stack-pointer address, and (optional) pc-address.  */

  static void
  view (const char *args, int from_tty)
  {
    frame_info_ptr fid;

    if (args == NULL)
      error (_("Missing address argument to view a frame"));

    gdb_argv argv (args);

    if (argv.count () == 2)
      {
	CORE_ADDR addr[2];

	addr [0] = value_as_address (parse_and_eval (argv[0]));
	addr [1] = value_as_address (parse_and_eval (argv[1]));
	fid = create_new_frame (addr[0], addr[1]);
      }
    else
      {
	CORE_ADDR addr = value_as_address (parse_and_eval (argv[0]));
	fid = create_new_frame (addr, false);
      }
    FPTR (fid, false);
  }

  /* The "frame function" family of commands.  ARG is the name of a
     function within the stack, the first function (searching from frame
     0) with that name will be selected.  */

  static void
  function (const char *arg, int from_tty)
  {
    if (arg == NULL)
      error (_("Missing function name argument"));
    frame_info_ptr fid = find_frame_for_function (arg);
    if (fid == NULL)
      error (_("No frame for function \"%s\"."), arg);
    FPTR (fid, false);
  }

  /* The "frame" base command, that is, when no sub-command is specified.
     If one argument is provided then we assume that this is a frame's
     level as historically, this was the supported command syntax that was
     used most often.

     If no argument is provided, then the current frame is selected.  */

  static void
  base_command (const char *arg, int from_tty)
  {
    if (arg == NULL)
      FPTR (get_selected_frame (_("No stack.")), true);
    else
      level (arg, from_tty);
  }
};

/* Instantiate three FRAME_COMMAND_HELPER instances to implement the
   sub-commands for 'info frame', 'frame', and 'select-frame' commands.  */

static frame_command_helper <info_frame_command_core> info_frame_cmd;
static frame_command_helper <frame_command_core> frame_cmd;
static frame_command_helper <select_frame_command_core> select_frame_cmd;

/* Print briefly all stack frames or just the innermost COUNT_EXP
   frames.  */

static void
backtrace_command_1 (const frame_print_options &fp_opts,
		     const backtrace_cmd_options &bt_opts,
		     const char *count_exp, int from_tty)

{
  frame_info_ptr fi;
  int count;
  int py_start = 0, py_end = 0;
  enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;

  if (!target_has_stack ())
    error (_("No stack."));

  if (count_exp)
    {
      count = parse_and_eval_long (count_exp);
      if (count < 0)
	py_start = count;
      else
	{
	  py_start = 0;
	  /* The argument to apply_ext_lang_frame_filter is the number
	     of the final frame to print, and frames start at 0.  */
	  py_end = count - 1;
	}
    }
  else
    {
      py_end = -1;
      count = -1;
    }

  frame_filter_flags flags = 0;

  if (bt_opts.full)
    flags |= PRINT_LOCALS;
  if (bt_opts.hide)
    flags |= PRINT_HIDE;
  if (fp_opts.print_raw_frame_arguments)
    flags |= PRINT_RAW_FRAME_ARGUMENTS;

  if (!bt_opts.no_filters)
    {
      enum ext_lang_frame_args arg_type;

      flags |= PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS;
      if (from_tty)
	flags |= PRINT_MORE_FRAMES;

      if (fp_opts.print_frame_arguments == print_frame_arguments_scalars)
	arg_type = CLI_SCALAR_VALUES;
      else if (fp_opts.print_frame_arguments == print_frame_arguments_all)
	arg_type = CLI_ALL_VALUES;
      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,
					    py_start, py_end);
    }

  /* Run the inbuilt backtrace if there are no filters registered, or
     "-no-filters" has been specified from the command.  */
  if (bt_opts.no_filters || result == EXT_LANG_BT_NO_FILTERS)
    {
      frame_info_ptr trailing;

      /* The following code must do two things.  First, it must set the
	 variable TRAILING to the frame from which we should start
	 printing.  Second, it must set the variable count to the number
	 of frames which we should print, or -1 if all of them.  */

      if (count_exp != NULL && count < 0)
	{
	  trailing = trailing_outermost_frame (-count);
	  count = -1;
	}
      else
	trailing = get_current_frame ();

      for (fi = trailing; fi && count--; fi = get_prev_frame (fi))
	{
	  QUIT;

	  /* Don't use print_stack_frame; if an error() occurs it probably
	     means further attempts to backtrace would fail (on the other
	     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 (fp_opts, fi, 1, LOCATION, 1, 0);
	  if ((flags & PRINT_LOCALS) != 0)
	    print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout);

	  /* Save the last frame to check for error conditions.  */
	  trailing = fi;
	}

      /* If we've stopped before the end, mention that.  */
      if (fi && from_tty)
	gdb_printf (_("(More stack frames follow...)\n"));

      /* If we've run out of frames, and the reason appears to be an error
	 condition, print it.  */
      if (fi == NULL && trailing != NULL)
	{
	  enum unwind_stop_reason reason;

	  reason = get_frame_unwind_stop_reason (trailing);
	  if (reason >= UNWIND_FIRST_ERROR)
	    gdb_printf (_("Backtrace stopped: %s\n"),
			frame_stop_reason_string (trailing));
	}
    }
}

/* 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)
{
  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.  */

static const char *
parse_backtrace_qualifiers (const char *arg,
			    backtrace_cmd_options *bt_cmd_opts = nullptr)
{
  while (true)
    {
      const char *save_arg = arg;
      std::string this_arg = extract_arg (&arg);

      if (this_arg.empty ())
	return arg;

      if (startswith ("no-filters", this_arg))
	{
	  if (bt_cmd_opts != nullptr)
	    bt_cmd_opts->no_filters = true;
	}
      else if (startswith ("full", this_arg))
	{
	  if (bt_cmd_opts != nullptr)
	    bt_cmd_opts->full = true;
	}
      else if (startswith ("hide", this_arg))
	{
	  if (bt_cmd_opts != nullptr)
	    bt_cmd_opts->hide = true;
	}
      else
	{
	  /* Not a recognized qualifier, so stop.  */
	  return save_arg;
	}
    }
}

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;

  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;
    }

  /* 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.  */

static void
iterate_over_block_locals (const struct block *b,
			   iterate_over_block_arg_local_vars_cb cb)
{
  for (struct symbol *sym : block_iterator_range (b))
    {
      switch (sym->aclass ())
	{
	case LOC_CONST:
	case LOC_CONST_BYTES:
	case LOC_LOCAL:
	case LOC_REGISTER:
	case LOC_STATIC:
	case LOC_COMPUTED:
	case LOC_OPTIMIZED_OUT:
	  if (sym->is_argument ())
	    break;
	  if (sym->domain () == COMMON_BLOCK_DOMAIN)
	    break;
	  cb (sym->print_name (), sym);
	  break;

	default:
	  /* Ignore symbols which are not locals.  */
	  break;
	}
    }
}

/* Iterate over all the local variables in block B, including all its
   superblocks, stopping when the top-level block is reached.  */

void
iterate_over_block_local_vars (const struct block *block,
			       iterate_over_block_arg_local_vars_cb cb)
{
  while (block)
    {
      iterate_over_block_locals (block, cb);
      /* After handling the function's top-level block, stop.  Don't
	 continue to its superblock, the block of per-file
	 symbols.  */
      if (block->function ())
	break;
      block = block->superblock ();
    }
}

/* Data to be passed around in the calls to the locals and args
   iterators.  */

struct print_variable_and_value_data
{
  std::optional<compiled_regex> preg;
  std::optional<compiled_regex> treg;
  struct frame_id frame_id;
  int num_tabs;
  struct ui_file *stream;
  int values_printed;

  void operator() (const char *print_name, struct symbol *sym);
};

/* The callback for the locals and args iterators.  */

void
print_variable_and_value_data::operator() (const char *print_name,
					   struct symbol *sym)
{
  frame_info_ptr frame;

  if (preg.has_value ()
      && preg->exec (sym->natural_name (), 0, NULL, 0) != 0)
    return;
  if (treg.has_value ()
      && !treg_matches_sym_type_name (*treg, sym))
    return;
  if (language_def (sym->language ())->symbol_printing_suppressed (sym))
    return;

  frame = frame_find_by_id (frame_id);
  if (frame == NULL)
    {
      warning (_("Unable to restore previously selected frame."));
      return;
    }

  print_variable_and_value (print_name, sym, frame, stream, num_tabs);

  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, std::optional<compiled_regex> *reg)
{
  if (regexp != NULL)
    {
      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
				? REG_ICASE : 0);
      reg->emplace (regexp, cflags, _("Invalid regexp"));
    }
  else
    reg->reset ();
}

/* Print all variables from the innermost up to the function block of FRAME.
   Print them with values to STREAM indented by NUM_TABS.
   If REGEXP is not NULL, only print local variables whose name
   matches REGEXP.
   If T_REGEXP is not NULL, only print local variables whose type
   matches T_REGEXP.
   If no local variables have been printed and !QUIET, prints a message
   explaining why no local variables could be printed.  */

static void
print_frame_local_vars (const frame_info_ptr &frame,
			bool quiet,
			const char *regexp, const char *t_regexp,
			int num_tabs, struct ui_file *stream)
{
  struct print_variable_and_value_data cb_data;
  const struct block *block;
  CORE_ADDR pc;

  if (!get_frame_pc_if_available (frame, &pc))
    {
      if (!quiet)
	gdb_printf (stream,
		    _("PC unavailable, cannot determine locals.\n"));
      return;
    }

  block = get_frame_block (frame, 0);
  if (block == 0)
    {
      if (!quiet)
	gdb_printf (stream, "No symbol table info available.\n");
      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.values_printed = 0;

  /* Temporarily change the selected frame to the given FRAME.
     This allows routines that rely on the selected frame instead
     of being given a frame as parameter to use the correct frame.  */
  scoped_restore_selected_frame restore_selected_frame;
  select_frame (frame);

  iterate_over_block_local_vars (block, cb_data);

  if (!cb_data.values_printed && !quiet)
    {
      if (regexp == NULL && t_regexp == NULL)
	gdb_printf (stream, _("No locals.\n"));
      else
	gdb_printf (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;
  std::string 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;
  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.empty () ? nullptr : opts.type_regexp.c_str (),
     0, gdb_stdout);
}

/* Iterate over all the argument variables in block B.  */

void
iterate_over_block_arg_vars (const struct block *b,
			     iterate_over_block_arg_local_vars_cb cb)
{
  for (struct symbol *sym : block_iterator_range (b))
    {
      /* Don't worry about things which aren't arguments.  */
      if (sym->is_argument ())
	{
	  /* We have to look up the symbol because arguments can have
	     two entries (one a parameter, one a local) and the one we
	     want is the local, which lookup_symbol will find for us.
	     This includes gcc1 (not gcc2) on the sparc when passing a
	     small structure and gcc2 when the argument type is float
	     and it is passed as a double and converted to float by
	     the prologue (in the latter case the type of the LOC_ARG
	     symbol is double and the type of the LOC_LOCAL symbol is
	     float).  There are also LOC_ARG/LOC_REGISTER pairs which
	     are not combined in symbol-reading.  */

	  struct symbol *sym2
	    = lookup_symbol_search_name (sym->search_name (),
					 b, SEARCH_VAR_DOMAIN).symbol;
	  cb (sym->print_name (), sym2);
	}
    }
}

/* 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.  */

static void
print_frame_arg_vars (const frame_info_ptr &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;
  std::optional<compiled_regex> preg;
  std::optional<compiled_regex> treg;

  if (!get_frame_pc_if_available (frame, &pc))
    {
      if (!quiet)
	gdb_printf (stream,
		    _("PC unavailable, cannot determine args.\n"));
      return;
    }

  func = get_frame_function (frame);
  if (func == NULL)
    {
      if (!quiet)
	gdb_printf (stream, _("No symbol table info available.\n"));
      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.values_printed = 0;

  iterate_over_block_arg_vars (func->value_block (), cb_data);

  if (!cb_data.values_printed && !quiet)
    {
      if (regexp == NULL && t_regexp == NULL)
	gdb_printf (stream, _("No arguments.\n"));
      else
	gdb_printf (stream, _("No matching arguments.\n"));
    }
}

/* Implement the 'info args' command.  */

void
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.")),
     opts.quiet, args,
     opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
     gdb_stdout);
}

/* Return the symbol-block in which the selected frame is executing.
   Can return zero under various legitimate circumstances.

   If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the relevant
   code address within the block returned.  We use this to decide
   which macros are in scope.  */

const struct block *
get_selected_block (CORE_ADDR *addr_in_block)
{
  if (!has_stack_frames ())
    return 0;

  return get_frame_block (get_selected_frame (NULL), addr_in_block);
}

/* Find a frame a certain number of levels away from FRAME.
   LEVEL_OFFSET_PTR points to an int containing the number of levels.
   Positive means go to earlier frames (up); negative, the reverse.
   The int that contains the number of levels is counted toward
   zero as the frames for those levels are found.
   If the top or bottom frame is reached, that frame is returned,
   but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates
   how much farther the original request asked to go.  */

frame_info_ptr
find_relative_frame (frame_info_ptr frame, int *level_offset_ptr)
{
  /* Going up is simple: just call get_prev_frame enough times or
     until the initial frame is reached.  */
  while (*level_offset_ptr > 0)
    {
      frame_info_ptr prev = get_prev_frame (frame);

      if (!prev)
	break;
      (*level_offset_ptr)--;
      frame = prev;
    }

  /* Going down is just as simple.  */
  while (*level_offset_ptr < 0)
    {
      frame_info_ptr next = get_next_frame (frame);

      if (!next)
	break;
      (*level_offset_ptr)++;
      frame = next;
    }

  return frame;
}

/* Select the frame up one or COUNT_EXP stack levels from the
   previously selected frame, and print it briefly.  */

static void
up_silently_base (const char *count_exp)
{
  frame_info_ptr frame;
  int count = 1;

  if (count_exp)
    count = parse_and_eval_long (count_exp);

  frame = find_relative_frame (get_selected_frame ("No stack."), &count);
  if (count != 0 && count_exp == NULL)
    error (_("Initial frame selected; you cannot go up."));
  select_frame (frame);
}

static void
up_silently_command (const char *count_exp, int from_tty)
{
  up_silently_base (count_exp);
}

static void
up_command (const char *count_exp, int from_tty)
{
  up_silently_base (count_exp);
  notify_user_selected_context_changed (USER_SELECTED_FRAME);
}

/* Select the frame down one or COUNT_EXP stack levels from the previously
   selected frame, and print it briefly.  */

static void
down_silently_base (const char *count_exp)
{
  frame_info_ptr frame;
  int count = -1;

  if (count_exp)
    count = -parse_and_eval_long (count_exp);

  frame = find_relative_frame (get_selected_frame ("No stack."), &count);
  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.  */

      error (_("Bottom (innermost) frame selected; you cannot go down."));
    }

  select_frame (frame);
}

static void
down_silently_command (const char *count_exp, int from_tty)
{
  down_silently_base (count_exp);
}

static void
down_command (const char *count_exp, int from_tty)
{
  down_silently_base (count_exp);
  notify_user_selected_context_changed (USER_SELECTED_FRAME);
}

void
return_command (const char *retval_exp, int from_tty)
{
  /* Initialize it just to avoid a GCC false warning.  */
  enum return_value_convention rv_conv = RETURN_VALUE_STRUCT_CONVENTION;
  frame_info_ptr thisframe;
  struct gdbarch *gdbarch;
  struct symbol *thisfun;
  struct value *return_value = NULL;
  struct value *function = NULL;
  std::string query_prefix;

  thisframe = get_selected_frame ("No selected frame.");
  thisfun = get_frame_function (thisframe);
  gdbarch = get_frame_arch (thisframe);

  if (get_frame_type (thisframe) == INLINE_FRAME)
    error (_("Can not force return from an inlined function."));

  /* Compute the return value.  If the computation triggers an error,
     let it bail.  If the return type can't be handled, set
     RETURN_VALUE to NULL, and QUERY_PREFIX to an informational
     message.  */
  if (retval_exp)
    {
      expression_up retval_expr = parse_expression (retval_exp);
      struct type *return_type = NULL;

      /* Compute the return value.  Should the computation fail, this
	 call throws an error.  */
      return_value = retval_expr->evaluate ();

      /* Cast return value to the return type of the function.  Should
	 the cast fail, this call throws an error.  */
      if (thisfun != NULL)
	return_type = thisfun->type ()->target_type ();
      if (return_type == NULL)
	{
	  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."));
	  return_type = return_value->type ();
	}
      return_type = check_typedef (return_type);
      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.  */
      if (return_value->lazy ())
	return_value->fetch_lazy ();

      if (thisfun != NULL)
	function = read_var_value (thisfun, NULL, thisframe);

      rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
      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 = NULL;
      else if (thisfun != NULL)
	{
	  if (is_nocall_function (check_typedef (function->type ())))
	    {
	      query_prefix =
		string_printf ("Function '%s' does not follow the target "
			       "calling convention.\n"
			       "If you continue, setting the return value "
			       "will probably lead to unpredictable "
			       "behaviors.\n",
			       thisfun->print_name ());
	    }

	  rv_conv = struct_return_convention (gdbarch, function, return_type);
	  if (rv_conv == RETURN_VALUE_STRUCT_CONVENTION
	      || rv_conv == RETURN_VALUE_ABI_RETURNS_ADDRESS)
	    {
	      query_prefix = "The location at which to store the "
		"function's return value is unknown.\n"
		"If you continue, the return value "
		"that you specified will be ignored.\n";
	      return_value = NULL;
	    }
	}
    }

  /* Does an interactive user really want to do this?  Include
     information, such as how well GDB can handle the return value, in
     the query message.  */
  if (from_tty)
    {
      int confirmed;

      if (get_frame_type (thisframe) == SIGTRAMP_FRAME)
	{
	  warning (_("Returning from signal trampoline does not fully restore"
		     " pre-signal state, such as process signal mask."));
	  confirmed = query (_("%sMake signal trampoline return now? "),
			     query_prefix.c_str ());
	}
      else if (thisfun == NULL)
	confirmed = query (_("%sMake selected stack frame return now? "),
			   query_prefix.c_str ());
      else
	{
	  if (TYPE_NO_RETURN (thisfun->type ()))
	    warning (_("Function does not return normally to caller."));
	  confirmed = query (_("%sMake %s return now? "),
			     query_prefix.c_str (),
			     thisfun->print_name ());
	}
      if (!confirmed)
	error (_("Not confirmed"));
    }

  /* Discard the selected frame and all frames inner-to it.  */
  frame_pop (get_selected_frame (NULL));

  /* Store RETURN_VALUE in the just-returned register set.  */
  if (return_value != NULL)
    {
      struct type *return_type = return_value->type ();
      regcache *regcache = get_thread_regcache (inferior_thread ());
      struct gdbarch *cache_arch = regcache->arch ();

      gdb_assert (rv_conv != RETURN_VALUE_STRUCT_CONVENTION
		  && rv_conv != RETURN_VALUE_ABI_RETURNS_ADDRESS);
      gdbarch_return_value_as_value
	(cache_arch, function, return_type, regcache, NULL /*read*/,
	 return_value->contents ().data () /*write*/);
    }

  /* If we are at the end of a call dummy now, pop the dummy frame
     too.  */
  if (get_frame_type (get_current_frame ()) == DUMMY_FRAME)
    frame_pop (get_current_frame ());

  select_frame (get_current_frame ());
  /* If interactive, print the frame that is now current.  */
  if (from_tty)
    print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}

/* Find the most inner frame in the current stack for a function called
   FUNCTION_NAME.  If no matching frame is found return NULL.  */

static frame_info_ptr
find_frame_for_function (const char *function_name)
{
  /* Used to hold the lower and upper addresses for each of the
     SYMTAB_AND_LINEs found for functions matching FUNCTION_NAME.  */
  struct function_bounds
  {
    CORE_ADDR low, high;
  };
  frame_info_ptr frame;
  bool found = false;
  int level = 1;

  gdb_assert (function_name != NULL);

  frame = get_current_frame ();
  std::vector<symtab_and_line> sals
    = decode_line_with_current_source (function_name,
				       DECODE_LINE_FUNFIRSTLINE);
  gdb::def_vector<function_bounds> func_bounds (sals.size ());
  for (size_t i = 0; i < sals.size (); i++)
    {
      if (sals[i].pspace != current_program_space)
	func_bounds[i].low = func_bounds[i].high = 0;
      else if (sals[i].pc == 0
	       || find_pc_partial_function (sals[i].pc, NULL,
					    &func_bounds[i].low,
					    &func_bounds[i].high) == 0)
	func_bounds[i].low = func_bounds[i].high = 0;
    }

  do
    {
      CORE_ADDR frame_pc = get_frame_address_in_block (frame);

      for (size_t i = 0; (i < sals.size () && !found); i++)
	found = (frame_pc >= func_bounds[i].low
		 && frame_pc < func_bounds[i].high);
      if (!found)
	{
	  level = 1;
	  frame = find_relative_frame (frame, &level);
	}
    }
  while (!found && level == 0);

  if (!found)
    frame = NULL;

  return frame;
}

/* 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.

   frame apply 3 info frame     Apply 'info frame' to frames 0, 1, 2
   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.
   frame apply all -s -q p local_var_no_idea_in_which_frame
		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.  */

/* 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.
   COUNT -1 means all frames starting at TRAILING.  WHICH_COMMAND is used
   for error messages.  */

static void
frame_apply_command_count (const char *which_command,
			   const char *cmd, int from_tty,
			   frame_info_ptr trailing, int count)
{
  qcs_flags flags;
  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);

  validate_flags_qcs (which_command, &flags);

  if (cmd == NULL || *cmd == '\0')
    error (_("Please specify a command to apply on the selected frames"));

  /* The below will restore the current inferior/thread/frame.
     Usually, only the frame is effectively to be restored.
     But in case CMD switches of inferior/thread, better restore
     these also.  */
  scoped_restore_current_thread restore_thread;

  /* 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_ptr fi = trailing; fi && count--; fi = get_prev_frame (fi))
    {
      QUIT;

      select_frame (fi);
      try
	{
	  std::string cmd_result;
	  {
	    /* In case CMD switches of inferior/thread/frame, the below
	       restores the inferior/thread/frame.  FI can then be
	       set to the selected frame.  */
	    scoped_restore_current_thread restore_fi_current_frame;

	    execute_command_to_string
	      (cmd_result, cmd, from_tty, gdb_stdout->term_out ());
	  }
	  fi = get_selected_frame (_("frame apply "
				     "unable to get selected frame."));
	  if (!flags.silent || cmd_result.length () > 0)
	    {
	      if (!flags.quiet)
		print_stack_frame (fi, 1, LOCATION, 0);
	      gdb_printf ("%s", cmd_result.c_str ());
	    }
	}
      catch (const gdb_exception_error &ex)
	{
	  fi = get_selected_frame (_("frame apply "
				     "unable to get selected frame."));
	  if (!flags.silent)
	    {
	      if (!flags.quiet)
		print_stack_frame (fi, 1, LOCATION, 0);
	      if (flags.cont)
		gdb_printf ("%s\n", ex.what ());
	      else
		throw;
	    }
	}
    }
}

/* 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
frame_apply_level_command (const char *cmd, int from_tty)
{
  if (!target_has_stack ())
    error (_("No stack."));

  bool level_found = false;
  const char *levels_str = cmd;
  number_or_range_parser levels (levels_str);

  /* Skip the LEVEL list to find the flags and command args.  */
  while (!levels.finished ())
    {
      /* Call for effect.  */
      levels.get_number ();

      level_found = true;
      if (levels.in_range ())
	levels.skip_range ();
    }

  if (!level_found)
    error (_("Missing or invalid LEVEL... argument"));

  cmd = levels.cur_tok ();

  /* Redo the LEVELS parsing, but applying COMMAND.  */
  levels.init (levels_str);
  while (!levels.finished ())
    {
      const int level_beg = levels.get_number ();
      int n_frames;

      if (levels.in_range ())
	{
	  n_frames = levels.end_value () - level_beg + 1;
	  levels.skip_range ();
	}
      else
	n_frames = 1;

      frame_apply_command_count ("frame apply level", cmd, from_tty,
				 leading_innermost_frame (level_beg), n_frames);
    }
}

/* Implementation of the "frame apply all" command.  */

static void
frame_apply_all_command (const char *cmd, int from_tty)
{
  if (!target_has_stack ())
    error (_("No stack."));

  frame_apply_command_count ("frame apply all", cmd, from_tty,
			     get_current_frame (), INT_MAX);
}

/* Implementation of the "frame apply" command.  */

static void
frame_apply_command (const char* cmd, int from_tty)
{
  int count;
  frame_info_ptr trailing;

  if (!target_has_stack ())
    error (_("No stack."));

  if (cmd == NULL)
    error (_("Missing COUNT argument."));
  count = get_number_trailer (&cmd, 0);
  if (count == 0)
    error (_("Invalid COUNT argument."));

  if (count < 0)
    {
      trailing = trailing_outermost_frame (-count);
      count = -1;
    }
  else
    trailing = get_current_frame ();

  frame_apply_command_count ("frame apply", cmd, from_tty,
			     trailing, count);
}

/* Implementation of the "faas" command.  */

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);
}


/* Find inner-mode frame with frame address ADDRESS.  Return NULL if no
   matching frame can be found.  */

static frame_info_ptr
find_frame_for_address (CORE_ADDR address)
{
  struct frame_id id;
  frame_info_ptr fid;

  id = frame_id_build_wild (address);

  /* If (s)he specifies the frame with an address, he deserves
     what (s)he gets.  Still, give the highest one that matches.
     (NOTE: cagney/2004-10-29: Why highest, or outer-most, I don't
     know).  */
  for (fid = get_current_frame ();
       fid != NULL;
       fid = get_prev_frame (fid))
    {
      if (id == get_frame_id (fid))
	{
	  frame_info_ptr prev_frame;

	  while (1)
	    {
	      prev_frame = get_prev_frame (fid);
	      if (!prev_frame
		  || id != get_frame_id (prev_frame))
		break;
	      fid = prev_frame;
	    }
	  return fid;
	}
    }
  return NULL;
}



/* Commands with a prefix of `frame apply'.  */
static struct cmd_list_element *frame_apply_cmd_list = NULL;

/* Commands with a prefix of `frame'.  */
static struct cmd_list_element *frame_cmd_list = NULL;

/* Commands with a prefix of `select frame'.  */
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;

INIT_GDB_FILE (stack)
{
  struct cmd_list_element *cmd;

  add_com ("return", class_stack, return_command, _("\
Make selected stack frame return to its caller.\n\
Control remains in the debugger, but when you continue\n\
execution will resume in the frame above the one now selected.\n\
If an argument is given, it is an expression for the value to return."));

  add_com ("up", class_stack, up_command, _("\
Select and print stack frame that called this one.\n\
An argument says how many frames up to go."));
  add_com ("up-silently", class_support, up_silently_command, _("\
Same as the `up' command, but does not print anything.\n\
This is useful in command scripts."));

  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_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."));

  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, 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\
\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"
				  FRAME_APPLY_OPTION_HELP),
			       frame_apply_opts);

  cmd = add_prefix_cmd ("apply", class_stack, frame_apply_command,
			frame_apply_cmd_help.c_str (),
			&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 (_("\
Apply a command to all frames.\n\
\n\
Usage: frame apply all [OPTION]... COMMAND\n"
				  FRAME_APPLY_OPTION_HELP),
			       frame_apply_opts);

  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\
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);
  set_cmd_completer_handle_brkchars (cmd, frame_apply_level_cmd_completer);

  cmd = add_com ("faas", class_stack, faas_command, _("\
Apply a command to all frames (ignoring errors and empty output).\n\
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,
	   _("\
Select and print a stack frame by stack address.\n\
\n\
Usage: frame address STACK-ADDRESS"),
	   &frame_cmd_list);

  add_cmd ("view", class_stack, &frame_cmd.view,
	   _("\
View a stack frame that might be outside the current backtrace.\n\
\n\
Usage: frame view STACK-ADDRESS\n\
       frame view STACK-ADDRESS PC-ADDRESS"),
	   &frame_cmd_list);

  cmd = add_cmd ("function", class_stack, &frame_cmd.function,
	   _("\
Select and print a stack frame by function name.\n\
\n\
Usage: frame function NAME\n\
\n\
The innermost frame that visited function NAME is selected."),
	   &frame_cmd_list);
  set_cmd_completer (cmd, frame_selection_by_function_completer);


  add_cmd ("level", class_stack, &frame_cmd.level,
	   _("\
Select and print a stack frame by level.\n\
\n\
Usage: frame level LEVEL"),
	   &frame_cmd_list);

  cmd = add_prefix_cmd_suppress_notification ("select-frame", class_stack,
		      &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, 1, &cmdlist,
		      &cli_suppress_notification.user_selected_context);

  add_cmd_suppress_notification ("address", class_stack,
			 &select_frame_cmd.address, _("\
Select a stack frame by stack address.\n\
\n\
Usage: select-frame address STACK-ADDRESS"),
			 &select_frame_cmd_list,
			 &cli_suppress_notification.user_selected_context);


  add_cmd_suppress_notification ("view", class_stack,
		 &select_frame_cmd.view, _("\
Select a stack frame that might be outside the current backtrace.\n\
\n\
Usage: select-frame view STACK-ADDRESS\n\
       select-frame view STACK-ADDRESS PC-ADDRESS"),
		 &select_frame_cmd_list,
		 &cli_suppress_notification.user_selected_context);

  cmd = add_cmd_suppress_notification ("function", class_stack,
	       &select_frame_cmd.function, _("\
Select a stack frame by function name.\n\
\n\
Usage: select-frame function NAME"),
	       &select_frame_cmd_list,
	       &cli_suppress_notification.user_selected_context);
  set_cmd_completer (cmd, frame_selection_by_function_completer);

  add_cmd_suppress_notification ("level", class_stack,
			 &select_frame_cmd.level, _("\
Select a stack frame by level.\n\
\n\
Usage: select-frame level LEVEL"),
			 &select_frame_cmd_list,
			 &cli_suppress_notification.user_selected_context);

  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\
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 *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_cmd, class_stack, 0);

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

  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, 1, &infolist);
  add_info_alias ("f", info_frame_cmd_el, 1);

  add_cmd ("address", class_stack, &info_frame_cmd.address,
	   _("\
Print information about a stack frame selected by stack address.\n\
\n\
Usage: info frame address STACK-ADDRESS"),
	   &info_frame_cmd_list);

  add_cmd ("view", class_stack, &info_frame_cmd.view,
	   _("\
Print information about a stack frame outside the current backtrace.\n\
\n\
Usage: info frame view STACK-ADDRESS\n\
       info frame view STACK-ADDRESS PC-ADDRESS"),
	   &info_frame_cmd_list);

  cmd = add_cmd ("function", class_stack, &info_frame_cmd.function,
	   _("\
Print information about a stack frame selected by function name.\n\
\n\
Usage: info frame function NAME"),
	   &info_frame_cmd_list);
  set_cmd_completer (cmd, frame_selection_by_function_completer);

  add_cmd ("level", class_stack, &info_frame_cmd.level,
	   _("\
Print information about a stack frame selected by level.\n\
\n\
Usage: info frame level LEVEL"),
	   &info_frame_cmd_list);

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

  /* Install "set print raw frame-arguments", a deprecated spelling of
     "set 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 (set_show_frame_args.set, "set print raw-frame-arguments");

  add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
				&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."),
				_("\
If ON, GDB will display disassembly of the next source line, in addition\n\
to displaying the source line itself.  If the next source line cannot\n\
be displayed (e.g., source is unavailable or there's no line info), GDB\n\
will display disassembly of next instruction instead of showing the\n\
source line.\n\
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);
  disassemble_next_line = AUTO_BOOLEAN_FALSE;

  gdb::option::add_setshow_cmds_for_options
    (class_stack, &user_frame_print_options,
     frame_print_option_defs, &setprintlist, &showprintlist);
}
