From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2139 invoked by alias); 1 Aug 2008 19:15:21 -0000 Received: (qmail 2127 invoked by uid 22791); 1 Aug 2008 19:15:20 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 01 Aug 2008 19:14:54 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m71JEqOI004978 for ; Fri, 1 Aug 2008 15:14:52 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m71JEpWK026686; Fri, 1 Aug 2008 15:14:51 -0400 Received: from opsy.redhat.com (vpn-10-95.bos.redhat.com [10.16.10.95]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m71JEoYn027480; Fri, 1 Aug 2008 15:14:51 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 2BEC58880A6; Fri, 1 Aug 2008 13:14:50 -0600 (MDT) To: gdb-patches@sourceware.org Subject: RFA: fix PR gdb/2489 From: Tom Tromey Reply-To: tromey@redhat.com X-Attribution: Tom Date: Fri, 01 Aug 2008 19:15:00 -0000 Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-08/txt/msg00016.txt.bz2 This patch fixes PR gdb/2489. The bug is that field name completion does not consider methods. The fix is to also examine method names when completing; but not to consider constructor names. Built and regression tested on x86-64 (compile farm). New test case included. Ok? Tom b/gdb/ChangeLog: 2008-08-01 Tom Tromey PR gdb/2489: * completer.c (count_struct_fields): Count method names. (add_struct_fields): Add matching method names. b/gdb/testsuite/ChangeLog: 2008-08-01 Tom Tromey * gdb.cp/pr2489.cc: New file. * gdb.cp/cpcompletion.exp: New file. diff --git a/gdb/completer.c b/gdb/completer.c index e7ee817..e42d8a3 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -339,7 +339,7 @@ location_completer (char *text, char *word) } /* Helper for expression_completer which recursively counts the number - of named fields in a structure or union type. */ + of named fields and methods in a structure or union type. */ static int count_struct_fields (struct type *type) { @@ -353,17 +353,25 @@ count_struct_fields (struct type *type) else if (TYPE_FIELD_NAME (type, i)) ++result; } + + for (i = TYPE_NFN_FIELDS (type) - 1; i >=0; --i) + { + if (TYPE_FN_FIELDLIST_NAME (type, i)) + ++result; + } + return result; } -/* Helper for expression_completer which recursively adds field names - from TYPE, a struct or union type, to the array OUTPUT. This - function assumes that OUTPUT is correctly-sized. */ +/* Helper for expression_completer which recursively adds field and + method names from TYPE, a struct or union type, to the array + OUTPUT. This function assumes that OUTPUT is correctly-sized. */ static void add_struct_fields (struct type *type, int *nextp, char **output, char *fieldname, int namelen) { int i; + char *type_name = NULL; CHECK_TYPEDEF (type); for (i = 0; i < TYPE_NFIELDS (type); ++i) @@ -378,6 +386,22 @@ add_struct_fields (struct type *type, int *nextp, char **output, ++*nextp; } } + + for (i = TYPE_NFN_FIELDS (type) - 1; i >=0; --i) + { + char *name = TYPE_FN_FIELDLIST_NAME (type, i); + if (name && ! strncmp (name, fieldname, namelen)) + { + if (!type_name) + type_name = type_name_no_tag (type); + /* Omit constructors from the completion list. */ + if (strcmp (type_name, name)) + { + output[*nextp] = xstrdup (name); + ++*nextp; + } + } + } } /* Complete on expressions. Often this means completing on symbol diff --git a/gdb/testsuite/gdb.cp/cpcompletion.exp b/gdb/testsuite/gdb.cp/cpcompletion.exp new file mode 100644 index 0000000..1f9caa6 --- /dev/null +++ b/gdb/testsuite/gdb.cp/cpcompletion.exp @@ -0,0 +1,78 @@ +# Copyright 2008 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 . + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file is part of the gdb testsuite. + +if $tracelevel then { + strace $tracelevel +} + +if { [skip_cplus_tests] } { continue } + +set testfile pr2489 +set binfile ${objdir}/${subdir}/${testfile} + +if {[gdb_compile "${srcdir}/${subdir}/${testfile}.cc" "${testfile}.o" object {c++ debug}] != ""} { + untested completion.exp + return -1 +} + +if {[gdb_compile "${testfile}.o" ${binfile} executable {c++ debug}] != "" } { + untested completion.exp + return -1 +} + +gdb_exit + +# Don't let a .inputrc file or an existing setting of INPUTRC mess up +# the test results. Even if /dev/null doesn't exist on the particular +# platform, the readline library will use the default setting just by +# failing to open the file. OTOH, opening /dev/null successfully will +# also result in the default settings being used since nothing will be +# read from this file. +global env +if [info exists env(INPUTRC)] { + set old_inputrc $env(INPUTRC) +} +set env(INPUTRC) "/dev/null" + +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set bp_location [gdb_get_line_number "Set breakpoint here" ${testfile}.cc] + +if {![runto $bp_location]} { + perror "test suppressed" +} + +send_gdb "p foo1.g\t" +gdb_expect { + -re "^p foo1\\.get_foo $"\ + { send_gdb "()\n" + gdb_expect { + -re "^.* = 0.*$gdb_prompt $"\ + { pass "complete 'p foo1.g'"} + -re ".*$gdb_prompt $" { fail "complete 'p foo1.g'"} + timeout {fail "(timeout) complete 'p foo1.g'"} + } + } + -re ".*$gdb_prompt $" { fail "complete 'p foo1.g'" } + timeout { fail "(timeout) complete 'p foo1.g' 2" } + } + diff --git a/gdb/testsuite/gdb.cp/pr2489.cc b/gdb/testsuite/gdb.cp/pr2489.cc new file mode 100644 index 0000000..f735205 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr2489.cc @@ -0,0 +1,34 @@ + +class Foo +{ + +private: + int foo_value; + +public: + Foo () { foo_value = 0;} + Foo (int i) { foo_value = i;} + ~Foo () { } + void set_foo (int value); + int get_foo (); + + bool operator== (const Foo &other) { return foo_value == other.foo_value; } +}; + +void Foo::set_foo (int value) +{ + foo_value = value; +} + +int Foo::get_foo () +{ + return foo_value; +} + +int main () +{ + Foo foo1; + foo1.set_foo (42); // Set breakpoint here. + return 0; +} +