* mi-main.c (mi_cmd_thread_select): Only return MI_CMD_CAUGHT_ERROR
[deliverable/binutils-gdb.git] / gdb / stack.c
index 3e81f628e44f29d816837127f55c1638a840fc43..f36e651a375f0739e3dfb158d80d021dd364bec1 100644 (file)
@@ -1,5 +1,8 @@
 /* Print and select stack frames for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991-1996, 1998-2000 Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "target.h"
+#include "source.h"
 #include "breakpoint.h"
 #include "demangle.h"
 #include "inferior.h"
 #include "annotate.h"
-#include "symfile.h"
-#include "objfiles.h"
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
 
 /* Prototypes for exported functions. */
 
@@ -50,9 +50,9 @@ void (*selected_frame_level_changed_hook) (int);
 
 void _initialize_stack (void);
 
-/* Prototypes for local functions. */
+void return_command (char *, int);
 
-static void return_command (char *, int);
+/* Prototypes for local functions. */
 
 static void down_command (char *, int);
 
@@ -109,8 +109,6 @@ struct frame_info *parse_frame_specification (char *);
 static void frame_info (char *, int);
 
 extern int addressprint;       /* Print addresses, or stay symbolic only? */
-extern int info_verbose;       /* Verbosity of symbol reading msgs */
-extern int lines_to_list;      /* # of lines "list" command shows by default */
 
 /* The "selected" stack frame is used by default for local and arg access.
    May be zero, for no selected frame.  */
@@ -121,7 +119,17 @@ struct frame_info *selected_frame;
    0 for innermost, 1 for its caller, ...
    or -1 for frame specified by address with no defined level.  */
 
-int selected_frame_level;
+/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
+   or -1 for NULL frame.  */
+
+int
+frame_relative_level (struct frame_info *fi)
+{
+  if (fi == NULL)
+    return -1;
+  else
+    return fi->level;
+}
 
 /* Zero means do things normally; we are interacting directly with the
    user.  One means print the full filename and linenumber when a
@@ -150,11 +158,6 @@ show_and_print_stack_frame_stub (void *args)
 {
   struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
 
-  /* Reversed order of these so tuiDo() doesn't occur
-   * in the middle of "Breakpoint 1 ... [location]" printing = RT
-   */
-  if (tui_version)
-    print_frame_info_base (p->fi, p->level, p->source, p->args);
   print_frame_info (p->fi, p->level, p->source, p->args);
 
   return 0;
@@ -168,10 +171,7 @@ print_stack_frame_stub (void *args)
 {
   struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
 
-  if (tui_version)
-    print_frame_info (p->fi, p->level, p->source, p->args);
-  else
-    print_frame_info_base (p->fi, p->level, p->source, p->args);
+  print_frame_info_base (p->fi, p->level, p->source, p->args);
   return 0;
 }
 
@@ -358,7 +358,10 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
       if (level >= 0)
-       printf_filtered ("#%-2d ", level);
+        {
+          ui_out_text (uiout, "#");
+          ui_out_field_fmt_int (uiout, 2, ui_left, "level", level);
+        }
       annotate_function_call ();
       printf_filtered ("<function called from gdb>\n");
       annotate_frame_end ();
@@ -371,7 +374,10 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
       if (level >= 0)
-       printf_filtered ("#%-2d ", level);
+        {
+          ui_out_text (uiout, "#");
+          ui_out_field_fmt_int (uiout, 2, ui_left, "level", level);
+        }
       annotate_signal_handler_caller ();
       printf_filtered ("<signal handler called>\n");
       annotate_frame_end ();
@@ -399,8 +405,12 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
 
   source_print = (source == SRC_LINE || source == SRC_AND_LOC);
 
+  if (sal.symtab)
+    set_current_source_symtab_and_line (&sal);
+
   if (source_print && sal.symtab)
     {
+      struct symtab_and_line cursal;
       int done = 0;
       int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
 
@@ -409,22 +419,32 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
                                     fi->pc);
       if (!done)
        {
-         if (addressprint && mid_statement && !tui_version)
-           {
-#ifdef UI_OUT
-             ui_out_field_core_addr (uiout, "addr", fi->pc);
-             ui_out_text (uiout, "\t");
-#else
-             print_address_numeric (fi->pc, 1, gdb_stdout);
-             printf_filtered ("\t");
-#endif
-           }
          if (print_frame_info_listing_hook)
            print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
-         else if (!tui_version)
-           print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+         else
+           {
+             /* 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 (addressprint && mid_statement)
+               {
+                 ui_out_field_core_addr (uiout, "addr", fi->pc);
+                 ui_out_text (uiout, "\t");
+               }
+
+             print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+           }
        }
-      current_source_line = max (sal.line - lines_to_list / 2, 1);
+      /* 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)
@@ -445,15 +465,14 @@ print_frame (struct frame_info *fi,
   struct symbol *func;
   register char *funname = 0;
   enum language funlang = language_unknown;
-#ifdef UI_OUT
   struct ui_stream *stb;
   struct cleanup *old_chain;
+  struct cleanup *list_chain;
 
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
-#endif /* UI_OUT */
 
-  func = find_pc_function (fi->pc);
+  func = find_pc_function (frame_address_in_block (fi));
   if (func)
     {
       /* In certain pathological cases, the symtabs give the wrong
@@ -472,7 +491,7 @@ print_frame (struct frame_info *fi,
          ever changed many parts of GDB will need to be changed (and we'll
          create a find_pc_minimal_function or some such).  */
 
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
       if (msymbol != NULL
          && (SYMBOL_VALUE_ADDRESS (msymbol)
              > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
@@ -520,7 +539,7 @@ print_frame (struct frame_info *fi,
     }
   else
     {
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
       if (msymbol != NULL)
        {
          funname = SYMBOL_NAME (msymbol);
@@ -530,78 +549,48 @@ print_frame (struct frame_info *fi,
 
   annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
 
-#ifdef UI_OUT
-  ui_out_list_begin (uiout, "frame");
-#endif
+  list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
 
   if (level >= 0)
     {
-#ifdef UI_OUT
       ui_out_text (uiout, "#");
-      ui_out_field_fmt (uiout, "level", "%-2d", level);
-      ui_out_spaces (uiout, 1);
-#else
-      printf_filtered ("#%-2d ", level);
-#endif
+      ui_out_field_fmt_int (uiout, 2, ui_left, "level", level);
     }
   if (addressprint)
     if (fi->pc != sal.pc || !sal.symtab || source == LOC_AND_ADDRESS)
       {
        annotate_frame_address ();
-#ifdef UI_OUT
        ui_out_field_core_addr (uiout, "addr", fi->pc);
        annotate_frame_address_end ();
        ui_out_text (uiout, " in ");
-#else
-       print_address_numeric (fi->pc, 1, gdb_stdout);
-       annotate_frame_address_end ();
-       printf_filtered (" in ");
-#endif
       }
   annotate_frame_function_name ();
-#ifdef UI_OUT
   fprintf_symbol_filtered (stb->stream, funname ? funname : "??", funlang,
                           DMGL_ANSI);
   ui_out_field_stream (uiout, "func", stb);
   ui_out_wrap_hint (uiout, "   ");
-#else
-  fprintf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang,
-                          DMGL_ANSI);
-  wrap_here ("   ");
-#endif
   annotate_frame_args ();
       
-#ifdef UI_OUT
   ui_out_text (uiout, " (");
-#else
-  fputs_filtered (" (", gdb_stdout);
-#endif
   if (args)
     {
       struct print_args_args args;
+      struct cleanup *args_list_chain;
       args.fi = fi;
       args.func = func;
       args.stream = gdb_stdout;
-#ifdef UI_OUT
-      ui_out_list_begin (uiout, "args");
+      args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args");
       catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
       /* FIXME: args must be a list. If one argument is a string it will
                 have " that will not be properly escaped.  */
-      ui_out_list_end (uiout);
-#else
-      catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
-#endif
+      /* Invoke ui_out_tuple_end.  */
+      do_cleanups (args_list_chain);
       QUIT;
     }
-#ifdef UI_OUT
   ui_out_text (uiout, ")");
-#else
-  printf_filtered (")");
-#endif
   if (sal.symtab && sal.symtab->filename)
     {
       annotate_frame_source_begin ();
-#ifdef UI_OUT
       ui_out_wrap_hint (uiout, "   ");
       ui_out_text (uiout, " at ");
       annotate_frame_source_file ();
@@ -610,37 +599,9 @@ print_frame (struct frame_info *fi,
       ui_out_text (uiout, ":");
       annotate_frame_source_line ();
       ui_out_field_int (uiout, "line", sal.line);
-#else
-      wrap_here ("   ");
-      printf_filtered (" at ");
-      annotate_frame_source_file ();
-      printf_filtered ("%s", sal.symtab->filename);
-      annotate_frame_source_file_end ();
-      printf_filtered (":");
-      annotate_frame_source_line ();
-      printf_filtered ("%d", sal.line);
-#endif
       annotate_frame_source_end ();
     }
 
-#ifdef PC_LOAD_SEGMENT
-  /* If we couldn't print out function name but if can figure out what
-         load segment this pc value is from, at least print out some info
-         about its load segment. */
-  if (!funname)
-    {
-      annotate_frame_where ();
-#ifdef UI_OUT
-      ui_out_wrap_hint (uiout, "  ");
-      ui_out_text (uiout, " from ");
-      ui_out_field_string (uiout, "from", PC_LOAD_SEGMENT (fi->pc));
-#else
-      wrap_here ("  ");
-      printf_filtered (" from %s", PC_LOAD_SEGMENT (fi->pc));
-#endif
-    }
-#endif /* PC_LOAD_SEGMENT */
-
 #ifdef PC_SOLIB
   if (!funname || (!sal.symtab || !sal.symtab->filename))
     {
@@ -648,55 +609,27 @@ print_frame (struct frame_info *fi,
       if (lib)
        {
          annotate_frame_where ();
-#ifdef UI_OUT
          ui_out_wrap_hint (uiout, "  ");
          ui_out_text (uiout, " from ");
          ui_out_field_string (uiout, "from", lib);
-#else
-         wrap_here ("  ");
-         printf_filtered (" from %s", lib);
-#endif
        }
     }
 #endif /* PC_SOLIB */
 
-#ifdef UI_OUT
-  ui_out_list_end (uiout);
+  /* do_cleanups will call ui_out_tuple_end() for us.  */
+  do_cleanups (list_chain);
   ui_out_text (uiout, "\n");
   do_cleanups (old_chain);
-#else
-  printf_filtered ("\n");
-#endif
 }
 \f
 
-#if 0
-void
-stack_publish_stopped_with_no_frame (void)
-{
-  TUIDO (((TuiOpaqueFuncPtr) tuiUpdateOnEnd));
-
-  return;
-}
-#endif
-
 /* Show or print the frame info.  If this is the tui, it will be shown in 
    the source display */
 void
 print_frame_info (struct frame_info *fi, register int level, int source,
                  int args)
 {
-  if (!tui_version)
-    print_frame_info_base (fi, level, source, args);
-  else
-    {
-      if (fi && (frame_in_dummy (fi) || fi->signal_handler_caller))
-       print_frame_info_base (fi, level, source, args);
-      else
-       {
-         TUIDO (((TuiOpaqueFuncPtr) tui_vShowFrameInfo, fi));
-       }
-    }
+  print_frame_info_base (fi, level, source, args);
 }
 
 /* Show the frame info.  If this is the tui, it will be shown in 
@@ -704,7 +637,6 @@ print_frame_info (struct frame_info *fi, register int level, int source,
 void
 show_stack_frame (struct frame_info *fi)
 {
-  TUIDO (((TuiOpaqueFuncPtr) tui_vShowFrameInfo, fi));
 }
 \f
 
@@ -718,6 +650,7 @@ parse_frame_specification (char *frame_exp)
   int numargs = 0;
 #define        MAXARGS 4
   CORE_ADDR args[MAXARGS];
+  int level;
 
   if (frame_exp)
     {
@@ -737,8 +670,20 @@ parse_frame_specification (char *frame_exp)
          addr_string = savestring (frame_exp, p - frame_exp);
 
          {
-           tmp_cleanup = make_cleanup (free, addr_string);
-           args[numargs++] = parse_and_eval_address (addr_string);
+           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);
          }
 
@@ -758,7 +703,6 @@ parse_frame_specification (char *frame_exp)
       /* NOTREACHED */
     case 1:
       {
-       int level = args[0];
        struct frame_info *fid =
        find_relative_frame (get_current_frame (), &level);
        struct frame_info *tfid;
@@ -780,7 +724,7 @@ parse_frame_specification (char *frame_exp)
           really should be used instead of spaces to delimit; using spaces
           normally works in an expression).  */
 #ifdef SETUP_ARBITRARY_FRAME
-       error ("No frame %d", args[0]);
+       error ("No frame %s", paddr_d (args[0]));
 #endif
 
        /* If (s)he specifies the frame with an address, he deserves what
@@ -893,9 +837,10 @@ frame_info (char *addr_exp, int from_tty)
     }
   calling_frame_info = get_prev_frame (fi);
 
-  if (!addr_exp && selected_frame_level >= 0)
+  if (!addr_exp && frame_relative_level (selected_frame) >= 0)
     {
-      printf_filtered ("Stack level %d, frame at ", selected_frame_level);
+      printf_filtered ("Stack level %d, frame at ",
+                      frame_relative_level (selected_frame));
       print_address_numeric (fi->frame, 1, gdb_stdout);
       printf_filtered (":\n");
     }
@@ -994,39 +939,84 @@ frame_info (char *addr_exp, int from_tty)
       }
   }
 
-  FRAME_INIT_SAVED_REGS (fi);
-  if (fi->saved_regs != NULL)
-    {
-      /* The sp is special; what's returned isn't the save address, but
-         actually the value of the previous frame's sp.  */
-      printf_filtered (" Previous frame's sp is ");
-      print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout);
-      printf_filtered ("\n");
-      count = 0;
-      numregs = ARCH_NUM_REGS;
-      for (i = 0; i < numregs; i++)
-       if (fi->saved_regs[i] && i != SP_REGNUM)
+  if (fi->saved_regs == NULL)
+    FRAME_INIT_SAVED_REGS (fi);
+  /* Print as much information as possible on the location of all the
+     registers.  */
+  {
+    enum lval_type lval;
+    int optimized;
+    CORE_ADDR addr;
+    int realnum;
+    int count;
+    int i;
+    int need_nl = 1;
+
+    /* 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)
+      {
+       /* Find out the location of the saved stack pointer with out
+           actually evaluating it.  */
+       frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
+                              &realnum, NULL);
+       if (!optimized && lval == not_lval)
          {
-           if (count == 0)
-             puts_filtered (" Saved registers:\n ");
-           else
-             puts_filtered (",");
-           wrap_here (" ");
-           printf_filtered (" %s at ", REGISTER_NAME (i));
-           print_address_numeric (fi->saved_regs[i], 1, gdb_stdout);
-           count++;
+           void *value = alloca (MAX_REGISTER_RAW_SIZE);
+           CORE_ADDR sp;
+           frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
+                                  &realnum, value);
+           sp = extract_address (value, REGISTER_RAW_SIZE (SP_REGNUM));
+           printf_filtered (" Previous frame's sp is ");
+           print_address_numeric (sp, 1, gdb_stdout);
+           printf_filtered ("\n");
+           need_nl = 0;
          }
-      if (count)
-       puts_filtered ("\n");
-    }
-  else
-    {
-      /* We could get some information about saved registers by
-         calling get_saved_register on each register.  Which info goes
-         with which frame is necessarily lost, however, and I suspect
-         that the users don't care whether they get the info.  */
+       else if (!optimized && lval == lval_memory)
+         {
+           printf_filtered (" Previous frame's sp at ");
+           print_address_numeric (addr, 1, gdb_stdout);
+           printf_filtered ("\n");
+           need_nl = 0;
+         }
+       else if (!optimized && lval == lval_register)
+         {
+           printf_filtered (" Previous frame's sp in %s\n",
+                            REGISTER_NAME (realnum));
+           need_nl = 0;
+         }
+       /* else keep quiet.  */
+      }
+
+    count = 0;
+    numregs = NUM_REGS + NUM_PSEUDO_REGS;
+    for (i = 0; i < numregs; i++)
+      if (i != SP_REGNUM)
+       {
+         /* Find out the location of the saved register without
+             fetching the corresponding value.  */
+         frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum,
+                                NULL);
+         /* For moment, only display registers that were saved on the
+            stack.  */
+         if (!optimized && lval == lval_memory)
+           {
+             if (count == 0)
+               puts_filtered (" Saved registers:\n ");
+             else
+               puts_filtered (",");
+             wrap_here (" ");
+             printf_filtered (" %s at ", REGISTER_NAME (i));
+             print_address_numeric (addr, 1, gdb_stdout);
+             count++;
+           }
+       }
+    if (count || need_nl)
       puts_filtered ("\n");
-    }
+  }
 }
 
 #if 0
@@ -1038,7 +1028,7 @@ static int backtrace_limit;
 static void
 set_backtrace_limit_command (char *count_exp, int from_tty)
 {
-  int count = parse_and_eval_address (count_exp);
+  int count = parse_and_eval_long (count_exp);
 
   if (count < 0)
     error ("Negative argument not meaningful as backtrace limit.");
@@ -1086,7 +1076,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
   trailing_level = 0;
   if (count_exp)
     {
-      count = parse_and_eval_address (count_exp);
+      count = parse_and_eval_long (count_exp);
       if (count < 0)
        {
          struct frame_info *current;
@@ -1131,7 +1121,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
           fi = get_prev_frame (fi))
        {
          QUIT;
-         ps = find_pc_psymtab (fi->pc);
+         ps = find_pc_psymtab (frame_address_in_block (fi));
          if (ps)
            PSYMTAB_TO_SYMTAB (ps);     /* Force syms to come in */
        }
@@ -1216,7 +1206,7 @@ backtrace_command (char *arg, int from_tty)
   backtrace_command_1 (argPtr, (argIndicatingFullTrace >= 0), from_tty);
 
   if (argIndicatingFullTrace >= 0 && totArgLen > 0)
-    free (argPtr);
+    xfree (argPtr);
 
   if (old_chain)
     do_cleanups (old_chain);
@@ -1237,16 +1227,12 @@ static int
 print_block_frame_locals (struct block *b, register struct frame_info *fi,
                          int num_tabs, register struct ui_file *stream)
 {
-  int nsyms;
   register int i, j;
   register struct symbol *sym;
   register int values_printed = 0;
 
-  nsyms = BLOCK_NSYMS (b);
-
-  for (i = 0; i < nsyms; i++)
+  ALL_BLOCK_SYMBOLS (b, i, sym)
     {
-      sym = BLOCK_SYM (b, i);
       switch (SYMBOL_CLASS (sym))
        {
        case LOC_LOCAL:
@@ -1276,16 +1262,12 @@ static int
 print_block_frame_labels (struct block *b, int *have_default,
                          register struct ui_file *stream)
 {
-  int nsyms;
   register int i;
   register struct symbol *sym;
   register int values_printed = 0;
 
-  nsyms = BLOCK_NSYMS (b);
-
-  for (i = 0; i < nsyms; i++)
+  ALL_BLOCK_SYMBOLS (b, i, sym)
     {
-      sym = BLOCK_SYM (b, i);
       if (STREQ (SYMBOL_NAME (sym), "default"))
        {
          if (*have_default)
@@ -1322,7 +1304,7 @@ static void
 print_frame_local_vars (register struct frame_info *fi, register int num_tabs,
                        register struct ui_file *stream)
 {
-  register struct block *block = get_frame_block (fi);
+  register struct block *block = get_frame_block (fi, 0);
   register int values_printed = 0;
 
   if (block == 0)
@@ -1356,7 +1338,7 @@ print_frame_label_vars (register struct frame_info *fi, int this_level_only,
                        register struct ui_file *stream)
 {
   register struct blockvector *bl;
-  register struct block *block = get_frame_block (fi);
+  register struct block *block = get_frame_block (fi, 0);
   register int values_printed = 0;
   int index, have_default = 0;
   char *blocks_printed;
@@ -1462,7 +1444,6 @@ print_frame_arg_vars (register struct frame_info *fi,
 {
   struct symbol *func = get_frame_function (fi);
   register struct block *b;
-  int nsyms;
   register int i;
   register struct symbol *sym, *sym2;
   register int values_printed = 0;
@@ -1474,11 +1455,8 @@ print_frame_arg_vars (register struct frame_info *fi,
     }
 
   b = SYMBOL_BLOCK_VALUE (func);
-  nsyms = BLOCK_NSYMS (b);
-
-  for (i = 0; i < nsyms; i++)
+  ALL_BLOCK_SYMBOLS (b, i, sym)
     {
-      sym = BLOCK_SYM (b, i);
       switch (SYMBOL_CLASS (sym))
        {
        case LOC_ARG:
@@ -1513,7 +1491,6 @@ print_frame_arg_vars (register struct frame_info *fi,
          break;
        }
     }
-
   if (!values_printed)
     {
       fprintf_filtered (stream, "No arguments.\n");
@@ -1537,18 +1514,27 @@ args_plus_locals_info (char *ignore, int from_tty)
 }
 \f
 
-/* Select frame FI, and note that its stack level is LEVEL.
-   LEVEL may be -1 if an actual level number is not known.  */
+/* Select frame FI (or NULL - to invalidate the current frame).  */
 
 void
-select_frame (struct frame_info *fi, int level)
+select_frame (struct frame_info *fi)
 {
   register struct symtab *s;
 
   selected_frame = fi;
-  selected_frame_level = level;
+  /* NOTE: cagney/2002-05-04: FI can be NULL.  This occures when the
+     frame is being invalidated.  */
   if (selected_frame_level_changed_hook)
-    selected_frame_level_changed_hook (level);
+    selected_frame_level_changed_hook (frame_relative_level (fi));
+
+  /* FIXME: kseitz/2002-08-28: It would be nice to call
+     selected_frame_level_changed_event right here, but due to limitations
+     in the current interfaces, we would end up flooding UIs with events
+     because select_frame is used extensively internally.
+
+     Once we have frame-parameterized frame (and frame-related) commands,
+     the event notification can be moved here, since this function will only
+     be called when the users selected frame is being changed. */
 
   /* Ensure that symbols for this frame are read in.  Also, determine the
      source language of this frame, and switch to it if desired.  */
@@ -1562,68 +1548,38 @@ select_frame (struct frame_info *fi, int level)
        {
          set_language (s->language);
        }
-      /* elz: this if here fixes the problem with the pc not being displayed
-         in the tui asm layout, with no debug symbols. The value of s 
-         would be 0 here, and select_source_symtab would abort the
-         command by calling the 'error' function */
-      if (s)
-       {
-         TUIDO (((TuiOpaqueFuncPtr) tui_vSelectSourceSymtab, s));
-       }
     }
 }
 \f
 
-/* Select frame FI, noting that its stack level is LEVEL.  Also print
-   the stack frame and show the source if this is the tui version.  */
-void
-select_and_print_frame (struct frame_info *fi, int level)
+/* Select frame FI.  Also print the stack frame and show the source if
+   this is the tui version.  */
+static void
+select_and_print_frame (struct frame_info *fi)
 {
-  select_frame (fi, level);
+  select_frame (fi);
   if (fi)
     {
-      print_stack_frame (fi, level, 1);
-      TUIDO (((TuiOpaqueFuncPtr) tui_vCheckDataValues, fi));
+      print_stack_frame (fi, frame_relative_level (fi), 1);
     }
 }
 \f
-
-/* Select frame FI, noting that its stack level is LEVEL.  Be silent if
-   not the TUI */
-#if 0
-void
-select_and_maybe_print_frame (struct frame_info *fi, int level)
-{
-  if (!tui_version)
-    select_frame (fi, level);
-  else
-    select_and_print_frame (fi, level);
-}
-#endif
-
-
-/* Store the selected frame and its level into *FRAMEP and *LEVELP.
-   If there is no selected frame, *FRAMEP is set to NULL.  */
-
-void
-record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
-{
-  *frameaddrp = selected_frame ? selected_frame->frame : 0;
-  *levelp = selected_frame_level;
-}
-
 /* Return the symbol-block in which the selected frame is executing.
-   Can return zero under various legitimate circumstances.  */
+   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.  */
 
 struct block *
-get_selected_block (void)
+get_selected_block (CORE_ADDR *addr_in_block)
 {
   if (!target_has_stack)
     return 0;
 
   if (!selected_frame)
-    return get_current_block ();
-  return get_frame_block (selected_frame);
+    return get_current_block (addr_in_block);
+  return get_frame_block (selected_frame, addr_in_block);
 }
 
 /* Find a frame a certain number of levels away from FRAME.
@@ -1674,39 +1630,26 @@ find_relative_frame (register struct frame_info *frame,
    frame expressions. */
 
 /* ARGSUSED */
-#ifdef UI_OUT
 void
 select_frame_command_wrapper (char *level_exp, int from_tty)
 {
   select_frame_command (level_exp, from_tty);
 }
-#endif
+
 static void
 select_frame_command (char *level_exp, int from_tty)
 {
-  register struct frame_info *frame, *frame1;
-  unsigned int level = 0;
+  struct frame_info *frame;
+  int level = frame_relative_level (selected_frame);
 
   if (!target_has_stack)
     error ("No stack.");
 
   frame = parse_frame_specification (level_exp);
 
-  /* Try to figure out what level this frame is.  But if there is
-     no current stack, don't error out -- let the user set one.  */
-  frame1 = 0;
-  if (get_current_frame ())
-    {
-      for (frame1 = get_prev_frame (0);
-          frame1 && frame1 != frame;
-          frame1 = get_prev_frame (frame1))
-       level++;
-    }
-
-  if (!frame1)
-    level = 0;
-
-  select_frame (frame, level);
+  select_frame (frame);
+  if (level != frame_relative_level (selected_frame))
+    selected_frame_level_changed_event (frame_relative_level (selected_frame));
 }
 
 /* The "frame" command.  With no arg, print selected frame briefly.
@@ -1717,7 +1660,8 @@ void
 frame_command (char *level_exp, int from_tty)
 {
   select_frame_command (level_exp, from_tty);
-  show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+  show_and_print_stack_frame (selected_frame,
+                             frame_relative_level (selected_frame), 1);
 }
 
 /* The XDB Compatibility command to print the current frame. */
@@ -1727,7 +1671,8 @@ current_frame_command (char *level_exp, int from_tty)
 {
   if (target_has_stack == 0 || selected_frame == 0)
     error ("No stack.");
-  print_only_stack_frame (selected_frame, selected_frame_level, 1);
+  print_only_stack_frame (selected_frame,
+                         frame_relative_level (selected_frame), 1);
 }
 
 /* Select the frame up one or COUNT stack levels
@@ -1740,7 +1685,7 @@ up_silently_base (char *count_exp)
   register struct frame_info *fi;
   int count = 1, count1;
   if (count_exp)
-    count = parse_and_eval_address (count_exp);
+    count = parse_and_eval_long (count_exp);
   count1 = count;
 
   if (target_has_stack == 0 || selected_frame == 0)
@@ -1749,22 +1694,22 @@ up_silently_base (char *count_exp)
   fi = find_relative_frame (selected_frame, &count1);
   if (count1 != 0 && count_exp == 0)
     error ("Initial frame selected; you cannot go up.");
-  select_frame (fi, selected_frame_level + count - count1);
+  select_frame (fi);
+  selected_frame_level_changed_event (frame_relative_level (selected_frame));
 }
 
 static void
 up_silently_command (char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
-  if (tui_version)
-    print_stack_frame (selected_frame, selected_frame_level, 1);
 }
 
 static void
 up_command (char *count_exp, int from_tty)
 {
   up_silently_base (count_exp);
-  show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+  show_and_print_stack_frame (selected_frame,
+                             frame_relative_level (selected_frame), 1);
 }
 
 /* Select the frame down one or COUNT stack levels
@@ -1777,7 +1722,7 @@ down_silently_base (char *count_exp)
   register struct frame_info *frame;
   int count = -1, count1;
   if (count_exp)
-    count = -parse_and_eval_address (count_exp);
+    count = -parse_and_eval_long (count_exp);
   count1 = count;
 
   if (target_has_stack == 0 || selected_frame == 0)
@@ -1795,7 +1740,8 @@ down_silently_base (char *count_exp)
       error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
     }
 
-  select_frame (frame, selected_frame_level + count - count1);
+  select_frame (frame);
+  selected_frame_level_changed_event (frame_relative_level (selected_frame));
 }
 
 /* ARGSUSED */
@@ -1803,32 +1749,24 @@ static void
 down_silently_command (char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
-  if (tui_version)
-    print_stack_frame (selected_frame, selected_frame_level, 1);
 }
 
 static void
 down_command (char *count_exp, int from_tty)
 {
   down_silently_base (count_exp);
-  show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
+  show_and_print_stack_frame (selected_frame,
+                             frame_relative_level (selected_frame), 1);
 }
 \f
-#ifdef UI_OUT
 void
-return_command_wrapper (char *retval_exp, int from_tty)
-{
-  return_command (retval_exp, from_tty);
-}
-#endif
-static 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;
-  value_ptr return_value = NULL;
+  struct value *return_value = NULL;
 
   if (selected_frame == NULL)
     error ("No selected frame.");
@@ -1892,6 +1830,12 @@ return_command (char *retval_exp, int from_tty)
   if (retval_exp)
     set_return_value (return_value);
 
+  /* If we are at the end of a call dummy now, pop the dummy frame too.  */
+
+  if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
+                               FRAME_FP (get_current_frame ())))
+    POP_FRAME;
+
   /* If interactive, print the frame that is now current.  */
 
   if (from_tty)
@@ -1953,12 +1897,12 @@ func_command (char *arg, int from_tty)
   while (!found && level == 0);
 
   if (func_bounds)
-    free (func_bounds);
+    xfree (func_bounds);
 
   if (!found)
     printf_filtered ("'%s' not within current stack frame.\n", arg);
   else if (fp != selected_frame)
-    select_and_print_frame (fp, level);
+    select_and_print_frame (fp);
 }
 
 /* Gets the language of the current frame.  */
This page took 0.034807 seconds and 4 git commands to generate.