diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 25ef530a10..114a621212 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2017-12-13 Pedro Alves + + * completer.c (completion_tracker::maybe_add_completion): New + 'text' and 'word' parameters. Use make_completion_match_str. + (completion_tracker::add_completion): New 'text' and 'word' + parameters. Pass down. + (completion_tracker::recompute_lowest_common_denominator): Change + parameter type to gdb::unique_xmalloc_ptr rval ref. Adjust. + * completer.h (completion_tracker::add_completion): New 'text' and + 'word' parameters. + (completion_tracker::recompute_lowest_common_denominator): Change + parameter type to gdb::unique_xmalloc_ptr rval ref. + (completion_tracker::recompute_lowest_common_denominator): Change + parameter type to gdb::unique_xmalloc_ptr rval ref. + * symtab.c (completion_list_add_name): Pass down 'text' and 'word' + as well. + 2017-12-13 Pedro Alves * cli/cli-decode.c (complete_on_cmdlist, complete_on_enum): Use diff --git a/gdb/completer.c b/gdb/completer.c index 0195114486..844696fa03 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1510,7 +1510,8 @@ completion_tracker::~completion_tracker () bool completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr name, - completion_match_for_lcd *match_for_lcd) + completion_match_for_lcd *match_for_lcd, + const char *text, const char *word) { void **slot; @@ -1531,7 +1532,10 @@ completion_tracker::maybe_add_completion if (match_for_lcd_str == NULL) match_for_lcd_str = name.get (); - recompute_lowest_common_denominator (match_for_lcd_str); + gdb::unique_xmalloc_ptr lcd + = make_completion_match_str (match_for_lcd_str, text, word); + + recompute_lowest_common_denominator (std::move (lcd)); *slot = name.get (); m_entries_vec.push_back (std::move (name)); @@ -1544,9 +1548,10 @@ completion_tracker::maybe_add_completion void completion_tracker::add_completion (gdb::unique_xmalloc_ptr name, - completion_match_for_lcd *match_for_lcd) + completion_match_for_lcd *match_for_lcd, + const char *text, const char *word) { - if (!maybe_add_completion (std::move (name), match_for_lcd)) + if (!maybe_add_completion (std::move (name), match_for_lcd, text, word)) throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached.")); } @@ -1904,21 +1909,23 @@ completion_find_completion_word (completion_tracker &tracker, const char *text, /* See completer.h. */ void -completion_tracker::recompute_lowest_common_denominator (const char *new_match) +completion_tracker::recompute_lowest_common_denominator + (gdb::unique_xmalloc_ptr &&new_match_up) { if (m_lowest_common_denominator == NULL) { /* We don't have a lowest common denominator yet, so simply take - the whole NEW_MATCH as being it. */ - m_lowest_common_denominator = xstrdup (new_match); + the whole NEW_MATCH_UP as being it. */ + m_lowest_common_denominator = new_match_up.release (); m_lowest_common_denominator_unique = true; } else { /* Find the common denominator between the currently-known - lowest common denominator and NEW_MATCH. That becomes the + lowest common denominator and NEW_MATCH_UP. That becomes the new lowest common denominator. */ size_t i; + const char *new_match = new_match_up.get (); for (i = 0; (new_match[i] != '\0' diff --git a/gdb/completer.h b/gdb/completer.h index 73c0f4c783..df3c8e86de 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -319,7 +319,8 @@ public: it is not there already. If too many completions were already found, this throws an error. */ void add_completion (gdb::unique_xmalloc_ptr name, - completion_match_for_lcd *match_for_lcd = NULL); + completion_match_for_lcd *match_for_lcd = NULL, + const char *text = NULL, const char *word = NULL); /* Add all completions matches in LIST. Elements are moved out of LIST. */ @@ -406,7 +407,8 @@ private: it is not there already. If false is returned, too many completions were found. */ bool maybe_add_completion (gdb::unique_xmalloc_ptr name, - completion_match_for_lcd *match_for_lcd); + completion_match_for_lcd *match_for_lcd, + const char *text, const char *word); /* Given a new match, recompute the lowest common denominator (LCD) to hand over to readline. Normally readline computes this itself @@ -418,7 +420,8 @@ private: "std::vector<..>::push_back", "std::string::push_back", etc., and in this case we want the lowest common denominator to be "push_back" instead of "std::". */ - void recompute_lowest_common_denominator (const char *new_match); + void recompute_lowest_common_denominator + (gdb::unique_xmalloc_ptr &&new_match); /* Completion match outputs returned by the symbol name matching routines (see symbol_name_matcher_ftype). These results are only diff --git a/gdb/symtab.c b/gdb/symtab.c index bb98619a7c..220ae0969b 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4735,7 +4735,7 @@ completion_list_add_name (completion_tracker &tracker, in this case we want the completion lowest common denominator to be "push_back" instead of "std::". */ tracker.add_completion (std::move (completion), - &match_res.match_for_lcd); + &match_res.match_for_lcd, text, word); } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c4d8ecf35b..450ca3574f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2017-12-13 Pedro Alves + + * gdb.cp/cpcompletion.exp: Load completion-support.exp. + ("expression with namespace"): New set of tests. + * gdb.cp/pr9594.cc (Test_NS::foo, Test_NS::bar) + (Nested::Test_NS::qux): New. + * lib/completion-support.exp (test_gdb_complete_cmd_multiple): Add + defaults to 'start_quote_char' and 'end_quote_char' parameters. + 2017-12-13 Joel Brobecker * gdb.base/server-del-break.c: New file. diff --git a/gdb/testsuite/gdb.cp/cpcompletion.exp b/gdb/testsuite/gdb.cp/cpcompletion.exp index c7883ee376..62669dc0bd 100644 --- a/gdb/testsuite/gdb.cp/cpcompletion.exp +++ b/gdb/testsuite/gdb.cp/cpcompletion.exp @@ -15,6 +15,8 @@ # This file is part of the gdb testsuite. +load_lib completion-support.exp + # A helper procedure to test location completions restricted by # class. proc test_class_complete {class expr name matches} { @@ -85,3 +87,43 @@ gdb_test "complete p foo1.Fo" "p foo1\\.Foofoo" # Test completion with an anonymous struct. gdb_test "complete p a.g" "p a\\.get" + +with_test_prefix "expression with namespace" { + # Before the scope operator, GDB shows all the symbols whose + # fully-qualified name matches the completion word. + test_gdb_complete_multiple "p " "Test_NS" "" { + "Test_NS" + "Test_NS::Nested" + "Test_NS::Nested::qux" + "Test_NS::bar" + "Test_NS::foo" + } + + # Unlike in linespecs, tab- and complete-command completion work a + # bit differently when completing around the scope operator. The + # matches in the tab-completion case only show the part of the + # symbol after the scope, since ':' is a word break character. + + set tab_completion_list { + "Nested" + "Nested::qux" + "bar" + "foo" + } + test_gdb_complete_tab_multiple "p Test_NS:" ":" $tab_completion_list + test_gdb_complete_tab_multiple "p Test_NS::" "" $tab_completion_list + + # OTOH, the complete command must show the whole command, with + # qualified symbol displayed as entered by the user. + set cmd_completion_list { + "Test_NS::Nested" + "Test_NS::Nested::qux" + "Test_NS::bar" + "Test_NS::foo" + } + test_gdb_complete_cmd_multiple "p " "Test_NS:" $cmd_completion_list + test_gdb_complete_cmd_multiple "p " "Test_NS::" $cmd_completion_list + + # Add a disambiguating character and we get a unique completion. + test_gdb_complete_unique "p Test_NS::f" "p Test_NS::foo" +} diff --git a/gdb/testsuite/gdb.cp/pr9594.cc b/gdb/testsuite/gdb.cp/pr9594.cc index 8fdee84ae1..54ddaafc0c 100644 --- a/gdb/testsuite/gdb.cp/pr9594.cc +++ b/gdb/testsuite/gdb.cp/pr9594.cc @@ -39,6 +39,19 @@ void Foo::Foofoo () { } +namespace Test_NS { + +int foo; +int bar; + +namespace Nested { + +int qux; + +} /* namespace Nested */ + +} /* namespace Test_NS */ + int main () { // Anonymous struct with method. diff --git a/gdb/testsuite/lib/completion-support.exp b/gdb/testsuite/lib/completion-support.exp index c7cc1c9755..fe5b16a85b 100644 --- a/gdb/testsuite/lib/completion-support.exp +++ b/gdb/testsuite/lib/completion-support.exp @@ -178,7 +178,7 @@ proc test_gdb_complete_cmd_unique { input_line complete_line_re } { # complete command displays the COMPLETION_LIST completion list. Each # entry in the list should be prefixed by CMD_PREFIX. -proc test_gdb_complete_cmd_multiple { cmd_prefix completion_word completion_list start_quote_char end_quote_char } { +proc test_gdb_complete_cmd_multiple { cmd_prefix completion_word completion_list {start_quote_char ""} {end_quote_char ""} } { global gdb_prompt set expected_re [make_cmd_completion_list_re $cmd_prefix $completion_list $start_quote_char $end_quote_char]