2005-02-14 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / stack.c
index ebf439e50e6bcd5e109e1e0ec373c95ee3d6159c..54af2b9480a2e7999218134ec68c953497fa0619 100644 (file)
@@ -1,8 +1,8 @@
 /* Print and select stack frames for GDB, the GNU debugger.
 
    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
 /* Print and select stack frames for GDB, the GNU debugger.
 
    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
-   Foundation, Inc.
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -43,7 +43,9 @@
 #include "stack.h"
 #include "gdb_assert.h"
 #include "dictionary.h"
 #include "stack.h"
 #include "gdb_assert.h"
 #include "dictionary.h"
+#include "exceptions.h"
 #include "reggroups.h"
 #include "reggroups.h"
+#include "regcache.h"
 
 /* Prototypes for exported functions. */
 
 
 /* Prototypes for exported functions. */
 
@@ -51,12 +53,10 @@ void args_info (char *, int);
 
 void locals_info (char *, int);
 
 
 void locals_info (char *, int);
 
-void (*selected_frame_level_changed_hook) (int);
+void (*deprecated_selected_frame_level_changed_hook) (int);
 
 void _initialize_stack (void);
 
 
 void _initialize_stack (void);
 
-void return_command (char *, int);
-
 /* Prototypes for local functions. */
 
 static void down_command (char *, int);
 /* Prototypes for local functions. */
 
 static void down_command (char *, int);
@@ -96,14 +96,14 @@ static int print_block_frame_locals (struct block *,
                                     struct ui_file *);
 
 static void print_frame (struct frame_info *fi, 
                                     struct ui_file *);
 
 static void print_frame (struct frame_info *fi, 
-                        int level, 
-                        int source
-                        int args, 
+                        int print_level, 
+                        enum print_what print_what
+                        int print_args, 
                         struct symtab_and_line sal);
 
                         struct symtab_and_line sal);
 
-static void backtrace_command (char *, int);
+static void set_current_sal_from_frame (struct frame_info *, int);
 
 
-struct frame_info *parse_frame_specification (char *);
+static void backtrace_command (char *, int);
 
 static void frame_info (char *, int);
 
 
 static void frame_info (char *, int);
 
@@ -121,42 +121,41 @@ int annotation_level = 0;
 struct print_stack_frame_args
   {
     struct frame_info *fi;
 struct print_stack_frame_args
   {
     struct frame_info *fi;
-    int level;
-    int source;
-    int args;
+    int print_level;
+    enum print_what print_what;
+    int print_args;
   };
 
 /* Show or print the frame arguments.
    Pass the args the way catch_errors wants them.  */
   };
 
 /* Show or print the frame arguments.
    Pass the args the way catch_errors wants them.  */
-static int print_stack_frame_stub (void *args);
 static int
 print_stack_frame_stub (void *args)
 {
 static int
 print_stack_frame_stub (void *args)
 {
-  struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
+  struct print_stack_frame_args *p = args;
+  int center = (p->print_what == SRC_LINE
+                || p->print_what == SRC_AND_LOC);
 
 
-  print_frame_info (p->fi, p->level, p->source, p->args);
+  print_frame_info (p->fi, p->print_level, p->print_what, p->print_args);
+  set_current_sal_from_frame (p->fi, center);
   return 0;
 }
 
   return 0;
 }
 
-/* Show or print a stack frame briefly.  FRAME_INFI should be the frame info
-   and LEVEL should be its level in the stack (or -1 for level not defined).
-   This prints the level, the function executing, the arguments,
-   and the file name and line number.
-   If the pc is not at the beginning of the source line,
-   the actual pc is printed at the beginning.
-
-   If SOURCE is 1, print the source line as well.
-   If SOURCE is -1, print ONLY the source line.  */
+/* Show or print a stack frame FI briefly.  The output is format
+   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
 
 void
-print_stack_frame (struct frame_info *fi, int level, int source)
+print_stack_frame (struct frame_info *fi, int print_level,
+                  enum print_what print_what)
 {
   struct print_stack_frame_args args;
 
   args.fi = fi;
 {
   struct print_stack_frame_args args;
 
   args.fi = fi;
-  args.level = level;
-  args.source = source;
-  args.args = 1;
+  args.print_level = print_level;
+  args.print_what = print_what;
+  args.print_args = 1;
 
   catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL);
 }  
 
   catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL);
 }  
@@ -351,11 +350,11 @@ print_frame_args (struct symbol *func, struct frame_info *fi, int num,
             2 for each recurse.  */
          val = read_var_value (sym, fi);
 
             2 for each recurse.  */
          val = read_var_value (sym, fi);
 
-         annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val));
+         annotate_arg_value (val == NULL ? NULL : value_type (val));
 
          if (val)
            {
 
          if (val)
            {
-             val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+             val_print (value_type (val), value_contents (val), 0,
                         VALUE_ADDRESS (val),
                         stb->stream, 0, 0, 2, Val_no_prettyprint);
              ui_out_field_stream (uiout, "value", stb);
                         VALUE_ADDRESS (val),
                         stb->stream, 0, 0, 2, Val_no_prettyprint);
              ui_out_field_stream (uiout, "value", stb);
@@ -408,6 +407,24 @@ print_args_stub (void *args)
   return 0;
 }
 
   return 0;
 }
 
+/* Set the current source and line to the location of the given
+   frame, if possible.  When CENTER is true, adjust so the
+   relevant line is in the center of the next 'list'. */
+
+static void
+set_current_sal_from_frame (struct frame_info *fi, int center)
+{
+  struct symtab_and_line sal;
+
+  find_frame_sal (fi, &sal);
+  if (sal.symtab)
+    {
+      if (center)
+        sal.line = max (sal.line - get_lines_to_list () / 2, 1);
+      set_current_source_symtab_and_line (&sal);
+    }
+}
+
 /* Print information about a frame for frame "fi" at level "level".
    Used in "where" output, also used to emit breakpoint or step
    messages.  
 /* Print information about a frame for frame "fi" at level "level".
    Used in "where" output, also used to emit breakpoint or step
    messages.  
@@ -419,7 +436,8 @@ print_args_stub (void *args)
    LOC_AND_SRC: Print location and source line.  */
 
 void
    LOC_AND_SRC: Print location and source line.  */
 
 void
-print_frame_info (struct frame_info *fi, int level, int source, int args)
+print_frame_info (struct frame_info *fi, int print_level,
+                 enum print_what print_what, int print_args)
 {
   struct symtab_and_line sal;
   int source_print;
 {
   struct symtab_and_line sal;
   int source_print;
@@ -431,14 +449,16 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
       struct cleanup *uiout_cleanup
        = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
       struct cleanup *uiout_cleanup
        = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
-      annotate_frame_begin (level == -1 ? 0 : level, get_frame_pc (fi));
+      annotate_frame_begin (print_level ? frame_relative_level (fi) : 0,
+                           get_frame_pc (fi));
 
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
 
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
-      if (level >= 0)
+      if (print_level)
         {
           ui_out_text (uiout, "#");
         {
           ui_out_text (uiout, "#");
-          ui_out_field_fmt_int (uiout, 2, ui_left, "level", level);
+          ui_out_field_fmt_int (uiout, 2, ui_left, "level",
+                               frame_relative_level (fi));
         }
       if (ui_out_is_mi_like_p (uiout))
         {
         }
       if (ui_out_is_mi_like_p (uiout))
         {
@@ -472,31 +492,30 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
      line containing fi->pc.  */
   find_frame_sal (fi, &sal);
 
      line containing fi->pc.  */
   find_frame_sal (fi, &sal);
 
-  location_print = (source == LOCATION 
-                   || source == LOC_AND_ADDRESS
-                   || source == SRC_AND_LOC);
+  location_print = (print_what == LOCATION 
+                   || print_what == LOC_AND_ADDRESS
+                   || print_what == SRC_AND_LOC);
 
   if (location_print || !sal.symtab)
 
   if (location_print || !sal.symtab)
-    print_frame (fi, level, source, args, sal);
+    print_frame (fi, print_level, print_what, print_args, sal);
 
 
-  source_print = (source == SRC_LINE || source == SRC_AND_LOC);
-
-  if (sal.symtab)
-    set_current_source_symtab_and_line (&sal);
+  source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
 
   if (source_print && sal.symtab)
     {
 
   if (source_print && sal.symtab)
     {
-      struct symtab_and_line cursal;
       int done = 0;
       int done = 0;
-      int mid_statement = (source == SRC_LINE) && (get_frame_pc (fi) != sal.pc);
+      int mid_statement = ((print_what == SRC_LINE)
+                          && (get_frame_pc (fi) != sal.pc));
 
       if (annotation_level)
        done = identify_source_line (sal.symtab, sal.line, mid_statement,
                                     get_frame_pc (fi));
       if (!done)
        {
 
       if (annotation_level)
        done = identify_source_line (sal.symtab, sal.line, mid_statement,
                                     get_frame_pc (fi));
       if (!done)
        {
-         if (print_frame_info_listing_hook)
-           print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
+         if (deprecated_print_frame_info_listing_hook)
+           deprecated_print_frame_info_listing_hook (sal.symtab, 
+                                                     sal.line, 
+                                                     sal.line + 1, 0);
          else
            {
              /* We used to do this earlier, but that is clearly
          else
            {
              /* We used to do this earlier, but that is clearly
@@ -506,7 +525,7 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
                 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
                 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. */
+                ability to decide for themselves if it is desired.  */
              if (addressprint && mid_statement)
                {
                  ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi));
              if (addressprint && mid_statement)
                {
                  ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi));
@@ -516,14 +535,9 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
              print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
            }
        }
              print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
            }
        }
-      /* Make sure we have at least a default source file */
-      set_default_source_symtab_and_line ();
-      cursal = get_current_source_symtab_and_line ();
-      cursal.line = max (sal.line - get_lines_to_list () / 2, 1);
-      set_current_source_symtab_and_line (&cursal);
     }
 
     }
 
-  if (source != 0)
+  if (print_what != LOCATION)
     set_default_breakpoint (1, get_frame_pc (fi), sal.symtab, sal.line);
 
   annotate_frame_end ();
     set_default_breakpoint (1, get_frame_pc (fi), sal.symtab, sal.line);
 
   annotate_frame_end ();
@@ -533,9 +547,9 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
 
 static void
 print_frame (struct frame_info *fi, 
 
 static void
 print_frame (struct frame_info *fi, 
-            int level, 
-            int source
-            int args, 
+            int print_level, 
+            enum print_what print_what
+            int print_args, 
             struct symtab_and_line sal)
 {
   struct symbol *func;
             struct symtab_and_line sal)
 {
   struct symbol *func;
@@ -572,14 +586,6 @@ print_frame (struct frame_info *fi,
          && (SYMBOL_VALUE_ADDRESS (msymbol)
              > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
        {
          && (SYMBOL_VALUE_ADDRESS (msymbol)
              > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
        {
-#if 0
-         /* There is no particular reason to think the line number
-            information is wrong.  Someone might have just put in
-            a label with asm() but left the line numbers alone.  */
-         /* In this case we have no way of knowing the source file
-            and line number, so don't print them.  */
-         sal.symtab = 0;
-#endif
          /* We also don't know anything about the function besides
             its address and name.  */
          func = 0;
          /* We also don't know anything about the function besides
             its address and name.  */
          func = 0;
@@ -623,19 +629,21 @@ print_frame (struct frame_info *fi,
        }
     }
 
        }
     }
 
-  annotate_frame_begin (level == -1 ? 0 : level, get_frame_pc (fi));
+  annotate_frame_begin (print_level ? frame_relative_level (fi) : 0,
+                       get_frame_pc (fi));
 
   list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
 
   list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
-  if (level >= 0)
+  if (print_level)
     {
       ui_out_text (uiout, "#");
     {
       ui_out_text (uiout, "#");
-      ui_out_field_fmt_int (uiout, 2, ui_left, "level", level);
+      ui_out_field_fmt_int (uiout, 2, ui_left, "level",
+                           frame_relative_level (fi));
     }
   if (addressprint)
     if (get_frame_pc (fi) != sal.pc
        || !sal.symtab
     }
   if (addressprint)
     if (get_frame_pc (fi) != sal.pc
        || !sal.symtab
-       || source == LOC_AND_ADDRESS)
+       || print_what == LOC_AND_ADDRESS)
       {
        annotate_frame_address ();
        ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi));
       {
        annotate_frame_address ();
        ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi));
@@ -650,7 +658,7 @@ print_frame (struct frame_info *fi,
   annotate_frame_args ();
       
   ui_out_text (uiout, " (");
   annotate_frame_args ();
       
   ui_out_text (uiout, " (");
-  if (args)
+  if (print_args)
     {
       struct print_args_args args;
       struct cleanup *args_list_chain;
     {
       struct print_args_args args;
       struct cleanup *args_list_chain;
@@ -709,122 +717,146 @@ show_stack_frame (struct frame_info *fi)
 \f
 
 /* Read a frame specification in whatever the appropriate format is.
 \f
 
 /* Read a frame specification in whatever the appropriate format is.
-   Call error() if the specification is in any way invalid (i.e.
-   this function never returns NULL).  */
+   Call error() if the specification is in any way invalid (i.e.  this
+   function never returns NULL).  When SEPECTED_P is non-NULL set it's
+   target to indicate that the default selected frame was used.  */
 
 
-struct frame_info *
-parse_frame_specification (char *frame_exp)
+static struct frame_info *
+parse_frame_specification_1 (const char *frame_exp, const char *message,
+                            int *selected_frame_p)
 {
 {
-  int numargs = 0;
-#define        MAXARGS 4
-  CORE_ADDR args[MAXARGS];
-  int level;
+  int numargs;
+  struct value *args[4];
+  CORE_ADDR addrs[ARRAY_SIZE (args)];
 
 
-  if (frame_exp)
+  if (frame_exp == NULL)
+    numargs = 0;
+  else
     {
     {
-      char *addr_string, *p;
+      char *addr_string;
       struct cleanup *tmp_cleanup;
 
       struct cleanup *tmp_cleanup;
 
-      while (*frame_exp == ' ')
-       frame_exp++;
-
-      while (*frame_exp)
+      numargs = 0;
+      while (1)
        {
        {
-         if (numargs > MAXARGS)
-           error ("Too many args in frame specification");
-         /* Parse an argument.  */
-         for (p = frame_exp; *p && *p != ' '; p++)
-           ;
-         addr_string = savestring (frame_exp, p - frame_exp);
-
-         {
-           struct value *vp;
-
-           tmp_cleanup = make_cleanup (xfree, addr_string);
-
-           /* NOTE: we call parse_and_eval and then both
-              value_as_long and value_as_address rather than calling
-              parse_and_eval_long and parse_and_eval_address because
-              of the issue of potential side effects from evaluating
-              the expression.  */
-           vp = parse_and_eval (addr_string);
-           if (numargs == 0)
-             level = value_as_long (vp);
-
-           args[numargs++] = value_as_address (vp);
-           do_cleanups (tmp_cleanup);
-         }
+         char *addr_string;
+         struct cleanup *cleanup;
+         const char *p;
+
+         /* Skip leading white space, bail of EOL.  */
+         while (isspace (*frame_exp))
+           frame_exp++;
+         if (!*frame_exp)
+           break;
 
 
-         /* Skip spaces, move to possible next arg.  */
-         while (*p == ' ')
-           p++;
+         /* Parse the argument, extract it, save it.  */
+         for (p = frame_exp;
+              *p && !isspace (*p);
+              p++);
+         addr_string = savestring (frame_exp, p - frame_exp);
          frame_exp = p;
          frame_exp = p;
+         cleanup = make_cleanup (xfree, addr_string);
+         
+         /* NOTE: Parse and evaluate expression, but do not use
+            functions such as parse_and_eval_long or
+            parse_and_eval_address to also extract the value.
+            Instead value_as_long and value_as_address are used.
+            This avoids problems with expressions that contain
+            side-effects.  */
+         if (numargs >= ARRAY_SIZE (args))
+           error (_("Too many args in frame specification"));
+         args[numargs++] = parse_and_eval (addr_string);
+
+         do_cleanups (cleanup);
        }
     }
 
        }
     }
 
-  switch (numargs)
+  /* If no args, default to the selected frame.  */
+  if (numargs == 0)
     {
     {
-    case 0:
-      if (deprecated_selected_frame == NULL)
-       error ("No selected frame.");
-      return deprecated_selected_frame;
-      /* NOTREACHED */
-    case 1:
-      {
-       struct frame_info *fid =
-       find_relative_frame (get_current_frame (), &level);
-       struct frame_info *tfid;
-
-       if (level == 0)
-         /* find_relative_frame was successful */
-         return fid;
-
-       /* If SETUP_ARBITRARY_FRAME is defined, then frame specifications
-          take at least 2 addresses.  It is important to detect this case
-          here so that "frame 100" does not give a confusing error message
-          like "frame specification requires two addresses".  This of course
-          does not solve the "frame 100" problem for machines on which
-          a frame specification can be made with one address.  To solve
-          that, we need a new syntax for a specifying a frame by address.
-          I think the cleanest syntax is $frame(0x45) ($frame(0x23,0x45) for
-          two args, etc.), but people might think that is too much typing,
-          so I guess *0x23,0x45 would be a possible alternative (commas
-          really should be used instead of spaces to delimit; using spaces
-          normally works in an expression).  */
-#ifdef SETUP_ARBITRARY_FRAME
-       error ("No frame %s", paddr_d (args[0]));
-#endif
-
-       /* If (s)he specifies the frame with an address, he deserves what
-          (s)he gets.  Still, give the highest one that matches.  */
+      if (selected_frame_p != NULL)
+       (*selected_frame_p) = 1;
+      return get_selected_frame (message);
+    }
 
 
-       for (fid = get_current_frame ();
-            fid && get_frame_base (fid) != args[0];
-            fid = get_prev_frame (fid))
-         ;
+  /* None of the remaining use the selected frame.  */
+  if (selected_frame_p != NULL)
+    (*selected_frame_p) = 0;
 
 
-       if (fid)
-         while ((tfid = get_prev_frame (fid)) &&
-                (get_frame_base (tfid) == args[0]))
-           fid = tfid;
+  /* Assume the single arg[0] is an integer, and try using that to
+     select a frame relative to current.  */
+  if (numargs == 1)
+    {
+      struct frame_info *fid;
+      int level = value_as_long (args[0]);
+      fid = find_relative_frame (get_current_frame (), &level);
+      if (level == 0)
+       /* find_relative_frame was successful */
+       return fid;
+    }
 
 
-       /* We couldn't identify the frame as an existing frame, but
-          perhaps we can create one with a single argument.  */
-      }
+  /* Convert each value into a corresponding address.  */
+  {
+    int i;
+    for (i = 0; i < numargs; i++)
+      addrs[i] = value_as_address (args[0]);
+  }
 
 
-    default:
+  /* Assume that the single arg[0] is an address, use that to identify
+     a frame with a matching ID.  Should this also accept stack/pc or
+     stack/pc/special.  */
+  if (numargs == 1)
+    {
+      struct frame_id id = frame_id_build_wild (addrs[0]);
+      struct frame_info *fid;
+
+      /* If SETUP_ARBITRARY_FRAME is defined, then frame
+        specifications take at least 2 addresses.  It is important to
+        detect this case here so that "frame 100" does not give a
+        confusing error message like "frame specification requires
+        two addresses".  This of course does not solve the "frame
+        100" problem for machines on which a frame specification can
+        be made with one address.  To solve that, we need a new
+        syntax for a specifying a frame by address.  I think the
+        cleanest syntax is $frame(0x45) ($frame(0x23,0x45) for two
+        args, etc.), but people might think that is too much typing,
+        so I guess *0x23,0x45 would be a possible alternative (commas
+        really should be used instead of spaces to delimit; using
+        spaces normally works in an expression).  */
 #ifdef SETUP_ARBITRARY_FRAME
 #ifdef SETUP_ARBITRARY_FRAME
-      return SETUP_ARBITRARY_FRAME (numargs, args);
-#else
-      /* Usual case.  Do it here rather than have everyone supply
-         a SETUP_ARBITRARY_FRAME that does this.  */
-      if (numargs == 1)
-       return create_new_frame (args[0], 0);
-      error ("Too many args in frame specification");
+      error (_("No frame %s"), paddr_d (addrs[0]));
 #endif
 #endif
-      /* NOTREACHED */
-    }
-  /* NOTREACHED */
+      /* 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 (frame_id_eq (id, get_frame_id (fid)))
+           {
+             while (frame_id_eq (id, frame_unwind_id (fid)))
+               fid = get_prev_frame (fid);
+             return fid;
+           }
+       }
+      }
+
+  /* We couldn't identify the frame as an existing frame, but
+     perhaps we can create one with a single argument.  */
+  if (numargs == 1)
+    return create_new_frame (addrs[0], 0);
+  else if (numargs == 2)
+    return create_new_frame (addrs[0], addrs[1]);
+  else
+    error (_("Too many args in frame specification"));
+}
+
+struct frame_info *
+parse_frame_specification (char *frame_exp)
+{
+  return parse_frame_specification_1 (frame_exp, NULL, NULL);
 }
 
 /* Print verbosely the selected frame or the frame at address ADDR.
 }
 
 /* Print verbosely the selected frame or the frame at address ADDR.
@@ -842,9 +874,9 @@ frame_info (char *addr_exp, int from_tty)
   char *funname = 0;
   enum language funlang = language_unknown;
   const char *pc_regname;
   char *funname = 0;
   enum language funlang = language_unknown;
   const char *pc_regname;
+  int selected_frame_p;
 
 
-  if (!target_has_stack)
-    error ("No stack.");
+  fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);
 
   /* Name of the value returned by get_frame_pc().  Per comments, "pc"
      is not a good name.  */
 
   /* Name of the value returned by get_frame_pc().  Per comments, "pc"
      is not a good name.  */
@@ -860,10 +892,6 @@ frame_info (char *addr_exp, int from_tty)
        get_frame_pc().  */
     pc_regname = "pc";
 
        get_frame_pc().  */
     pc_regname = "pc";
 
-  fi = parse_frame_specification (addr_exp);
-  if (fi == NULL)
-    error ("Invalid frame specified.");
-
   find_frame_sal (fi, &sal);
   func = get_frame_function (fi);
   /* FIXME: cagney/2002-11-28: Why bother?  Won't sal.symtab contain
   find_frame_sal (fi, &sal);
   func = get_frame_function (fi);
   /* FIXME: cagney/2002-11-28: Why bother?  Won't sal.symtab contain
@@ -909,21 +937,21 @@ frame_info (char *addr_exp, int from_tty)
     }
   calling_frame_info = get_prev_frame (fi);
 
     }
   calling_frame_info = get_prev_frame (fi);
 
-  if (!addr_exp && frame_relative_level (deprecated_selected_frame) >= 0)
+  if (selected_frame_p && frame_relative_level (fi) >= 0)
     {
     {
-      printf_filtered ("Stack level %d, frame at ",
-                      frame_relative_level (deprecated_selected_frame));
-      print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
+      printf_filtered (_("Stack level %d, frame at "),
+                      frame_relative_level (fi));
+      deprecated_print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
       printf_filtered (":\n");
     }
   else
     {
       printf_filtered (":\n");
     }
   else
     {
-      printf_filtered ("Stack frame at ");
-      print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
+      printf_filtered (_("Stack frame at "));
+      deprecated_print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
       printf_filtered (":\n");
     }
   printf_filtered (" %s = ", pc_regname);
       printf_filtered (":\n");
     }
   printf_filtered (" %s = ", pc_regname);
-  print_address_numeric (get_frame_pc (fi), 1, gdb_stdout);
+  deprecated_print_address_numeric (get_frame_pc (fi), 1, gdb_stdout);
 
   wrap_here ("   ");
   if (funname)
 
   wrap_here ("   ");
   if (funname)
@@ -938,20 +966,13 @@ frame_info (char *addr_exp, int from_tty)
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s ", pc_regname);
   puts_filtered ("; ");
   wrap_here ("    ");
   printf_filtered ("saved %s ", pc_regname);
-  print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout);
+  deprecated_print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout);
   printf_filtered ("\n");
 
   printf_filtered ("\n");
 
-  {
-    int frameless;
-    frameless = FRAMELESS_FUNCTION_INVOCATION (fi);
-    if (frameless)
-      printf_filtered (" (FRAMELESS),");
-  }
-
   if (calling_frame_info)
     {
       printf_filtered (" called by frame at ");
   if (calling_frame_info)
     {
       printf_filtered (" called by frame at ");
-      print_address_numeric (get_frame_base (calling_frame_info),
+      deprecated_print_address_numeric (get_frame_base (calling_frame_info),
                             1, gdb_stdout);
     }
   if (get_next_frame (fi) && calling_frame_info)
                             1, gdb_stdout);
     }
   if (get_next_frame (fi) && calling_frame_info)
@@ -960,7 +981,7 @@ frame_info (char *addr_exp, int from_tty)
   if (get_next_frame (fi))
     {
       printf_filtered (" caller of frame at ");
   if (get_next_frame (fi))
     {
       printf_filtered (" caller of frame at ");
-      print_address_numeric (get_frame_base (get_next_frame (fi)), 1,
+      deprecated_print_address_numeric (get_frame_base (get_next_frame (fi)), 1,
                             gdb_stdout);
     }
   if (get_next_frame (fi) || calling_frame_info)
                             gdb_stdout);
     }
   if (get_next_frame (fi) || calling_frame_info)
@@ -969,10 +990,6 @@ frame_info (char *addr_exp, int from_tty)
     printf_filtered (" source language %s.\n",
                     language_str (s->language));
 
     printf_filtered (" source language %s.\n",
                     language_str (s->language));
 
-#ifdef PRINT_EXTRA_FRAME_INFO
-  PRINT_EXTRA_FRAME_INFO (fi);
-#endif
-
   {
     /* Address of the argument list for this frame, or 0.  */
     CORE_ADDR arg_list = get_frame_args_address (fi);
   {
     /* Address of the argument list for this frame, or 0.  */
     CORE_ADDR arg_list = get_frame_args_address (fi);
@@ -984,7 +1001,7 @@ frame_info (char *addr_exp, int from_tty)
     else
       {
        printf_filtered (" Arglist at ");
     else
       {
        printf_filtered (" Arglist at ");
-       print_address_numeric (arg_list, 1, gdb_stdout);
+       deprecated_print_address_numeric (arg_list, 1, gdb_stdout);
        printf_filtered (",");
 
        if (!FRAME_NUM_ARGS_P ())
        printf_filtered (",");
 
        if (!FRAME_NUM_ARGS_P ())
@@ -1016,14 +1033,11 @@ frame_info (char *addr_exp, int from_tty)
     else
       {
        printf_filtered (" Locals at ");
     else
       {
        printf_filtered (" Locals at ");
-       print_address_numeric (arg_list, 1, gdb_stdout);
+       deprecated_print_address_numeric (arg_list, 1, gdb_stdout);
        printf_filtered (",");
       }
   }
 
        printf_filtered (",");
       }
   }
 
-  if (DEPRECATED_FRAME_INIT_SAVED_REGS_P ()
-      && deprecated_get_frame_saved_regs (fi) == NULL)
-    DEPRECATED_FRAME_INIT_SAVED_REGS (fi);
   /* Print as much information as possible on the location of all the
      registers.  */
   {
   /* Print as much information as possible on the location of all the
      registers.  */
   {
@@ -1055,16 +1069,16 @@ frame_info (char *addr_exp, int from_tty)
            /* NOTE: cagney/2003-05-22: This is assuming that the
                stack pointer was packed as an unsigned integer.  That
                may or may not be valid.  */
            /* NOTE: cagney/2003-05-22: This is assuming that the
                stack pointer was packed as an unsigned integer.  That
                may or may not be valid.  */
-           sp = extract_unsigned_integer (value, REGISTER_RAW_SIZE (SP_REGNUM));
+           sp = extract_unsigned_integer (value, register_size (current_gdbarch, SP_REGNUM));
            printf_filtered (" Previous frame's sp is ");
            printf_filtered (" Previous frame's sp is ");
-           print_address_numeric (sp, 1, gdb_stdout);
+           deprecated_print_address_numeric (sp, 1, gdb_stdout);
            printf_filtered ("\n");
            need_nl = 0;
          }
        else if (!optimized && lval == lval_memory)
          {
            printf_filtered (" Previous frame's sp at ");
            printf_filtered ("\n");
            need_nl = 0;
          }
        else if (!optimized && lval == lval_memory)
          {
            printf_filtered (" Previous frame's sp at ");
-           print_address_numeric (addr, 1, gdb_stdout);
+           deprecated_print_address_numeric (addr, 1, gdb_stdout);
            printf_filtered ("\n");
            need_nl = 0;
          }
            printf_filtered ("\n");
            need_nl = 0;
          }
@@ -1097,7 +1111,7 @@ frame_info (char *addr_exp, int from_tty)
                puts_filtered (",");
              wrap_here (" ");
              printf_filtered (" %s at ", REGISTER_NAME (i));
                puts_filtered (",");
              wrap_here (" ");
              printf_filtered (" %s at ", REGISTER_NAME (i));
-             print_address_numeric (addr, 1, gdb_stdout);
+             deprecated_print_address_numeric (addr, 1, gdb_stdout);
              count++;
            }
        }
              count++;
            }
        }
@@ -1106,33 +1120,6 @@ frame_info (char *addr_exp, int from_tty)
   }
 }
 
   }
 }
 
-#if 0
-/* Set a limit on the number of frames printed by default in a
-   backtrace.  */
-
-static int backtrace_limit;
-
-static void
-set_backtrace_limit_command (char *count_exp, int from_tty)
-{
-  int count = parse_and_eval_long (count_exp);
-
-  if (count < 0)
-    error ("Negative argument not meaningful as backtrace limit.");
-
-  backtrace_limit = count;
-}
-
-static void
-backtrace_limit_info (char *arg, int from_tty)
-{
-  if (arg)
-    error ("\"Info backtrace-limit\" takes no arguments.");
-
-  printf_unfiltered ("Backtrace limit: %d.\n", backtrace_limit);
-}
-#endif
-
 /* Print briefly all stack frames or just the innermost COUNT frames.  */
 
 static void backtrace_command_1 (char *count_exp, int show_locals,
 /* Print briefly all stack frames or just the innermost COUNT frames.  */
 
 static void backtrace_command_1 (char *count_exp, int show_locals,
@@ -1147,7 +1134,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
   int trailing_level;
 
   if (!target_has_stack)
   int trailing_level;
 
   if (!target_has_stack)
-    error ("No stack.");
+    error (_("No stack."));
 
   /* The following code must do two things.  First, it must
      set the variable TRAILING to the frame from which we should start
 
   /* The following code must do two things.  First, it must
      set the variable TRAILING to the frame from which we should start
@@ -1158,7 +1145,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
   /* The target can be in a state where there is no valid frames
      (e.g., just connected). */
   if (trailing == NULL)
   /* The target can be in a state where there is no valid frames
      (e.g., just connected). */
   if (trailing == NULL)
-    error ("No stack.");
+    error (_("No stack."));
 
   trailing_level = 0;
   if (count_exp)
 
   trailing_level = 0;
   if (count_exp)
@@ -1224,14 +1211,30 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
          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).  */
          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 (fi, trailing_level + i, 0, 1);
+      print_frame_info (fi, 1, LOCATION, 1);
       if (show_locals)
        print_frame_local_vars (fi, 1, gdb_stdout);
     }
 
   /* If we've stopped before the end, mention that.  */
   if (fi && from_tty)
       if (show_locals)
        print_frame_local_vars (fi, 1, gdb_stdout);
     }
 
   /* If we've stopped before the end, mention that.  */
   if (fi && from_tty)
-    printf_filtered ("(More stack frames follow...)\n");
+    printf_filtered (_("(More stack frames follow...)\n"));
+}
+
+struct backtrace_command_args
+  {
+    char *count_exp;
+    int show_locals;
+    int from_tty;
+  };
+
+/* Stub to call backtrace_command_1 by way of an error catcher.  */
+static int
+backtrace_command_stub (void *data)
+{
+  struct backtrace_command_args *args = (struct backtrace_command_args *)data;
+  backtrace_command_1 (args->count_exp, args->show_locals, args->from_tty);
+  return 0;
 }
 
 static void
 }
 
 static void
@@ -1241,6 +1244,7 @@ backtrace_command (char *arg, int from_tty)
   char **argv = (char **) NULL;
   int argIndicatingFullTrace = (-1), totArgLen = 0, argc = 0;
   char *argPtr = arg;
   char **argv = (char **) NULL;
   int argIndicatingFullTrace = (-1), totArgLen = 0, argc = 0;
   char *argPtr = arg;
+  struct backtrace_command_args btargs;
 
   if (arg != (char *) NULL)
     {
 
   if (arg != (char *) NULL)
     {
@@ -1290,7 +1294,10 @@ backtrace_command (char *arg, int from_tty)
        }
     }
 
        }
     }
 
-  backtrace_command_1 (argPtr, (argIndicatingFullTrace >= 0), from_tty);
+  btargs.count_exp = argPtr;
+  btargs.show_locals = (argIndicatingFullTrace >= 0);
+  btargs.from_tty = from_tty;
+  catch_errors (backtrace_command_stub, (char *)&btargs, "", RETURN_MASK_ERROR);
 
   if (argIndicatingFullTrace >= 0 && totArgLen > 0)
     xfree (argPtr);
 
   if (argIndicatingFullTrace >= 0 && totArgLen > 0)
     xfree (argPtr);
@@ -1303,7 +1310,11 @@ static void backtrace_full_command (char *arg, int from_tty);
 static void
 backtrace_full_command (char *arg, int from_tty)
 {
 static void
 backtrace_full_command (char *arg, int from_tty)
 {
-  backtrace_command_1 (arg, 1, from_tty);
+  struct backtrace_command_args btargs;
+  btargs.count_exp = arg;
+  btargs.show_locals = 1;
+  btargs.from_tty = from_tty;
+  catch_errors (backtrace_command_stub, (char *)&btargs, "", RETURN_MASK_ERROR);
 }
 \f
 
 }
 \f
 
@@ -1357,7 +1368,7 @@ print_block_frame_labels (struct block *b, int *have_default,
 
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
 
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
-      if (STREQ (DEPRECATED_SYMBOL_NAME (sym), "default"))
+      if (strcmp (DEPRECATED_SYMBOL_NAME (sym), "default") == 0)
        {
          if (*have_default)
            continue;
        {
          if (*have_default)
            continue;
@@ -1372,7 +1383,7 @@ print_block_frame_labels (struct block *b, int *have_default,
          if (addressprint)
            {
              fprintf_filtered (stream, " ");
          if (addressprint)
            {
              fprintf_filtered (stream, " ");
-             print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, stream);
+             deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, stream);
            }
          fprintf_filtered (stream, " in file %s, line %d\n",
                            sal.symtab->filename, sal.line);
            }
          fprintf_filtered (stream, " in file %s, line %d\n",
                            sal.symtab->filename, sal.line);
@@ -1449,9 +1460,9 @@ print_frame_label_vars (struct frame_info *fi, int this_level_only,
       int last_index;
 
       if (bl != blockvector_for_pc (end, &index))
       int last_index;
 
       if (bl != blockvector_for_pc (end, &index))
-       error ("blockvector blotch");
+       error (_("blockvector blotch"));
       if (BLOCKVECTOR_BLOCK (bl, index) != block)
       if (BLOCKVECTOR_BLOCK (bl, index) != block)
-       error ("blockvector botch");
+       error (_("blockvector botch"));
       last_index = BLOCKVECTOR_NBLOCKS (bl);
       index += 1;
 
       last_index = BLOCKVECTOR_NBLOCKS (bl);
       index += 1;
 
@@ -1493,9 +1504,8 @@ print_frame_label_vars (struct frame_info *fi, int this_level_only,
 void
 locals_info (char *args, int from_tty)
 {
 void
 locals_info (char *args, int from_tty)
 {
-  if (!deprecated_selected_frame)
-    error ("No frame selected.");
-  print_frame_local_vars (deprecated_selected_frame, 0, gdb_stdout);
+  print_frame_local_vars (get_selected_frame ("No frame selected."),
+                         0, gdb_stdout);
 }
 
 static void
 }
 
 static void
@@ -1511,18 +1521,12 @@ catch_info (char *ignore, int from_tty)
       /* Ideally, here we should interact with the C++ runtime
          system to find the list of active handlers, etc. */
       fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n");
       /* Ideally, here we should interact with the C++ runtime
          system to find the list of active handlers, etc. */
       fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n");
-#if 0
-      if (!deprecated_selected_frame)
-       error ("No frame selected.");
-#endif
     }
   else
     {
       /* Assume g++ compiled code -- old v 4.16 behaviour */
     }
   else
     {
       /* Assume g++ compiled code -- old v 4.16 behaviour */
-      if (!deprecated_selected_frame)
-       error ("No frame selected.");
-
-      print_frame_label_vars (deprecated_selected_frame, 0, gdb_stdout);
+      print_frame_label_vars (get_selected_frame ("No frame selected."),
+                             0, gdb_stdout);
     }
 }
 
     }
 }
 
@@ -1589,9 +1593,8 @@ print_frame_arg_vars (struct frame_info *fi,
 void
 args_info (char *ignore, int from_tty)
 {
 void
 args_info (char *ignore, int from_tty)
 {
-  if (!deprecated_selected_frame)
-    error ("No frame selected.");
-  print_frame_arg_vars (deprecated_selected_frame, gdb_stdout);
+  print_frame_arg_vars (get_selected_frame ("No frame selected."),
+                       gdb_stdout);
 }
 
 
 }
 
 
@@ -1610,9 +1613,7 @@ select_and_print_frame (struct frame_info *fi)
 {
   select_frame (fi);
   if (fi)
 {
   select_frame (fi);
   if (fi)
-    {
-      print_stack_frame (fi, frame_relative_level (fi), 1);
-    }
+    print_stack_frame (fi, 1, SRC_AND_LOC);
 }
 \f
 /* Return the symbol-block in which the selected frame is executing.
 }
 \f
 /* Return the symbol-block in which the selected frame is executing.
@@ -1629,7 +1630,7 @@ get_selected_block (CORE_ADDR *addr_in_block)
     return 0;
 
   /* NOTE: cagney/2002-11-28: Why go to all this effort to not create
     return 0;
 
   /* NOTE: cagney/2002-11-28: Why go to all this effort to not create
-     a selected/current frame?  Perhaphs this function is called,
+     a selected/current frame?  Perhaps this function is called,
      indirectly, by WFI in "infrun.c" where avoiding the creation of
      an inner most frame is very important (it slows down single
      step).  I suspect, though that this was true in the deep dark
      indirectly, by WFI in "infrun.c" where avoiding the creation of
      an inner most frame is very important (it slows down single
      step).  I suspect, though that this was true in the deep dark
@@ -1698,17 +1699,7 @@ find_relative_frame (struct frame_info *frame,
 void
 select_frame_command (char *level_exp, int from_tty)
 {
 void
 select_frame_command (char *level_exp, int from_tty)
 {
-  struct frame_info *frame;
-  int level = frame_relative_level (deprecated_selected_frame);
-
-  if (!target_has_stack)
-    error ("No stack.");
-
-  frame = parse_frame_specification (level_exp);
-
-  select_frame (frame);
-  if (level != frame_relative_level (deprecated_selected_frame))
-    selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame));
+  select_frame (parse_frame_specification_1 (level_exp, "No stack.", NULL));
 }
 
 /* The "frame" command.  With no arg, print selected frame briefly.
 }
 
 /* The "frame" command.  With no arg, print selected frame briefly.
@@ -1719,8 +1710,7 @@ void
 frame_command (char *level_exp, int from_tty)
 {
   select_frame_command (level_exp, from_tty);
 frame_command (char *level_exp, int from_tty)
 {
   select_frame_command (level_exp, from_tty);
-  print_stack_frame (deprecated_selected_frame,
-                    frame_relative_level (deprecated_selected_frame), 1);
+  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
 }
 
 /* The XDB Compatibility command to print the current frame. */
 }
 
 /* The XDB Compatibility command to print the current frame. */
@@ -1728,10 +1718,7 @@ frame_command (char *level_exp, int from_tty)
 static void
 current_frame_command (char *level_exp, int from_tty)
 {
 static void
 current_frame_command (char *level_exp, int from_tty)
 {
-  if (target_has_stack == 0 || deprecated_selected_frame == 0)
-    error ("No stack.");
-  print_stack_frame (deprecated_selected_frame,
-                         frame_relative_level (deprecated_selected_frame), 1);
+  print_stack_frame (get_selected_frame ("No stack."), 1, SRC_AND_LOC);
 }
 
 /* Select the frame up one or COUNT stack levels
 }
 
 /* Select the frame up one or COUNT stack levels
@@ -1746,14 +1733,10 @@ up_silently_base (char *count_exp)
     count = parse_and_eval_long (count_exp);
   count1 = count;
 
     count = parse_and_eval_long (count_exp);
   count1 = count;
 
-  if (target_has_stack == 0 || deprecated_selected_frame == 0)
-    error ("No stack.");
-
-  fi = find_relative_frame (deprecated_selected_frame, &count1);
+  fi = find_relative_frame (get_selected_frame ("No stack."), &count1);
   if (count1 != 0 && count_exp == 0)
   if (count1 != 0 && count_exp == 0)
-    error ("Initial frame selected; you cannot go up.");
+    error (_("Initial frame selected; you cannot go up."));
   select_frame (fi);
   select_frame (fi);
-  selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame));
 }
 
 static void
 }
 
 static void
@@ -1766,8 +1749,7 @@ static void
 up_command (char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
 up_command (char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
-  print_stack_frame (deprecated_selected_frame,
-                    frame_relative_level (deprecated_selected_frame), 1);
+  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
 }
 
 /* Select the frame down one or COUNT stack levels
 }
 
 /* Select the frame down one or COUNT stack levels
@@ -1782,10 +1764,7 @@ down_silently_base (char *count_exp)
     count = -parse_and_eval_long (count_exp);
   count1 = count;
 
     count = -parse_and_eval_long (count_exp);
   count1 = count;
 
-  if (target_has_stack == 0 || deprecated_selected_frame == 0)
-    error ("No stack.");
-
-  frame = find_relative_frame (deprecated_selected_frame, &count1);
+  frame = find_relative_frame (get_selected_frame ("No stack."), &count1);
   if (count1 != 0 && count_exp == 0)
     {
 
   if (count1 != 0 && count_exp == 0)
     {
 
@@ -1794,11 +1773,10 @@ down_silently_base (char *count_exp)
          impossible), but "down 9999" can be used to mean go all the way
          down without getting an error.  */
 
          impossible), but "down 9999" can be used to mean go all the way
          down without getting an error.  */
 
-      error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
+      error (_("Bottom (i.e., innermost) frame selected; you cannot go down."));
     }
 
   select_frame (frame);
     }
 
   select_frame (frame);
-  selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame));
 }
 
 static void
 }
 
 static void
@@ -1811,102 +1789,132 @@ static void
 down_command (char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
 down_command (char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
-  print_stack_frame (deprecated_selected_frame,
-                    frame_relative_level (deprecated_selected_frame), 1);
+  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
 }
 \f
 void
 return_command (char *retval_exp, int from_tty)
 {
   struct symbol *thisfun;
 }
 \f
 void
 return_command (char *retval_exp, int from_tty)
 {
   struct symbol *thisfun;
-  CORE_ADDR selected_frame_addr;
-  CORE_ADDR selected_frame_pc;
-  struct frame_info *frame;
   struct value *return_value = NULL;
   struct value *return_value = NULL;
+  const char *query_prefix = "";
 
 
-  if (deprecated_selected_frame == NULL)
-    error ("No selected frame.");
-  thisfun = get_frame_function (deprecated_selected_frame);
-  selected_frame_addr = get_frame_base (deprecated_selected_frame);
-  selected_frame_pc = get_frame_pc (deprecated_selected_frame);
-
-  /* Compute the return value (if any -- possibly getting errors here).  */
+  thisfun = get_frame_function (get_selected_frame ("No selected frame."));
 
 
+  /* 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)
     {
       struct type *return_type = NULL;
 
   if (retval_exp)
     {
       struct type *return_type = NULL;
 
+      /* Compute the return value.  Should the computation fail, this
+         call throws an error.  */
       return_value = parse_and_eval (retval_exp);
 
       return_value = parse_and_eval (retval_exp);
 
-      /* Cast return value to the return type of the function.  */
+      /* Cast return value to the return type of the function.  Should
+         the cast fail, this call throws an error.  */
       if (thisfun != NULL)
        return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
       if (return_type == NULL)
        return_type = builtin_type_int;
       if (thisfun != NULL)
        return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
       if (return_type == NULL)
        return_type = builtin_type_int;
+      CHECK_TYPEDEF (return_type);
       return_value = value_cast (return_type, return_value);
 
       return_value = value_cast (return_type, return_value);
 
-      /* Make sure we have fully evaluated it, since
-         it might live in the stack frame we're about to pop.  */
-      if (VALUE_LAZY (return_value))
+      /* Make sure the value is fully evaluated.  It may live in the
+         stack frame we're about to pop.  */
+      if (value_lazy (return_value))
        value_fetch_lazy (return_value);
        value_fetch_lazy (return_value);
-    }
 
 
-  /* If interactive, require confirmation.  */
-
-  if (from_tty)
-    {
-      if (thisfun != 0)
+      if (TYPE_CODE (return_type) == 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
+           occure.  */
+       return_value = NULL;
+      /* FIXME: cagney/2004-01-17: If the architecture implements both
+         return_value and extract_returned_value_address, should allow
+         "return" to work - don't set return_value to NULL.  */
+      else if (!gdbarch_return_value_p (current_gdbarch)
+              && (TYPE_CODE (return_type) == TYPE_CODE_STRUCT
+                  || TYPE_CODE (return_type) == TYPE_CODE_UNION))
        {
        {
-         if (!query ("Make %s return now? ", SYMBOL_PRINT_NAME (thisfun)))
-           {
-             error ("Not confirmed.");
-             /* NOTREACHED */
-           }
+         /* NOTE: cagney/2003-10-20: Compatibility hack for legacy
+            code.  Old architectures don't expect STORE_RETURN_VALUE
+            to be called with with a small struct that needs to be
+            stored in registers.  Don't start doing it now.  */
+         query_prefix = "\
+A structure or union return type is not supported by this architecture.\n\
+If you continue, the return value that you specified will be ignored.\n";
+         return_value = NULL;
+       }
+      else if (using_struct_return (return_type, 0))
+       {
+         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;
        }
        }
-      else if (!query ("Make selected stack frame return now? "))
-       error ("Not confirmed.");
     }
 
     }
 
-  /* FIXME: cagney/2003-01-18: Rather than pop each frame in turn,
-     this code should just go straight to the relevant frame and pop
-     that.  */
-
-  /* Do the real work.  Pop until the specified frame is current.  We
-     use this method because the deprecated_selected_frame is not
-     valid after a frame_pop().  The pc comparison makes this work
-     even if the selected frame shares its fp with another frame.  */
-
-  /* FIXME: cagney/32003-03-12: This code should use frame_id_eq().
-     Unfortunatly, that function doesn't yet include the PC in any
-     frame ID comparison.  */
+  /* 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 (thisfun == NULL)
+       confirmed = query (_("%sMake selected stack frame return now? "),
+                          query_prefix);
+      else
+       confirmed = query (_("%sMake %s return now? "), query_prefix,
+                          SYMBOL_PRINT_NAME (thisfun));
+      if (!confirmed)
+       error (_("Not confirmed"));
+    }
 
 
-  while (selected_frame_addr != get_frame_base (frame = get_current_frame ())
-        || selected_frame_pc != get_frame_pc (frame))
-    frame_pop (get_current_frame ());
+  /* NOTE: cagney/2003-01-18: Is this silly?  Rather than pop each
+     frame in turn, should this code just go straight to the relevant
+     frame and pop that?  */
 
 
-  /* Then pop that frame.  */
+  /* First discard all frames inner-to the selected frame (making the
+     selected frame current).  */
+  {
+    struct frame_id selected_id = get_frame_id (get_selected_frame (NULL));
+    while (!frame_id_eq (selected_id, get_frame_id (get_current_frame ())))
+      {
+       if (frame_id_inner (selected_id, get_frame_id (get_current_frame ())))
+         /* Caught in the safety net, oops!  We've gone way past the
+             selected frame.  */
+         error (_("Problem while popping stack frames (corrupt stack?)"));
+       frame_pop (get_current_frame ());
+      }
+  }
 
 
+  /* Second discard the selected frame (which is now also the current
+     frame).  */
   frame_pop (get_current_frame ());
 
   frame_pop (get_current_frame ());
 
-  /* Compute the return value (if any) and store in the place
-     for return values.  */
-
-  if (retval_exp)
-    set_return_value (return_value);
-
-  /* If we are at the end of a call dummy now, pop the dummy frame too.  */
+  /* Store RETURN_VAUE in the just-returned register set.  */
+  if (return_value != NULL)
+    {
+      struct type *return_type = value_type (return_value);
+      gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
+                                       NULL, NULL, NULL)
+                 == RETURN_VALUE_REGISTER_CONVENTION);
+      gdbarch_return_value (current_gdbarch, return_type,
+                           current_regcache, NULL /*read*/,
+                           value_contents (return_value) /*write*/);
+    }
 
 
-  /* FIXME: cagney/2003-01-18: This is silly.  Instead of popping all
-     the frames except the dummy, and then, as an afterthought,
-     popping the dummy frame, this code should just pop through to the
-     dummy frame.  */
-  
-  if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
-                               get_frame_base (get_current_frame ())))
+  /* 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 ());
 
   /* If interactive, print the frame that is now current.  */
     frame_pop (get_current_frame ());
 
   /* If interactive, print the frame that is now current.  */
-
   if (from_tty)
     frame_command ("0", 1);
   else
   if (from_tty)
     frame_command ("0", 1);
   else
@@ -1969,7 +1977,7 @@ func_command (char *arg, int from_tty)
     xfree (func_bounds);
 
   if (!found)
     xfree (func_bounds);
 
   if (!found)
-    printf_filtered ("'%s' not within current stack frame.\n", arg);
+    printf_filtered (_("'%s' not within current stack frame.\n"), arg);
   else if (fp != deprecated_selected_frame)
     select_and_print_frame (fp);
 }
   else if (fp != deprecated_selected_frame)
     select_and_print_frame (fp);
 }
@@ -1984,7 +1992,14 @@ get_frame_language (void)
 
   if (deprecated_selected_frame)
     {
 
   if (deprecated_selected_frame)
     {
-      s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
+      /* We determine the current frame language by looking up its
+         associated symtab.  To retrieve this symtab, we use the frame PC.
+         However we cannot use the frame pc as is, because it usually points
+         to the instruction following the "call", which is sometimes the first
+         instruction of another function.  So we rely on
+         get_frame_address_in_block(), it provides us with a PC which is
+         guaranteed to be inside the frame's code block.  */
+      s = find_pc_symtab (get_frame_address_in_block (deprecated_selected_frame));
       if (s)
        flang = s->language;
       else
       if (s)
        flang = s->language;
       else
@@ -2084,8 +2099,8 @@ Usage: T <count>\n");
            "Exceptions that can be caught in the current stack frame.");
 
 #if 0
            "Exceptions that can be caught in the current stack frame.");
 
 #if 0
-  add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command,
-  "Specify maximum number of frames for \"backtrace\" to print by default.",
+  add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\
+"Specify maximum number of frames for \"backtrace\" to print by default."),
           &setlist);
   add_info ("backtrace-limit", backtrace_limit_info,
      "The maximum number of frames for \"backtrace\" to print by default.");
           &setlist);
   add_info ("backtrace-limit", backtrace_limit_info,
      "The maximum number of frames for \"backtrace\" to print by default.");
This page took 0.042707 seconds and 4 git commands to generate.