* frame.h (selected_frame_level): Document as deprecated.
[deliverable/binutils-gdb.git] / gdb / stack.c
index f2536aa3195884d206d492fda22938c994a2a973..7a8bbc22146d6f15f1bb3152e9fb03e82d83b4fb 100644 (file)
@@ -1,6 +1,8 @@
 /* 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 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.
 
@@ -35,9 +37,7 @@
 #include "demangle.h"
 #include "inferior.h"
 #include "annotate.h"
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
 
 /* Prototypes for exported functions. */
 
@@ -108,7 +108,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.
@@ -120,7 +119,22 @@ 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;
+/* FIXME: cagney/2002-04-21: The variable `selected_frame_level' is
+   deprecated.  It will dissapear `real soon now'.  */
+
+int selected_frame_level; /* DEPRECATED */
+
+/* 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
@@ -400,20 +414,29 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
                                     fi->pc);
       if (!done)
        {
-         if (addressprint && mid_statement)
+         if (print_frame_info_listing_hook)
            {
-#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
+             print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
+             current_source_symtab = sal.symtab;
            }
-         if (print_frame_info_listing_hook)
-           print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
          else
-           print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+           {
+             /* 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);
     }
@@ -436,14 +459,12 @@ 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);
   if (func)
@@ -522,82 +543,49 @@ print_frame (struct frame_info *fi,
 
   annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
 
-#ifdef UI_OUT
   list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
-#endif
 
   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
     }
   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;
-#ifdef UI_OUT
       struct cleanup *args_list_chain;
-#endif
       args.fi = fi;
       args.func = func;
       args.stream = gdb_stdout;
-#ifdef UI_OUT
       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.  */
       /* Invoke ui_out_tuple_end.  */
       do_cleanups (args_list_chain);
-#else
-      catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
-#endif
       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 ();
@@ -606,16 +594,6 @@ 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 ();
     }
 
@@ -626,26 +604,17 @@ 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
   /* 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
 
@@ -696,12 +665,12 @@ parse_frame_specification (char *frame_exp)
          addr_string = savestring (frame_exp, p - frame_exp);
 
          {
-           value_ptr vp;
+           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_pointer rather than calling
+              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.  */
@@ -709,7 +678,7 @@ parse_frame_specification (char *frame_exp)
            if (numargs == 0)
              level = value_as_long (vp);
 
-           args[numargs++] = value_as_pointer (vp);
+           args[numargs++] = value_as_address (vp);
            do_cleanups (tmp_cleanup);
          }
 
@@ -750,7 +719,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
@@ -863,9 +832,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");
     }
@@ -1284,7 +1254,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)
@@ -1318,7 +1288,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;
@@ -1503,7 +1473,42 @@ select_frame (struct frame_info *fi, int level)
   register struct symtab *s;
 
   selected_frame = fi;
-  selected_frame_level = level;
+  /* FIXME: cagney/2002-04-21: The variable `selected_frame_level' is
+     deprecated.  It will dissapear `real soon now'.  */
+  selected_frame_level = level; /* DEPRECATED */
+  /* FIXME: cagney/2002-04-05: It can't be this easy (and looking at
+     the increasingly complex list of checkes, it wasn't)!  GDB is
+     dragging around, and constantly updating, the global variable
+     selected_frame_level.  Surely all that was needed was for the
+     level to be computed direct from the frame (by counting back to
+     the inner-most frame) or, as has been done here using a cached
+     value.  For moment, check that the expected and the actual level
+     are consistent.  If, after a few weeks, no one reports that this
+     assertion has failed, the global selected_frame_level and many
+     many parameters can all be deleted.  */
+  if (fi == NULL && level == -1)
+    /* Ok.  The target is clearing the selected frame as part of a
+       cache flush.  */
+    ;
+  else if (fi != NULL && fi->level == level)
+    /* Ok.  What you would expect.  Level is redundant.  */
+    ;
+  else if (fi != NULL && level == -1)
+    /* Ok.  See breakpoint.c.  The watchpoint code changes the
+       selected frame to the frame that contains the watchpoint and
+       then, later changes it back to the old value.  The -1 is used
+       as a marker so that the watchpoint code can easily detect that
+       things are not what they should be.  Why the watchpoint code
+       can't mindlessly save/restore the selected frame I don't know,
+       hopefully it can be simplified that way.  Hopefully the global
+       selected_frame can be replaced by a frame parameter, making
+       still more simplification possible.  */
+    ;
+  else
+    internal_error (__FILE__, __LINE__,
+                   "Conflicting frame levels fi->level=%d, level=%d",
+                   (fi ? fi->level : -1),
+                   level);
   if (selected_frame_level_changed_hook)
     selected_frame_level_changed_hook (level);
 
@@ -1543,21 +1548,25 @@ void
 record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
 {
   *frameaddrp = selected_frame ? selected_frame->frame : 0;
-  *levelp = selected_frame_level;
+  *levelp = frame_relative_level (selected_frame);
 }
 
 /* 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.
@@ -1608,13 +1617,12 @@ 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)
 {
@@ -1651,7 +1659,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. */
@@ -1661,7 +1670,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
@@ -1683,7 +1693,7 @@ 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, frame_relative_level (selected_frame) + count - count1);
 }
 
 static void
@@ -1696,7 +1706,8 @@ 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
@@ -1727,7 +1738,7 @@ 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, frame_relative_level (selected_frame) + count - count1);
 }
 
 /* ARGSUSED */
@@ -1741,16 +1752,16 @@ 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)
 {
@@ -1758,7 +1769,7 @@ return_command (char *retval_exp, int from_tty)
   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.");
This page took 0.029654 seconds and 4 git commands to generate.