aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-12-27 18:31:09 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2020-03-19 08:23:30 +0000
commit19a2740f7f2ea0f65745a3c00cf8a64647378aa3 (patch)
treed391f702c3054eb50db729a7936908ff2ef1b72d /gdb/symtab.c
parent724fd9ba432a20ef2e3f2c0d6060bff131226816 (diff)
downloadgdb-19a2740f7f2ea0f65745a3c00cf8a64647378aa3.zip
gdb-19a2740f7f2ea0f65745a3c00cf8a64647378aa3.tar.gz
gdb-19a2740f7f2ea0f65745a3c00cf8a64647378aa3.tar.bz2
gdb: Remove C++ symbol aliases from completion list
Consider debugging the following C++ program: struct object { int a; }; typedef object *object_p; static int get_value (object_p obj) { return obj->a; } int main () { object obj; obj.a = 0; return get_value (&obj); } Now in a GDB session: (gdb) complete break get_value break get_value(object*) break get_value(object_p) Or: (gdb) break get_va<TAB> (gdb) break get_value(object<RETURN> Function "get_value(object" not defined. Make breakpoint pending on future shared library load? (y or [n]) n The reason this happens is that we add completions based on the msymbol names and on the symbol names. For C++ both of these names include the parameter list, however, the msymbol names have some differences from the symbol names, for example: + typedefs are resolved, + whitespace rules are different around pointers, + the 'const' keyword is placed differently. What this means is that the msymbol names and symbol names appear to be completely different to GDB's completion tracker, and therefore to readline when it offers the completions. This commit builds on the previous commit which reworked the completion_tracker class. It is now trivial to add a remove_completion member function, this is then used along with cp_canonicalize_string_no_typedefs to remove the msymbol aliases from the completion tracker as we add the symbol names. Now, for the above program GDB only presents a single completion for 'get_value', which is 'get_value(object_p)'. It is still possible to reference the symbol using the msymbol name, so a user can manually type out 'break get_value (object *)' if they wish and will get the expected behaviour. I did consider adding an option to make this alias exclusion optional, in the end I didn't bother as I didn't think it would be very useful, but I can easily add such an option if people think it would be useful. gdb/ChangeLog: * 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. gdb/testsuite/ChangeLog: * gdb.linespec/cp-completion-aliases.cc: New file. * gdb.linespec/cp-completion-aliases.exp: New file. Change-Id: Ie5c7c9fc8ecf973072cfb4a9650867104bf7f50c
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c21
1 files changed, 21 insertions, 0 deletions
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. */