diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/completer.c | 14 | ||||
-rw-r--r-- | gdb/completer.h | 4 | ||||
-rw-r--r-- | gdb/symtab.c | 21 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.linespec/cp-completion-aliases.cc | 73 | ||||
-rw-r--r-- | gdb/testsuite/gdb.linespec/cp-completion-aliases.exp | 54 |
7 files changed, 180 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bc927d4..1fe2e58 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2020-03-19 Andrew Burgess <andrew.burgess@embecosm.com> + * completer.c (completion_tracker::remove_completion): Define new + function. + * completer.h (completion_tracker::remove_completion): Declare new + function. + * symtab.c (completion_list_add_symbol): Remove aliasing msymbols + when adding a C++ function symbol. + +2020-03-19 Andrew Burgess <andrew.burgess@embecosm.com> + * completer.c (completion_tracker::completion_hash_entry): Define new class. (advance_to_filename_complete_word_point): Call diff --git a/gdb/completer.c b/gdb/completer.c index 14c7a57..67dce30 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1678,6 +1678,20 @@ completion_tracker::add_completions (completion_list &&list) add_completion (std::move (candidate)); } +/* See completer.h. */ + +void +completion_tracker::remove_completion (const char *name) +{ + hashval_t hash = htab_hash_string (name); + if (htab_find_slot_with_hash (m_entries_hash, name, hash, NO_INSERT) + != NULL) + { + htab_remove_elt_with_hash (m_entries_hash, name, hash); + m_lowest_common_denominator_valid = false; + } +} + /* Helper for the make_completion_match_str overloads. Returns NULL as an indication that we want MATCH_NAME exactly. It is up to the caller to xstrdup that string if desired. */ diff --git a/gdb/completer.h b/gdb/completer.h index 7bfe0d5..fd0d47b 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -326,6 +326,10 @@ public: LIST. */ void add_completions (completion_list &&list); + /* Remove completion matching NAME from the completion list, does nothing + if NAME is not already in the completion list. */ + void remove_completion (const char *name); + /* Set the quote char to be appended after a unique completion is added to the input line. Set to '\0' to clear. See m_quote_char's description. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index aa415a9..f300d75 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -5296,6 +5296,27 @@ completion_list_add_symbol (completion_tracker &tracker, completion_list_add_name (tracker, sym->language (), sym->natural_name (), lookup_name, text, word); + + /* C++ function symbols include the parameters within both the msymbol + name and the symbol name. The problem is that the msymbol name will + describe the parameters in the most basic way, with typedefs stripped + out, while the symbol name will represent the types as they appear in + the program. This means we will see duplicate entries in the + completion tracker. The following converts the symbol name back to + the msymbol name and removes the msymbol name from the completion + tracker. */ + if (sym->language () == language_cplus + && SYMBOL_DOMAIN (sym) == VAR_DOMAIN + && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + /* The call to canonicalize returns the empty string if the input + string is already in canonical form, thanks to this we don't + remove the symbol we just added above. */ + std::string str + = cp_canonicalize_string_no_typedefs (sym->natural_name ()); + if (!str.empty ()) + tracker.remove_completion (str.c_str ()); + } } /* completion_list_add_name wrapper for struct minimal_symbol. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0588fe6..6574270e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-19 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.linespec/cp-completion-aliases.cc: New file. + * gdb.linespec/cp-completion-aliases.exp: New file. + 2020-03-19 Tom de Vries <tdevries@suse.de> * gdb.opt/inline-locals.exp: Add kfail PR number. Make kfail matching diff --git a/gdb/testsuite/gdb.linespec/cp-completion-aliases.cc b/gdb/testsuite/gdb.linespec/cp-completion-aliases.cc new file mode 100644 index 0000000..5f2fb5c --- /dev/null +++ b/gdb/testsuite/gdb.linespec/cp-completion-aliases.cc @@ -0,0 +1,73 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2019-2020 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 <http://www.gnu.org/licenses/>. */ + +#include <cstring> + +template<typename T> +struct magic +{ + T x; +}; + +struct object +{ + int a; +}; + +typedef magic<int> int_magic_t; + +typedef object *object_p; + +typedef const char *my_string_t; + +static int +get_value (object_p obj) +{ + return obj->a; +} + +static int +get_something (object_p obj) +{ + return obj->a; +} + +static int +get_something (my_string_t msg) +{ + return strlen (msg); +} + +static int +grab_it (int_magic_t *var) +{ + return var->x; +} + +int +main () +{ + magic<int> m; + m.x = 4; + + object obj; + obj.a = 0; + + int val = (get_value (&obj) + get_something (&obj) + + get_something ("abc") + grab_it (&m)); + return val; +} diff --git a/gdb/testsuite/gdb.linespec/cp-completion-aliases.exp b/gdb/testsuite/gdb.linespec/cp-completion-aliases.exp new file mode 100644 index 0000000..313ff84 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/cp-completion-aliases.exp @@ -0,0 +1,54 @@ +# Copyright 2019-2020 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 <http://www.gnu.org/licenses/>. + +# This file tests GDB's ability to remove symbol aliases from the +# completion list in C++. + +load_lib completion-support.exp + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { + return -1 +} + +# Tests below are about tab-completion, which doesn't work if readline +# library isn't used. Check it first. + +if { ![readline_is_used] } { + untested "no tab completion support without readline" + return -1 +} + +# Disable the completion limit for the whole testcase. +gdb_test_no_output "set max-completions unlimited" + +test_gdb_complete_tab_unique "break get_v" \ + "break get_value\\(object_p\\)" " " + +test_gdb_complete_cmd_unique "break get_v" \ + "break get_value\\(object_p\\)" + +test_gdb_complete_tab_unique "break gr" \ + "break grab_it\\(int_magic_t\\*\\)" " " + +test_gdb_complete_cmd_unique "break gr" \ + "break grab_it\\(int_magic_t\\*\\)" + +test_gdb_complete_tab_multiple "break get_som" "ething(" \ + { "get_something(my_string_t)" "get_something(object_p)" } + +test_gdb_complete_cmd_multiple "break " "get_som" \ + { "get_something(my_string_t)" "get_something(object_p)" } |