2004-04-28 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / stack.c
index 74941f9401d858accb2d3568f609a21acd5a5dbf..ce1b7b18087a089fc8d7835dbd406ee022de3d85 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,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
-   Foundation, Inc.
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -52,7 +52,7 @@ void args_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);
 
@@ -95,9 +95,9 @@ static int print_block_frame_locals (struct block *,
                                     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);
 
 static void backtrace_command (char *, int);
@@ -120,42 +120,38 @@ int annotation_level = 0;
 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.  */
-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;
 
-  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);
   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
-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;
-  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);
 }  
@@ -418,7 +414,8 @@ print_args_stub (void *args)
    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;
@@ -430,14 +427,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");
 
-      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.  */
-      if (level >= 0)
+      if (print_level)
         {
           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))
         {
@@ -471,14 +470,14 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
      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)
-    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);
+  source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
 
   if (sal.symtab)
     set_current_source_symtab_and_line (&sal);
@@ -487,15 +486,16 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
     {
       struct symtab_and_line cursal;
       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 (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
@@ -522,7 +522,7 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
       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 ();
@@ -532,9 +532,9 @@ print_frame_info (struct frame_info *fi, int level, int source, int args)
 
 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;
@@ -622,19 +622,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");
 
-  if (level >= 0)
+  if (print_level)
     {
       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
-       || source == LOC_AND_ADDRESS)
+       || print_what == LOC_AND_ADDRESS)
       {
        annotate_frame_address ();
        ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi));
@@ -649,7 +651,7 @@ print_frame (struct frame_info *fi,
   annotate_frame_args ();
       
   ui_out_text (uiout, " (");
-  if (args)
+  if (print_args)
     {
       struct print_args_args args;
       struct cleanup *args_list_chain;
@@ -942,7 +944,8 @@ frame_info (char *addr_exp, int from_tty)
 
   {
     int frameless;
-    frameless = FRAMELESS_FUNCTION_INVOCATION (fi);
+    frameless = (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P ()
+                && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (fi));
     if (frameless)
       printf_filtered (" (FRAMELESS),");
   }
@@ -968,10 +971,6 @@ frame_info (char *addr_exp, int from_tty)
     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);
@@ -1223,7 +1222,7 @@ 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).  */
-      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);
     }
@@ -1356,7 +1355,7 @@ print_block_frame_labels (struct block *b, int *have_default,
 
   ALL_BLOCK_SYMBOLS (b, iter, sym)
     {
-      if (STREQ (DEPRECATED_SYMBOL_NAME (sym), "default"))
+      if (DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (sym), "default"))
        {
          if (*have_default)
            continue;
@@ -1609,9 +1608,7 @@ select_and_print_frame (struct frame_info *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.
@@ -1718,8 +1715,7 @@ void
 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 (), 1, SRC_AND_LOC);
 }
 
 /* The XDB Compatibility command to print the current frame. */
@@ -1729,8 +1725,7 @@ 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 (), 1, SRC_AND_LOC);
 }
 
 /* Select the frame up one or COUNT stack levels
@@ -1765,8 +1760,7 @@ static void
 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 (), 1, SRC_AND_LOC);
 }
 
 /* Select the frame down one or COUNT stack levels
@@ -1810,8 +1804,7 @@ static void
 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 (), 1, SRC_AND_LOC);
 }
 \f
 void
@@ -1847,6 +1840,7 @@ return_command (char *retval_exp, int from_tty)
        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);
 
       /* Make sure the value is fully evaluated.  It may live in the
@@ -1854,33 +1848,36 @@ return_command (char *retval_exp, int from_tty)
       if (VALUE_LAZY (return_value))
        value_fetch_lazy (return_value);
 
-      /* Check that this architecture can handle the function's return
-         type.  In the case of "struct convention", still do the
-         "return", just also warn the user.  */
-      if (gdbarch_return_value_p (current_gdbarch))
+      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 (gdbarch_return_value (current_gdbarch, return_type,
-                                   NULL, NULL, NULL)
-             == RETURN_VALUE_REGISTER_CONVENTION)
-           return_value = NULL;
+         /* 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
+      else if (using_struct_return (return_type, 0))
        {
-         /* NOTE: cagney/2003-10-20: The double check is to ensure
-            that the STORE_RETURN_VALUE call, further down, is not
-            applied to a struct or union return-value.  It wasn't
-            allowed previously, so don't start allowing it now.  An
-            ABI that uses "register convention" to return small
-            structures and should implement the "return_value"
-            architecture method.  */
-         if (using_struct_return (return_type, 0)
-             || TYPE_CODE (return_type) == TYPE_CODE_STRUCT
-             || TYPE_CODE (return_type) == TYPE_CODE_UNION)
-           return_value = NULL;
+         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;
        }
-      if (return_value == NULL)
-       query_prefix = "\
-The location at which to store the function's return value is unknown.\n";
     }
 
   /* Does an interactive user really want to do this?  Include
@@ -1930,32 +1927,25 @@ The location at which to store the function's return value is unknown.\n";
          STORE_RETURN_VALUE (return_type, current_regcache,
                              VALUE_CONTENTS (return_value));
        }
+      /* FIXME: cagney/2004-01-17: If extract_returned_value_address
+         is available and the function is using
+         RETURN_VALUE_STRUCT_CONVENTION, should use it to find the
+         address of the returned value so that it can be assigned.  */
       else
        {
          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,
-                               VALUE_CONTENTS (return_value), NULL);
+         gdbarch_return_value (current_gdbarch, return_type,
+                               current_regcache, NULL /*read*/,
+                               VALUE_CONTENTS (return_value) /*write*/);
        }
     }
 
   /* If we are at the end of a call dummy now, pop the dummy frame
      too.  */
-  /* NOTE: cagney/2003-01-18: Is this silly?  Instead of popping all
-     the frames in sequence, should this code just pop the dummy frame
-     directly?  */
-#ifdef DEPRECATED_CALL_DUMMY_HAS_COMPLETED
-  /* Since all up-to-date architectures return direct to the dummy
-     breakpoint address, a dummy frame has, by definition, always
-     completed.  Hence this method is no longer needed.  */
-  if (DEPRECATED_CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
-                                          get_frame_base (get_current_frame ())))
-    frame_pop (get_current_frame ());
-#else
   if (get_frame_type (get_current_frame ()) == DUMMY_FRAME)
     frame_pop (get_current_frame ());
-#endif
 
   /* If interactive, print the frame that is now current.  */
   if (from_tty)
@@ -2035,7 +2025,14 @@ get_frame_language (void)
 
   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
This page took 0.062852 seconds and 4 git commands to generate.