--- ../../cvs/src/gdb/infcmd.c 2004-06-28 23:39:06.000000000 -0700 +++ ./infcmd.c 2004-07-12 15:45:51.000000000 -0700 @@ -64,7 +64,7 @@ static void nofp_registers_info (char *, int); -static void print_return_value (int struct_return, struct type *value_type); +static void print_return_value (struct type *value_type, struct value *value); static void finish_command_continuation (struct continuation_arg *); @@ -1075,41 +1075,18 @@ /* Print the result of a function at the end of a 'finish' command. */ static void -print_return_value (int struct_return, struct type *value_type) +print_return_value (struct type *value_type, struct value *value) { - struct gdbarch *gdbarch = current_gdbarch; struct cleanup *old_chain; struct ui_stream *stb; - struct value *value; gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID); - /* FIXME: 2003-09-27: When returning from a nested inferior function - call, it's possible (with no help from the architecture vector) - to locate and return/print a "struct return" value. This is just - a more complicated case of what is already being done in in the - inferior function call code. In fact, when inferior function - calls are made async, this will likely be made the norm. */ - - switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL)) - { - case RETURN_VALUE_REGISTER_CONVENTION: - case RETURN_VALUE_ABI_RETURNS_ADDRESS: - value = allocate_value (value_type); - CHECK_TYPEDEF (value_type); - gdbarch_return_value (current_gdbarch, value_type, stop_registers, - VALUE_CONTENTS_RAW (value), NULL); - break; - case RETURN_VALUE_STRUCT_CONVENTION: - value = NULL; - break; - default: - internal_error (__FILE__, __LINE__, "bad switch"); - } - if (value) { /* Print it. */ + gdbarch_return_value (current_gdbarch, value_type, stop_registers, + value, NULL); stb = ui_out_stream_new (uiout); old_chain = make_cleanup_ui_out_stream_delete (stb); ui_out_text (uiout, "Value returned is "); @@ -1142,39 +1119,19 @@ static void finish_command_continuation (struct continuation_arg *arg) { - struct symbol *function; struct breakpoint *breakpoint; struct cleanup *cleanups; + struct type *value_type; + struct value *value; breakpoint = (struct breakpoint *) arg->data.pointer; - function = (struct symbol *) arg->next->data.pointer; + value_type = (struct type *) arg->next->data.pointer; cleanups = (struct cleanup *) arg->next->next->data.pointer; + value = (struct value *) arg->next->next->next->data.pointer; if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != NULL) - { - struct type *value_type; - int struct_return; - int gcc_compiled; - - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); - if (!value_type) - internal_error (__FILE__, __LINE__, - "finish_command: function has no target type"); - - if (TYPE_CODE (value_type) == TYPE_CODE_VOID) - { - do_exec_cleanups (cleanups); - return; - } - - CHECK_TYPEDEF (value_type); - gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)); - struct_return = using_struct_return (value_type, gcc_compiled); - - print_return_value (struct_return, value_type); - } - + && value_type != NULL && TYPE_CODE (value_type) != TYPE_CODE_VOID) + print_return_value (value_type, value); do_exec_cleanups (cleanups); } @@ -1184,13 +1141,16 @@ static void finish_command (char *arg, int from_tty) { + struct gdbarch *gdbarch = current_gdbarch; struct symtab_and_line sal; struct frame_info *frame; struct symbol *function; struct breakpoint *breakpoint; struct cleanup *old_chain; - struct continuation_arg *arg1, *arg2, *arg3; + struct continuation_arg *arg1, *arg2, *arg3, *arg4; + struct type *value_type = NULL; + struct value *value = NULL; int async_exec = 0; /* Find out whether we must run in the background. */ @@ -1237,6 +1197,38 @@ function = find_pc_function (get_frame_pc (deprecated_selected_frame)); + if (function != NULL) + { + value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); + if (!value_type) + internal_error (__FILE__, __LINE__, + "finish_command: function has no target type"); + + /* FIXME: 2003-09-27: When returning from a nested inferior function + call, it's possible (with no help from the architecture vector) + to locate and return/print a "struct return" value. This is just + a more complicated case of what is already being done in in the + inferior function call code. In fact, when inferior function + calls are made async, this will likely be made the norm. */ + + switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL)) + { + case RETURN_VALUE_REGISTER_CONVENTION: + case RETURN_VALUE_ABI_RETURNS_ADDRESS: + value = allocate_value (value_type); + CHECK_TYPEDEF (value_type); + gdbarch_setup_return_value (gdbarch, deprecated_selected_frame, + value_type, value); + VALUE_FRAME_REGNUM(value) = 4; + break; + case RETURN_VALUE_STRUCT_CONVENTION: + value = NULL; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + } + /* Print info on the selected frame, including level number but not source. */ if (from_tty) @@ -1257,12 +1249,16 @@ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg3 = (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); + arg4 = + (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg1->next = arg2; arg2->next = arg3; - arg3->next = NULL; + arg3->next = arg4; + arg4->next = NULL; arg1->data.pointer = breakpoint; - arg2->data.pointer = function; + arg2->data.pointer = value_type; arg3->data.pointer = old_chain; + arg4->data.pointer = value; add_continuation (finish_command_continuation, arg1); } @@ -1276,27 +1272,8 @@ { /* Did we stop at our breakpoint? */ if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != NULL) - { - struct type *value_type; - int struct_return; - int gcc_compiled; - - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); - if (!value_type) - internal_error (__FILE__, __LINE__, - "finish_command: function has no target type"); - - /* FIXME: Shouldn't we do the cleanups before returning? */ - if (TYPE_CODE (value_type) == TYPE_CODE_VOID) - return; - - CHECK_TYPEDEF (value_type); - gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)); - struct_return = using_struct_return (value_type, gcc_compiled); - - print_return_value (struct_return, value_type); - } + && value_type != NULL && TYPE_CODE (value_type) != TYPE_CODE_VOID) + print_return_value (value_type, value); do_cleanups (old_chain); }