aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/completer.c14
-rw-r--r--gdb/completer.h4
-rw-r--r--gdb/symtab.c21
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.linespec/cp-completion-aliases.cc73
-rw-r--r--gdb/testsuite/gdb.linespec/cp-completion-aliases.exp54
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)" }