From patchwork Mon Oct 12 16:38:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 9058 Received: (qmail 22014 invoked by alias); 12 Oct 2015 16:38:42 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 22004 invoked by uid 89); 12 Oct 2015 16:38:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.0 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 12 Oct 2015 16:38:39 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id DDC7A279B8C0; Mon, 12 Oct 2015 18:38:36 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NqVg8rKX3aQh; Mon, 12 Oct 2015 18:38:36 +0200 (CEST) Received: from [10.10.1.112] (cacatoes.act-europe.fr [10.10.1.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id C7799279B833; Mon, 12 Oct 2015 18:38:36 +0200 (CEST) Subject: Re: [PATCH] [Ada] Enhance the menu to select function overloads with signatures To: Joel Brobecker References: <1441294498-11150-1-git-send-email-derodat@adacore.com> <20150923223006.GB10139@adacore.com> Cc: gdb-patches@sourceware.org From: Pierre-Marie de Rodat Message-ID: <561BE20C.7070804@adacore.com> Date: Mon, 12 Oct 2015 18:38:36 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20150923223006.GB10139@adacore.com> X-IsSubscribed: yes Joel, On 09/24/2015 12:30 AM, Joel Brobecker wrote: > This change looks good to me. I think the jury's still out on whether > people will prefer the new output or the old one (useful/time-saver > vs too much info making it hard to read). But we need to make the new > output the default for people to have a chance to try it and let us > know. So, all is good. Fine, thanks! Sorry for the late followup, got busy. :-) > Also, can you chat with AdaCore's IDE team to make sure this does > not cause any issue with them? I checked with them: this change is fine and integrates nicely with existing tools. > This change needs a documentation (gdb.texinfo) + NEWS update. > (the patch you sent is approved - but should wait for the doco > and NEWS to be approved as well, so they all go in together). Here's an updated patch that includes the gdb.texinfo + NEWS update. From ef849fd2f28dce38358d214243c9419ec322d3e7 Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Thu, 3 Sep 2015 17:34:58 +0200 Subject: [PATCH] Enhance the menu to select function overloads with signatures So far, trying to evaluate an expression involving a function call for which GDB could find multiple function candidates outputs a menu so that the user can select the one to run. For instance, with the two following functions: type New_Integer is new Integer; function F (I : Integer) return Boolean; function F (I : New_Integer) return Boolean; Then we get the following GDB session: (gdb) print f(1) Multiple matches for f [0] cancel [1] foo.f at foo.adb:23 [2] foo.f at foo.adb.28 > While the source location information is sufficient in order to determine which one to select, one has to look for them in source files, which is not convenient. This commit tunes this menu in order to also include the list of formal and return types (if any) in each entry. The above then becomes: (gdb) print f(1) Multiple matches for f [0] cancel [1] foo.f (integer) return boolean at foo.adb:23 [2] foo.f (foo.new_integer) return boolean at foo.adb.28 > Since this output is more verbose than previously, this change also introduces an option (set/show ada print-signatures) to get the original output. gdb/ChangeLog: * ada-lang.c (print_signatures): New. (ada_print_symbol_signature): New. (user_select_syms): Add signatures to the output of candidate symbols using ada_print_symbol_signature. (_initialize_ada_language): Add a "set/show ada print-signatures" boolean option. * NEWS: Create a post 7.10 section. Announce this enhancement and the corresponding new option. gdb/doc/ChangeLog: * gdb.texinfo (Ada Mode Into): Move overloading support description to its own node. (Overloading support for Ada): New node. (Ada Set Commands): Document the new option "ada print-signatures". gdb/testsuite/ChangeLog: * gdb.ada/fun_overload_menu.exp: New testcase. * gdb.ada/fun_overload_menu/foo.adb: New testcase. Tested on x86_64-linux, no regression. --- gdb/NEWS | 12 +++ gdb/ada-lang.c | 103 ++++++++++++++++++------ gdb/doc/gdb.texinfo | 50 ++++++++++-- gdb/testsuite/gdb.ada/fun_overload_menu.exp | 71 ++++++++++++++++ gdb/testsuite/gdb.ada/fun_overload_menu/foo.adb | 47 +++++++++++ 5 files changed, 253 insertions(+), 30 deletions(-) create mode 100644 gdb/testsuite/gdb.ada/fun_overload_menu.exp create mode 100644 gdb/testsuite/gdb.ada/fun_overload_menu/foo.adb diff --git a/gdb/NEWS b/gdb/NEWS index 5689def..49723ad 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -1,6 +1,18 @@ What has changed in GDB? (Organized release by release) +*** Changes since GDB 7.10 + +* In Ada, the overloading selection menu has been enhance to display the + parameter types and the return types for the matching overloaded subprograms. + +* New options + +set ada print-signatures on|off +show ada print-signatures" + Control whether parameter types and return types are displayed in overloading + selection menus. It is activaled (@code{on}) by default. + *** Changes in GDB 7.10 * Support for process record-replay and reverse debugging on aarch64*-linux* diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 3350d93..7e30c07 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -3879,6 +3879,49 @@ sort_choices (struct block_symbol syms[], int nsyms) } } +/* Whether GDB should display formals and return types for functions in the + overloads selection menu. */ +static int print_signatures = 1; + +/* Print the signature for SYM on STREAM according to the FLAGS options. For + all but functions, the signature is just the name of the symbol. For + functions, this is the name of the function, the list of types for formals + and the return type (if any). */ + +static void +ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym, + const struct type_print_options *flags) +{ + struct type *type = SYMBOL_TYPE (sym); + + fprintf_filtered (stream, "%s", SYMBOL_PRINT_NAME (sym)); + if (!print_signatures + || type == NULL + || TYPE_CODE (type) != TYPE_CODE_FUNC) + return; + + if (TYPE_NFIELDS (type) > 0) + { + int i; + + fprintf_filtered (stream, " ("); + for (i = 0; i < TYPE_NFIELDS (type); ++i) + { + if (i > 0) + fprintf_filtered (stream, "; "); + ada_print_type (TYPE_FIELD_TYPE (type, i), NULL, stream, -1, 0, + flags); + } + fprintf_filtered (stream, ")"); + } + if (TYPE_TARGET_TYPE (type) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + { + fprintf_filtered (stream, " return "); + ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags); + } +} + /* Given a list of NSYMS symbols in SYMS, select up to MAX_RESULTS>0 by asking the user (if necessary), returning the number selected, and setting the first elements of SYMS items. Error if no symbols @@ -3928,14 +3971,14 @@ See set/show multiple-symbol.")); struct symtab_and_line sal = find_function_start_sal (syms[i].symbol, 1); + printf_unfiltered ("[%d] ", i + first_choice); + ada_print_symbol_signature (gdb_stdout, syms[i].symbol, + &type_print_raw_options); if (sal.symtab == NULL) - printf_unfiltered (_("[%d] %s at :%d\n"), - i + first_choice, - SYMBOL_PRINT_NAME (syms[i].symbol), + printf_unfiltered (_(" at :%d\n"), sal.line); else - printf_unfiltered (_("[%d] %s at %s:%d\n"), i + first_choice, - SYMBOL_PRINT_NAME (syms[i].symbol), + printf_unfiltered (_(" at %s:%d\n"), symtab_to_filename_for_display (sal.symtab), sal.line); continue; @@ -3952,11 +3995,14 @@ See set/show multiple-symbol.")); symtab = symbol_symtab (syms[i].symbol); if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL) - printf_unfiltered (_("[%d] %s at %s:%d\n"), - i + first_choice, - SYMBOL_PRINT_NAME (syms[i].symbol), - symtab_to_filename_for_display (symtab), - SYMBOL_LINE (syms[i].symbol)); + { + printf_unfiltered ("[%d] ", i + first_choice); + ada_print_symbol_signature (gdb_stdout, syms[i].symbol, + &type_print_raw_options); + printf_unfiltered (_(" at %s:%d\n"), + symtab_to_filename_for_display (symtab), + SYMBOL_LINE (syms[i].symbol)); + } else if (is_enumeral && TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL) { @@ -3966,19 +4012,22 @@ See set/show multiple-symbol.")); printf_unfiltered (_("'(%s) (enumeral)\n"), SYMBOL_PRINT_NAME (syms[i].symbol)); } - else if (symtab != NULL) - printf_unfiltered (is_enumeral - ? _("[%d] %s in %s (enumeral)\n") - : _("[%d] %s at %s:?\n"), - i + first_choice, - SYMBOL_PRINT_NAME (syms[i].symbol), - symtab_to_filename_for_display (symtab)); - else - printf_unfiltered (is_enumeral - ? _("[%d] %s (enumeral)\n") - : _("[%d] %s at ?\n"), - i + first_choice, - SYMBOL_PRINT_NAME (syms[i].symbol)); + else + { + printf_unfiltered ("[%d] ", i + first_choice); + ada_print_symbol_signature (gdb_stdout, syms[i].symbol, + &type_print_raw_options); + + if (symtab != NULL) + printf_unfiltered (is_enumeral + ? _(" in %s (enumeral)\n") + : _(" at %s:?\n"), + symtab_to_filename_for_display (symtab)); + else + printf_unfiltered (is_enumeral + ? _(" (enumeral)\n") + : _(" at ?\n")); + } } } @@ -14476,6 +14525,14 @@ this incurs a slight performance penalty, so it is recommended to NOT change\n\ this option to \"off\" unless necessary."), NULL, NULL, &set_ada_list, &show_ada_list); + add_setshow_boolean_cmd ("print-signatures", class_vars, + &print_signatures, _("\ +Enable or disable the output of formal and return types for functions in the \ +overloads selection menu"), _("\ +Show whether the output of formal and return types for functions in the \ +overloads selection menu is activated"), + NULL, NULL, NULL, &set_ada_list, &show_ada_list); + add_catch_command ("exception", _("\ Catch Ada exceptions, when raised.\n\ With an argument, catch only exceptions with the given name."), diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d382da4..500744b 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -15445,6 +15445,8 @@ to be difficult. in @value{GDBN}. * Omissions from Ada:: Restrictions on the Ada expression syntax. * Additions to Ada:: Extensions of the Ada expression syntax. +* Overloading support for Ada:: Support for expressions involving overloaded + subprograms. * Stopping Before Main Program:: Debugging the program during elaboration. * Ada Exceptions:: Ada Exceptions * Ada Tasks:: Listing and setting breakpoints in tasks. @@ -15494,13 +15496,6 @@ mostly for documenting command files. The standard @value{GDBN} comment (@samp{#}) still works at the beginning of a line in Ada mode, but not in the middle (to allow based literals). -The debugger supports limited overloading. Given a subprogram call in which -the function symbol has multiple definitions, it will use the number of -actual parameters and some information about their types to attempt to narrow -the set of definitions. It also makes very limited use of context, preferring -procedures to functions in the context of the @code{call} command, and -functions to procedures elsewhere. - @node Omissions from Ada @subsubsection Omissions from Ada @cindex Ada, omissions from @@ -15761,6 +15756,35 @@ object. @end itemize +@node Overloading support for Ada +@subsubsection Overloading support for Ada +@cindex Ada, overloading + +The debugger supports limited overloading. Given a subprogram call in which +the function symbol has multiple definitions, it will use the number of +actual parameters and some information about their types to attempt to narrow +the set of definitions. It also makes very limited use of context, preferring +procedures to functions in the context of the @code{call} command, and +functions to procedures elsewhere. + +If, after narrowing, the set of matching definitions still contains more than +one definition, GDB will display a menu to query which one it should use, for +instance: + +@smallexample +(@value{GDBP}) print f(1) +Multiple matches for f +[0] cancel +[1] foo.f (integer) return boolean at foo.adb:23 +[2] foo.f (foo.new_integer) return boolean at foo.adb.28 +> +@end smallexample + +In this case, just select one menu entry either to cancel expression evaluation +(type @code{0} and press @code{ENTER}) or to continue evaluation with a +specific overloaded entity (type the corresponding number and press +@code{ENTER}). + @node Stopping Before Main Program @subsubsection Stopping at the Very Beginning @@ -16177,6 +16201,18 @@ bounds on @var{A}, as long as the component size is less than @var{size}. @kindex show varsize-limit @item show varsize-limit Show the limit on types whose size is determined by run-time quantities. + +@kindex set ada print-signatures +@item set ada print-signatures +Control whether parameter types and return types are displayed in overloading +selection menus. It is activaled (@code{on}) by default. +@pxref{Overloading support for Ada} + +@kindex show ada print-signatures +@item show ada print-signatures +Show the current setting for displaying parameter types and return types in +overloading selection menu. +@pxref{Overloading support for Ada} @end table @node Ada Glitches diff --git a/gdb/testsuite/gdb.ada/fun_overload_menu.exp b/gdb/testsuite/gdb.ada/fun_overload_menu.exp new file mode 100644 index 0000000..5a1c37a --- /dev/null +++ b/gdb/testsuite/gdb.ada/fun_overload_menu.exp @@ -0,0 +1,71 @@ +# Copyright 2015 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "ada.exp" + +standard_ada_testfile foo + +if {[gdb_compile_ada "$srcfile" "$binfile" executable [list debug]] != "" } { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "BREAK" ${testdir}/foo.adb] +runto "foo.adb:$bp_location" + + +proc test_menu {expr function menu_entries selection output} { + set menu [multi_line "Multiple matches for $function" \ + "\\\[0\\\] cancel" \ + "$menu_entries" \ + "> $"] + set test_name "multiple matches for $function ($expr)" + gdb_test_multiple "print $expr" "$test_name" \ + { + -re "$menu" { + pass "$test_name" + } + default { + fail "$test_name" + } + } + gdb_test "$selection" "$output" +} + + +# Check that function signatures in overload menus are displayed as expected. + +# 1. Test with overloaded functions +test_menu "f (1, null)" "f" \ + [multi_line \ + "\\\[1\\\] foo\.f \\(integer; foo\.integer_access\\) return boolean at .*foo.adb:.*" \ + "\\\[2\\\] foo\.f \\(foo\.new_integer; foo\.integer_access\\) return boolean at .*foo.adb:.*"] \ + "1" "= true" + +# 2. Test with overloaded procedures +test_menu "p (1, null)" "p" \ + [multi_line \ + "\\\[1\\\] foo\.p \\(integer; foo\.integer_access\\) at .*foo.adb:.*" \ + "\\\[2\\\] foo\.p \\(foo\.new_integer; foo\.integer_access\\) at .*foo.adb:.*" ] \ + "1" "= (void)" + +# 3. Test with signatures disabled +gdb_test "set ada print-signatures off" "" +test_menu "f (1, null)" "f" \ + [multi_line \ + "\\\[1\\\] foo\.f at .*foo.adb:.*" \ + "\\\[2\\\] foo\.f at .*foo.adb:.*"] \ + "1" "= true" diff --git a/gdb/testsuite/gdb.ada/fun_overload_menu/foo.adb b/gdb/testsuite/gdb.ada/fun_overload_menu/foo.adb new file mode 100644 index 0000000..75009ae --- /dev/null +++ b/gdb/testsuite/gdb.ada/fun_overload_menu/foo.adb @@ -0,0 +1,47 @@ +-- Copyright 2015 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +procedure Foo is + + type New_Integer is new Integer; + type Integer_Access is access Integer; + + function F (I : Integer; A : Integer_Access) return Boolean is + begin + return True; + end F; + + function F (I : New_Integer; A : Integer_Access) return Boolean is + begin + return False; + end F; + + procedure P (I : Integer; A : Integer_Access) is + begin + null; + end P; + + procedure P (I : New_Integer; A : Integer_Access) is + begin + null; + end P; + + B1 : constant Boolean := F (Integer'(1), null); -- BREAK + B2 : constant Boolean := F (New_Integer'(2), null); + +begin + P (Integer'(3), null); + P (New_Integer'(4), null); +end Foo; -- 2.6.0