summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.linespec
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-11-29 19:33:23 +0000
committerPedro Alves <palves@redhat.com>2017-11-29 19:43:48 +0000
commita20714ff39f621961151d0c204e89062ab2107eb (patch)
tree6a04775e3cd8c3f617986bb98abc2d3df77f54df /gdb/testsuite/gdb.linespec
parenta207cff2da9f154e4f581b19dcde215593bfccf9 (diff)
Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
This patch teaches GDB about setting breakpoints in all scopes (namespaces and classes) by default. Here's a contrived example: (gdb) b func<tab> (anonymous namespace)::A::function() Bn::(anonymous namespace)::B::function() function(int, int) (anonymous namespace)::B::function() Bn::(anonymous namespace)::function() gdb::(anonymous namespace)::A::function() (anonymous namespace)::B::function() const Bn::(anonymous namespace)::function(int, int) gdb::(anonymous namespace)::function() (anonymous namespace)::function() Bn::B::func() gdb::(anonymous namespace)::function(int, int) (anonymous namespace)::function(int, int) Bn::B::function() gdb::A::func() A::func() Bn::func() gdb::A::function() A::function() Bn::function() gdb::func() B::func() Bn::function(int, int) gdb::function() B::function() Bn::function(long) gdb::function(int, int) B::function() const func() gdb::function(long) B::function_const() const function() (gdb) b function Breakpoint 1 at 0x4005ce: function. (26 locations) (gdb) b B::function<tab> (anonymous namespace)::B::function() B::function() const Bn::B::function() (anonymous namespace)::B::function() const B::function_const() const B::function() Bn::(anonymous namespace)::B::function() (gdb) b B::function Breakpoint 1 at 0x40072c: B::function. (6 locations) To get back the original behavior of interpreting the function name as a fully-qualified name, you can use the new "-qualified" (or "-q") option/flag (added by this commit). For example: (gdb) b B::function (anonymous namespace)::B::function() B::function() const Bn::B::function() (anonymous namespace)::B::function() const B::function_const() const B::function() Bn::(anonymous namespace)::B::function() vs: (gdb) b -qualified B::function B::function() B::function() const B::function_const() const I've chosen "-qualified" / "-q" because "-f" (for "full" or "fully-qualified") is already taken for "-function". Note: the "-qualified" option works with both linespecs and explicit locations. I.e., these are equivalent: (gdb) b -q func (gdb) b -q -f func and so are these: (gdb) b -q filename.cc:func (gdb) b -q -s filename.cc -f func (gdb) b -s filename.cc -q -f func (gdb) b -s filename.cc -f func -q To better understand why I consider wild matching the better default, consider what happens when we get to the point when _all_ of GDB is wrapped under "namespace gdb {}". I have a patch series that does that, and when I started debugging that GDB, I immediately became frustrated. You'd have to write "b gdb::internal_error", "b gdb::foo", "b gdb::bar", etc. etc., which gets annoying pretty quickly. OTOH, consider how this makes it very easy to set breakpoints in classes wrapped in anonymous namespaces. You just don't think of them, GDB finds the symbols for you automatically. (At the Cauldron a couple months ago, several people told me that they run into a similar issue when debugging other C++ projects. One example was when debugging LLVM, which puts all its code under the "llvm" namespace.) Implementation-wise, what the patch does is: - makes C++ symbol name hashing only consider the last component of a symbol name. (so that we can look up symbol names by last-component name only). - adds a C++ symbol name matcher for symbol_name_match_type::WILD, which ignores missing leading specifiers / components. - adjusts a few preexisting testsuite tests to use "-qualified" when they mean it. - adds new testsuite tests. - adds unit tests. Grows the gdb.linespec/ tests like this: -# of expected passes 7823 +# of expected passes 8977 gdb/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * NEWS: Mention that breakpoints on C++ functions are now set on on all namespaces/classes by default, and mention "break -qualified". * ax-gdb.c (agent_command_1): Adjust to pass a symbol_name_match_type to new_linespec_location. * breakpoint.c (parse_breakpoint_sals): Adjust to get_linespec_location's return type change. (strace_marker_create_sals_from_location): Adjust to pass a symbol_name_match_type to new_linespec_location. (strace_marker_decode_location): Adjust to get_linespec_location's return type change. (strace_command): Adjust to pass a symbol_name_match_type to new_linespec_location. (LOCATION_HELP_STRING): Add paragraph about wildmatching, and mention "-qualified". * c-lang.c (cplus_language_defn): Install cp_search_name_hash. * completer.c (explicit_location_match_type::MATCH_QUALIFIED): New enumerator. (complete_address_and_linespec_locations): New parameter 'match_type'. Pass it down. (explicit_options): Add "-qualified". (collect_explicit_location_matches): Pass the requested match type to the linespec completers. Handle MATCH_QUALIFIED. (location_completer): Handle "-qualified" combined with linespecs. * cp-support.c (cp_search_name_hash): New. (cp_symbol_name_matches_1): Implement wild matching for C++. (cp_fq_symbol_name_matches): Reimplement. (cp_get_symbol_name_matcher): Return different matchers depending on the lookup name's match type. (selftests::test_cp_symbol_name_matches): Add wild matching tests. * cp-support.h (cp_search_name_hash): New declaration. * dwarf2read.c (selftests::dw2_expand_symtabs_matching::test_symbols): Add symbols. (test_dw2_expand_symtabs_matching_symbol): Add wild matching tests. * guile/scm-breakpoint.c (gdbscm_register_breakpoint_x): Adjust to pass a symbol_name_match_type to new_linespec_location. * linespec.c (linespec_parse_basic): Lookup function symbols using the parser's symbol name match type. (convert_explicit_location_to_linespec): New symbol_name_match_type parameter. Pass it down to find_linespec_symbols. (convert_explicit_location_to_sals): Pass the location's name match type to convert_explicit_location_to_linespec. (parse_linespec): New match_type parameter. Save it in the parser. (linespec_parser_new): Default to symbol_name_match_type::WILD. (linespec_complete_function): New symbol_name_match_type parameter. Use it. (complete_linespec_component): Pass down the parser's recorded name match type. (linespec_complete_label): New symbol_name_match_type parameter. Use it. (linespec_complete): New symbol_name_match_type parameter. Save it in the parser and pass it down. Adjust to get_linespec_location's prototype change. (find_function_symbols, find_linespec_symbols): New symbol_name_match_type parameter. Pass it down instead of assuming symbol_name_match_type::WILD. * linespec.h (linespec_complete, linespec_complete_function) (linespec_complete_label): New symbol_name_match_type parameter. * location.c (event_location::linespec_location): Now a struct linespec_location. (EL_LINESPEC): Adjust. (initialize_explicit_location): Default to symbol_name_match_type::WILD. (new_linespec_location): New symbol_name_match_type parameter. Record it in the location. (get_linespec_location): Now returns a struct linespec_location. (new_explicit_location): Also copy func_name_match_type. (explicit_to_string_internal) (string_to_explicit_location): Handle "-qualified". (copy_event_location): Adjust to LINESPEC_LOCATION type change. Copy symbol_name_match_type fields. (event_location_deleter::operator()): Adjust to LINESPEC_LOCATION type change. (event_location_to_string): Adjust to LINESPEC_LOCATION type change. Handle "-qualfied". (string_to_explicit_location): Handle "-qualified". (string_to_event_location_basic): New symbol_name_match_type parameter. Pass it down. (string_to_event_location): Handle "-qualified". * location.h (struct linespec_location): New. (explicit_location::func_name_match_type): New field. (new_linespec_location): Now returns a const linespec_location *. (string_to_event_location_basic): New symbol_name_match_type parameter. (explicit_completion_info::saw_explicit_location_option): New field. * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Adjust to pass a symbol_name_match_type to new_linespec_location. * python/py-breakpoint.c (bppy_init): Likewise. * python/python.c (gdbpy_decode_line): Likewise. gdb/testsuite/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * gdb.base/langs.exp: Use -qualified. * gdb.cp/meth-typedefs.exp: Use -qualified, and add tests without it. * gdb.cp/namespace.exp: Use -qualified. * gdb.linespec/cpcompletion.exp (overload-2, fqn, fqn-2) (overload-3, template-overload, template-ret-type, const-overload) (const-overload-quoted, anon-ns, ambiguous-prefix): New procedures. (test_driver): Call them. * gdb.cp/save-bp-qualified.cc: New. * gdb.cp/save-bp-qualified.exp: New. * gdb.linespec/explicit.exp: Test -qualified. * lib/completion-support.exp (completion::explicit_opts_list): Add "-qualified". * lib/gdb.exp (gdb_breakpoint): Handle "qualified". gdb/doc/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * gdb.texinfo (Linespec Locations): Document how "function" is interpreted in C++ and Ada. Document "-qualified". (Explicit Locations): Document how "-function" is interpreted in C++ and Ada. Document "-qualified".
Diffstat (limited to 'gdb/testsuite/gdb.linespec')
-rw-r--r--gdb/testsuite/gdb.linespec/cpcompletion.exp423
-rw-r--r--gdb/testsuite/gdb.linespec/explicit.exp80
2 files changed, 471 insertions, 32 deletions
diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp
index 873dc785cd..832ef07320 100644
--- a/gdb/testsuite/gdb.linespec/cpcompletion.exp
+++ b/gdb/testsuite/gdb.linespec/cpcompletion.exp
@@ -118,6 +118,339 @@ proc_with_prefix overload {} {
}
}
+# Test completion of a function that is defined in different scopes
+# with different parameters.
+
+proc_with_prefix overload-2 {} {
+ with_test_prefix "all" {
+ set completion_list {
+ "(anonymous namespace)::overload2_function(overload2_arg3)"
+ "(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
+ "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
+ "ns_overload2_test::overload2_function(overload2_arg5)"
+ "ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"
+ "overload2_function(overload2_arg1)"
+ "struct_overload2_test::overload2_function(overload2_arg2)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "overload2_func" "tion(overload2_arg" $completion_list
+ check_bp_locations_match_list \
+ "$cmd_prefix overload2_function" $completion_list
+ }
+ }
+
+ # Same, but restrict to functions/methods in some scope.
+ with_test_prefix "restrict scope" {
+ set completion_list {
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::overload2_function(overload2_arg5)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "ns_overload2_test::overload2_func" "tion(overload2_arg" $completion_list
+ check_bp_locations_match_list \
+ "$cmd_prefix ns_overload2_test::overload2_function" $completion_list
+ }
+ }
+
+ # Restrict to anonymous namespace scopes.
+ with_test_prefix "restrict scope 2" {
+ set completion_list {
+ "(anonymous namespace)::overload2_function(overload2_arg3)"
+ "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "(anonymous namespace)::overload2_func" "tion(overload2_arg" $completion_list
+ check_bp_locations_match_list \
+ "$cmd_prefix (anonymous namespace)::overload2_function" $completion_list
+ }
+ }
+
+ # Add enough scopes, and we get a unique completion.
+ with_test_prefix "unique completion" {
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_unique \
+ "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func" \
+ "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ check_setting_bp_fails "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func"
+ check_bp_locations_match_list \
+ "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function" \
+ {"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"}
+ }
+ }
+}
+
+# Test linespecs / locations using fully-qualified names.
+
+proc_with_prefix fqn {} {
+
+ # "-qualified" works with both explicit locations and linespecs.
+ # Also test that combining a source file with a function name
+ # still results in a full match, with both linespecs and explicit
+ # locations.
+ foreach cmd_prefix {
+ "b -qualified "
+ "b -qualified -function "
+ "b -qualified cpls.cc:"
+ "b -qualified -source cpls.cc -function "
+ "b -source cpls.cc -qualified -function "
+ } {
+ test_gdb_complete_unique \
+ "${cmd_prefix}overload2_func" \
+ "${cmd_prefix}overload2_function(overload2_arg1)"
+
+ # Drill down until we find a unique completion.
+ test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::" "" {
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
+ "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
+ "ns_overload2_test::overload2_function(overload2_arg5)"
+ "ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"
+ }
+
+ test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::" "" {
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
+ "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
+ }
+
+ test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::ns_overload2_test::" "" {
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
+ }
+
+ test_gdb_complete_unique \
+ "${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_func" \
+ "${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+
+ }
+}
+
+# Check that a fully-qualified lookup name doesn't match symbols in
+# nested scopes.
+
+proc_with_prefix fqn-2 {} {
+ set linespec "struct_overload2_test::overload2_function(overload2_arg6)"
+ set cmd_prefix "b -qualified"
+ check_setting_bp_fails "$cmd_prefix $linespec"
+ test_gdb_complete_none "$cmd_prefix $linespec"
+
+ # Check that using the same name, but not fully-qualifying it,
+ # would find something, just to make sure the test above is
+ # testing what we intend to test.
+ set cmd_prefix "b -function"
+ test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
+ check_bp_locations_match_list \
+ "$cmd_prefix $linespec" \
+ {"ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"}
+}
+
+# Test completion of functions in different scopes that have the same
+# name and parameters. Restricting the scopes should find fewer and
+# fewer matches.
+
+proc_with_prefix overload-3 {} {
+ with_test_prefix "all overloads" {
+ set completion_list {
+ "(anonymous namespace)::overload3_function(int)"
+ "(anonymous namespace)::overload3_function(long)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::overload3_function(int)"
+ "ns_overload3_test::overload3_function(long)"
+ "ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::struct_overload3_test::overload3_function(long)"
+ "overload3_function(int)"
+ "overload3_function(long)"
+ "struct_overload3_test::overload3_function(int)"
+ "struct_overload3_test::overload3_function(long)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple "$cmd_prefix " "overload3_func" "tion(" $completion_list
+ check_bp_locations_match_list "$cmd_prefix overload3_function" $completion_list
+ }
+ }
+
+ with_test_prefix "restrict overload" {
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_unique \
+ "$cmd_prefix overload3_function(int)" \
+ "$cmd_prefix overload3_function(int)"
+ check_bp_locations_match_list "$cmd_prefix overload3_function(int)" {
+ "(anonymous namespace)::overload3_function(int)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::overload3_function(int)"
+ "ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "overload3_function(int)"
+ "struct_overload3_test::overload3_function(int)"
+ }
+ }
+ }
+
+ with_test_prefix "restrict scope" {
+ set completion_list {
+ "(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::struct_overload3_test::overload3_function(long)"
+ "struct_overload3_test::overload3_function(int)"
+ "struct_overload3_test::overload3_function(long)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "struct_overload3_test::overload3_func" "tion(" \
+ $completion_list
+ check_bp_locations_match_list \
+ "$cmd_prefix struct_overload3_test::overload3_function" \
+ $completion_list
+ }
+ }
+}
+
+# Test completing an overloaded template method.
+
+proc_with_prefix template-overload {} {
+ set completion_list {
+ "template_struct<int>::template_overload_fn(int)"
+ "template_struct<long>::template_overload_fn(long)"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple "$cmd_prefix " "template_overload_fn" "(" $completion_list
+ check_bp_locations_match_list "$cmd_prefix template_overload_fn" $completion_list
+ check_bp_locations_match_list \
+ "$cmd_prefix template_struct<int>::template_overload_fn" \
+ "template_struct<int>::template_overload_fn(int)"
+ }
+}
+
+# Test completing template methods with non-void return type.
+
+proc_with_prefix template-ret-type {} {
+ set method_name "template2_fn<int, int>"
+ set param_list "(template2_ret_type<int>, int, int)"
+ set struct_type "template2_struct<template2_ret_type<int> >"
+ set ret_type "template2_ret_type<int>"
+
+ # Templates are listed both with and without return type, making
+ # "template2_<tab>" ambiguous.
+ foreach cmd_prefix {"b" "b -function"} {
+ set completion_list \
+ [list \
+ "${ret_type} ${struct_type}::${method_name}${param_list}" \
+ "${struct_type}::${method_name}${param_list}"]
+ test_gdb_complete_multiple "$cmd_prefix " "template2_" "" $completion_list
+
+ # Add one character more after "2_", and the linespec becomes
+ # unambiguous. Test completing the whole prefix range after that,
+ # thus testing completing either with or without return type.
+ foreach {s t} [list \
+ "template2_r" \
+ "${ret_type} ${struct_type}::${method_name}${param_list}" \
+ "template2_s" \
+ "${struct_type}::${method_name}${param_list}"] {
+ set linespec $t
+ set complete_line "$cmd_prefix $linespec"
+ set start [index_after $s $complete_line]
+ test_complete_prefix_range $complete_line $start
+ }
+
+ # Setting a breakpoint without the template params doesn't work.
+ check_setting_bp_fails "$cmd_prefix template2_fn"
+ # However, setting a breakpoint with template params and without
+ # the method params does work, just like with non-template
+ # functions. It also works with or without return type.
+ foreach linespec [list \
+ "${method_name}" \
+ "${method_name}${param_list}" \
+ "${struct_type}::${method_name}" \
+ "${struct_type}::${method_name}${param_list}" \
+ "${ret_type} ${struct_type}::${method_name}" \
+ "${ret_type} ${struct_type}::${method_name}${param_list}"] {
+ check_bp_locations_match_list \
+ "$cmd_prefix $linespec" \
+ [list "${struct_type}::${method_name}${param_list}"]
+ }
+ }
+}
+
+# Test completion of a const-overloaded funtion (const-overload).
+# Note that "const" appears after the function/method parameters.
+
+proc_with_prefix const-overload {} {
+ set completion_list {
+ "struct_with_const_overload::const_overload_fn()"
+ "struct_with_const_overload::const_overload_fn() const"
+ }
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "const_overload_fn" "()" \
+ $completion_list
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "const_overload_fn ( " ")" \
+ $completion_list
+ test_gdb_complete_multiple \
+ "$cmd_prefix " "const_overload_fn()" "" \
+ $completion_list
+
+ check_bp_locations_match_list \
+ "$cmd_prefix const_overload_fn" \
+ {"struct_with_const_overload::const_overload_fn()"
+ "struct_with_const_overload::const_overload_fn() const"}
+
+ check_setting_bp_fails "$cmd_prefix const_overload_fn("
+ check_bp_locations_match_list \
+ "$cmd_prefix const_overload_fn()" \
+ {"struct_with_const_overload::const_overload_fn()"}
+ check_bp_locations_match_list \
+ "$cmd_prefix const_overload_fn() const" \
+ {"struct_with_const_overload::const_overload_fn() const"}
+ }
+}
+
+# Same but quote-enclose the function name. This makes the overload
+# no longer be ambiguous.
+
+proc_with_prefix const-overload-quoted {} {
+ foreach cmd_prefix {"b" "b -function"} {
+ set linespec "'const_overload_fn()'"
+ test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
+ check_bp_locations_match_list \
+ "$cmd_prefix $linespec" {
+ "struct_with_const_overload::const_overload_fn()"
+ }
+
+ set linespec "'const_overload_fn() const'"
+ test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
+ check_bp_locations_match_list \
+ "$cmd_prefix $linespec" {
+ "struct_with_const_overload::const_overload_fn() const"
+ }
+ }
+}
+
# Test that when the function is unambiguous, linespec completion
# appends the end quote char automatically, both ' and ".
@@ -341,6 +674,73 @@ proc_with_prefix incomplete-scope-colon {} {
}
}
+# Test completing functions/methods in anonymous namespaces.
+
+proc_with_prefix anon-ns {} {
+ foreach cmd_prefix {"b" "b -function"} {
+ foreach qc $completion::maybe_quoted_list {
+ test_gdb_complete_unique \
+ "$cmd_prefix ${qc}anon_ns_function" \
+ "$cmd_prefix ${qc}anon_ns_function()${qc}"
+ check_bp_locations_match_list "$cmd_prefix ${qc}anon_ns_function()${qc}" {
+ "(anonymous namespace)::anon_ns_function()"
+ "(anonymous namespace)::anon_ns_struct::anon_ns_function()"
+ "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
+ "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()"
+ }
+ }
+
+ # A "(" finds all anonymous namespace functions/methods in all
+ # scopes.
+ test_gdb_complete_multiple "$cmd_prefix " "(" "anonymous namespace)::" {
+ "(anonymous namespace)::anon_ns_function()"
+ "(anonymous namespace)::anon_ns_struct::anon_ns_function()"
+ "(anonymous namespace)::overload2_function(overload2_arg3)"
+ "(anonymous namespace)::overload3_function(int)"
+ "(anonymous namespace)::overload3_function(long)"
+ "(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
+ "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
+ "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
+ "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::overload3_function(long)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
+ "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
+ "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
+ "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()"
+ }
+
+ set function "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
+ test_gdb_complete_unique "$cmd_prefix $function" "$cmd_prefix $function"
+ check_bp_locations_match_list "$cmd_prefix $function" [list $function]
+
+ # Test completing after the "(anonymous namespace)" part.
+ test_gdb_complete_unique \
+ "$cmd_prefix the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_fu" \
+ "$cmd_prefix $function"
+
+ # Test whitespace in the "(anonymous namespace)" component.
+
+ test_gdb_complete_unique \
+ "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu" \
+ "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function()"
+ check_setting_bp_fails \
+ "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu"
+
+ set function_ws \
+ "the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function ( )"
+ test_gdb_complete_unique "$cmd_prefix $function_ws" "$cmd_prefix $function_ws"
+ check_bp_locations_match_list "$cmd_prefix $function_ws" [list $function]
+ }
+}
+
# Basic test for completing "operator<". More extensive C++ operator
# tests in cpls-op.exp.
@@ -368,6 +768,19 @@ proc_with_prefix operator< {} {
}
}
+# Test completion of scopes with an ambiguous prefix.
+
+proc_with_prefix ambiguous-prefix {} {
+ foreach cmd_prefix {"b" "b -function"} {
+ test_gdb_complete_multiple "$cmd_prefix " "ambiguous_pre" "fix_" {
+ "ambiguous_prefix_global_func()"
+ "the_ambiguous_prefix_ns::ambiguous_prefix_ns_func()"
+ "the_ambiguous_prefix_struct::ambiguous_prefix_method()"
+ }
+ check_setting_bp_fails "$cmd_prefix ambiguous_prefix_"
+ }
+}
+
# Test completion of function labels.
proc_with_prefix function-labels {} {
@@ -516,13 +929,23 @@ proc_with_prefix if-expression {} {
proc test_driver {} {
all-param-prefixes
overload
+ overload-2
+ fqn
+ fqn-2
+ overload-3
+ template-overload
+ template-ret-type
+ const-overload
+ const-overload-quoted
append-end-quote-char-when-unambiguous
in-source-file-unconstrained
in-source-file-unambiguous
in-source-file-ambiguous
source-complete-appends-colon
incomplete-scope-colon
+ anon-ns
operator<
+ ambiguous-prefix
function-labels
keywords-after-function
keywords-after-label
diff --git a/gdb/testsuite/gdb.linespec/explicit.exp b/gdb/testsuite/gdb.linespec/explicit.exp
index 9cf0162f16..b592d29efb 100644
--- a/gdb/testsuite/gdb.linespec/explicit.exp
+++ b/gdb/testsuite/gdb.linespec/explicit.exp
@@ -401,51 +401,66 @@ namespace eval $testfile {
"-function"
"-label"
"-line"
+ "-qualified"
"-source"
"if"
"task"
"thread"
}
foreach what { "-function" "-label" "-line" "-source" } {
- with_test_prefix "complete after $what" {
- if {$what != "-line"} {
- set w "$what argument "
- test_gdb_complete_multiple \
- "b $w" "" "" $completions_list
- test_gdb_complete_unique \
- "b $w thr" \
- "b $w thread"
- test_gdb_complete_unique \
- "b $w -fun" \
- "b $w -function"
- } else {
- # After -line, we expect a number / offset.
- foreach line {"10" "+10" "-10"} {
- set w "-line $line"
- test_gdb_complete_multiple \
- "b $w " "" "" $completions_list
- test_gdb_complete_unique \
- "b $w thr" \
- "b $w thread"
- test_gdb_complete_unique \
- "b $w -fun" \
- "b $w -function"
+ # Also test with "-qualified" appearing before the
+ # explicit location.
+ foreach prefix {"" "-qualified "} {
+
+ # ... and with "-qualified" appearing after the
+ # explicit location.
+ foreach suffix {"" " -qualified"} {
+ with_test_prefix "complete after $prefix$what$suffix" {
+ if {$what != "-line"} {
+ set w "$prefix$what argument$suffix "
+ test_gdb_complete_multiple \
+ "b $w" "" "" $completions_list
+ test_gdb_complete_unique \
+ "b $w thr" \
+ "b $w thread"
+ test_gdb_complete_unique \
+ "b $w -fun" \
+ "b $w -function"
+ } else {
+ # After -line, we expect a number / offset.
+ foreach line {"10" "+10" "-10"} {
+ set w "$prefix-line $line$suffix"
+ test_gdb_complete_multiple \
+ "b $w " "" "" $completions_list
+ test_gdb_complete_unique \
+ "b $w thr" \
+ "b $w thread"
+ test_gdb_complete_unique \
+ "b $w -fun" \
+ "b $w -function"
+ }
+
+ # With an invalid -line argument, we don't get any
+ # completions.
+ test_gdb_complete_none "b $prefix-line argument$suffix "
+ }
+
}
- # With an invalid -line argument, we don't get any
- # completions.
- test_gdb_complete_none "b -line argument "
}
- # Don't complete a linespec keyword ("thread") or
- # another option name when expecting an option
- # argument.
- test_gdb_complete_none "b $what thr"
- test_gdb_complete_none "b $what -fun"
+ # These tests don't make sense with "-qualified" after
+ # the location.
+ with_test_prefix "complete after $prefix$what" {
+ # Don't complete a linespec keyword ("thread") or
+ # another option name when expecting an option
+ # argument.
+ test_gdb_complete_none "b $prefix$what thr"
+ test_gdb_complete_none "b $prefix$what -fun"
+ }
}
}
-
# Tests that ensure that after "if" we complete on expressions
# are in cpcompletion.exp.
@@ -518,6 +533,7 @@ namespace eval $testfile {
"-probe"
"-probe-dtrace"
"-probe-stap"
+ "-qualified"
"-source"
}
with_test_prefix "complete with no arguments and no symbols" {