This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]


On 11/28/2017 12:01 AM, Pedro Alves wrote:
> On 11/27/2017 05:13 PM, Pedro Alves wrote:
>> In v2:
>>
>>   - Implements Keith's suggestion of making "-qualified" a flag
>>     option, instead of being a replacement for "-function".  This
>>     means that "break -q filename.cc:function" interprets
>>     "filename.cc:function" as a linespec with two components instead
>>     of a (bogus) function name.  Basically, this folds in these
>>     changes (with some additional cleanup here and there):
>>      https://sourceware.org/ml/gdb-patches/2017-11/msg00621.html
>>      https://sourceware.org/ml/gdb-patches/2017-11/msg00618.html
> 
> Rereading this, I realized that the "-qualified" options wasn't being saved
> by "save breakpoints".  There were a couple problems.  First,
> linespec.c:canonicalize_linespec was losing the symbol_name_match_type.
> While addressing this, I realized that we don't really need to add
> a new field to ls_parser to record the desired symbol_name_match_type,
> since we can just use the one in PARSER_EXPLICIT.
> The second is that I missed updating the "-qualified" handling in
> explicit_to_string_internal to take into account the fact that
> "-qualified" now appears with traditional linespecs as well.
> 
> Below's what I'm folding in to the patch, to address this.  New
> testcase included.

And here's the resulting patch with that folded in.

Also force-pushed to users/palves/cxx-breakpoint-improvements-v2.

>From c954288a24007c2d5d563529e573d81641b29f43 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 28 Nov 2017 00:02:27 +0000
Subject: [PATCH v2.1 2/3] 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:
yyyy-mm-dd  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:
yyyy-mm-dd  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:
yyyy-mm-dd  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".
---
 gdb/doc/gdb.texinfo                         |  43 ++-
 gdb/NEWS                                    |  20 ++
 gdb/ax-gdb.c                                |   3 +-
 gdb/breakpoint.c                            |  32 ++-
 gdb/c-lang.c                                |   2 +-
 gdb/completer.c                             |  44 ++-
 gdb/cp-support.c                            | 163 ++++++++++-
 gdb/cp-support.h                            |   7 +
 gdb/dwarf2read.c                            |  48 ++++
 gdb/guile/scm-breakpoint.c                  |   6 +-
 gdb/linespec.c                              |  49 +++-
 gdb/linespec.h                              |  12 +-
 gdb/location.c                              |  90 ++++--
 gdb/location.h                              |  38 ++-
 gdb/mi/mi-cmd-break.c                       |   3 +-
 gdb/python/py-breakpoint.c                  |   3 +-
 gdb/python/python.c                         |   3 +-
 gdb/testsuite/gdb.base/langs.exp            |   2 +-
 gdb/testsuite/gdb.cp/meth-typedefs.exp      |  39 ++-
 gdb/testsuite/gdb.cp/namespace.exp          |   2 +-
 gdb/testsuite/gdb.cp/save-bp-qualified.cc   |  40 +++
 gdb/testsuite/gdb.cp/save-bp-qualified.exp  |  74 +++++
 gdb/testsuite/gdb.linespec/cpcompletion.exp | 423 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.linespec/explicit.exp     |  80 +++---
 gdb/testsuite/lib/completion-support.exp    |   2 +-
 gdb/testsuite/lib/gdb.exp                   |   6 +-
 26 files changed, 1109 insertions(+), 125 deletions(-)
 create mode 100644 gdb/testsuite/gdb.cp/save-bp-qualified.cc
 create mode 100644 gdb/testsuite/gdb.cp/save-bp-qualified.exp

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 675f6e7..7a71739 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7918,6 +7918,22 @@ name of @file{/build/trunk/gcc/expr.c}, but not
 Specifies the line that begins the body of the function @var{function}.
 For example, in C, this is the line with the open brace.
 
+By default, in C@t{++} and Ada, @var{function} is interpreted as
+specifying all functions named @var{function} in all scopes.  For
+C@t{++}, this means in all namespaces and classes.  For Ada, this
+means in all packages.
+
+For example, assuming a program with C@t{++} symbols named
+@code{A::B::func} and @code{B::func}, both commands @w{@kbd{break
+func}} and @w{@kbd{break B::func}} set a breakpoint on both symbols.
+
+Commands that accept a linespec let you override this with the
+@code{-qualified} option.  For example, @w{@kbd{break -qualified
+func}} sets a breakpoint on a free-function named @code{func} ignoring
+any C@t{++} class methods and namespace functions called @code{func}.
+
+@xref{Explicit Locations}.
+
 @item @var{function}:@var{label}
 Specifies the line where @var{label} appears in @var{function}.
 
@@ -7982,6 +7998,31 @@ on function locations unmodified by other options (such as @code{-label}
 or @code{-line}) refer to the line that begins the body of the function.
 In C, for example, this is the line with the open brace.
 
+By default, in C@t{++} and Ada, @var{function} is interpreted as
+specifying all functions named @var{function} in all scopes.  For
+C@t{++}, this means in all namespaces and classes.  For Ada, this
+means in all packages.
+
+For example, assuming a program with C@t{++} symbols named
+@code{A::B::func} and @code{B::func}, both commands @w{@kbd{break
+-function func}} and @w{@kbd{break -function B::func}} set a
+breakpoint on both symbols.
+
+You can use the @kbd{-qualified} flag to override this (see below).
+
+@item -qualified
+
+This flag makes @value{GDBN} interpret a function name specified with
+@kbd{-function} as a complete fully-qualified name.
+
+For example, assuming a C@t{++} program with symbols named
+@code{A::B::func} and @code{B::func}, the @w{@kbd{break -qualified
+-function B::func}} command sets a breakpoint on @code{B::func}, only.
+
+(Note: the @kbd{-qualified} option can precede a linespec as well
+(@pxref{Linespec Locations}), so the particular example above could be
+simplified as @w{@kbd{break -qualified B::func}}.)
+
 @item -label @var{label}
 The value specifies the name of a label.  When the function
 name is not specified, the label is searched in the function of the currently
@@ -7995,7 +8036,7 @@ relative to the current line.
 @end table
 
 Explicit location options may be abbreviated by omitting any non-unique
-trailing characters from the option name, e.g., @code{break -s main.c -li 3}.
+trailing characters from the option name, e.g., @w{@kbd{break -s main.c -li 3}}.
 
 @node Address Locations
 @subsection Address Locations
diff --git a/gdb/NEWS b/gdb/NEWS
index 754ce10..984fd96 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -52,6 +52,26 @@
 
   ** The "complete" command now mimics TAB completion accurately.
 
+* Breakpoints on C++ functions are now set on all scopes by default
+
+  By default, breakpoints on functions/methods are now interpreted as
+  specifying all functions with the given name ignoring missing
+  leading scopes (namespaces and classes).
+
+  For example, assuming a C++ program with symbols named:
+
+    A::B::func()
+    B::func()
+
+  both commands "break func()" and "break B::func()" set a breakpoint
+  on both symbols.
+
+  You can use the new flag "-qualified" to override this.  This makes
+  GDB interpret the specified function name as a complete
+  fully-qualified name instead.  For example, using the same C++
+  program, the "break -q B::func" command sets a breakpoint on
+  "B::func", only.
+
 * Python Scripting
 
   ** New events gdb.new_inferior, gdb.inferior_deleted, and
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 52ca081..5027f6a 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2638,7 +2638,8 @@ agent_command_1 (const char *exp, int eval)
 
       exp = skip_spaces (exp);
 
-      event_location_up location = new_linespec_location (&exp);
+      event_location_up location
+	= new_linespec_location (&exp, symbol_name_match_type::WILD);
       decode_line_full (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
 			(struct symtab *) NULL, 0, &canonical,
 			NULL, NULL);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b48c405..d4d095d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -9100,9 +9100,9 @@ parse_breakpoint_sals (const struct event_location *location,
 
   if (event_location_type (location) == LINESPEC_LOCATION)
     {
-      const char *address = get_linespec_location (location);
+      const char *spec = get_linespec_location (location)->spec_string;
 
-      if (address == NULL)
+      if (spec == NULL)
 	{
 	  /* The last displayed codepoint, if it's valid, is our default
 	     breakpoint address.  */
@@ -9148,15 +9148,15 @@ parse_breakpoint_sals (const struct event_location *location,
   cursal = get_current_source_symtab_and_line ();
   if (last_displayed_sal_is_valid ())
     {
-      const char *address = NULL;
+      const char *spec = NULL;
 
       if (event_location_type (location) == LINESPEC_LOCATION)
-	address = get_linespec_location (location);
+	spec = get_linespec_location (location)->spec_string;
 
       if (!cursal.symtab
-	  || (address != NULL
-	      && strchr ("+-", address[0]) != NULL
-	      && address[1] != '['))
+	  || (spec != NULL
+	      && strchr ("+-", spec[0]) != NULL
+	      && spec[1] != '['))
 	{
 	  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
 			    get_last_displayed_symtab (),
@@ -13147,12 +13147,13 @@ strace_marker_create_sals_from_location (const struct event_location *location,
   struct linespec_sals lsal;
   const char *arg_start, *arg;
 
-  arg = arg_start = get_linespec_location (location);
+  arg = arg_start = get_linespec_location (location)->spec_string;
   lsal.sals = decode_static_tracepoint_spec (&arg);
 
   std::string str (arg_start, arg - arg_start);
   const char *ptr = str.c_str ();
-  canonical->location = new_linespec_location (&ptr);
+  canonical->location
+    = new_linespec_location (&ptr, symbol_name_match_type::FULL);
 
   lsal.canonical
     = xstrdup (event_location_to_string (canonical->location.get ()));
@@ -13213,7 +13214,7 @@ strace_marker_decode_location (struct breakpoint *b,
 			       struct program_space *search_pspace)
 {
   struct tracepoint *tp = (struct tracepoint *) b;
-  const char *s = get_linespec_location (location);
+  const char *s = get_linespec_location (location)->spec_string;
 
   std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
   if (sals.size () > tp->static_trace_marker_id_idx)
@@ -14759,7 +14760,7 @@ strace_command (const char *arg, int from_tty)
   if (arg && startswith (arg, "-m") && isspace (arg[2]))
     {
       ops = &strace_marker_breakpoint_ops;
-      location = new_linespec_location (&arg);
+      location = new_linespec_location (&arg, symbol_name_match_type::FULL);
     }
   else
     {
@@ -15289,7 +15290,14 @@ Explicit locations are similar to linespecs but use an option/argument\n\
 syntax to specify location parameters.\n\
 Example: To specify the start of the label named \"the_top\" in the\n\
 function \"fact\" in the file \"factorial.c\", use \"-source factorial.c\n\
--function fact -label the_top\".\n"
+-function fact -label the_top\".\n\
+\n\
+By default, a specified function is matched against the program's\n\
+functions in all scopes.  For C++, this means in all namespaces and\n\
+classes.  For Ada, this means in all packages.  E.g., in C++,\n\
+\"func()\" matches \"A::func()\", \"A::B::func()\", etc.  The\n\
+\"-qualified\" flag overrides this behavior, making GDB interpret the\n\
+specified name as a complete fully-qualified name instead.\n"
 
 /* This help string is used for the break, hbreak, tbreak and thbreak
    commands.  It is defined as a macro to prevent duplication.
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 49077c7..8d96f94 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -1016,7 +1016,7 @@ extern const struct language_defn cplus_language_defn =
   c_watch_location_expression,
   cp_get_symbol_name_matcher,
   iterate_over_symbols,
-  default_search_name_hash,
+  cp_search_name_hash,
   &cplus_varobj_ops,
   NULL,
   NULL,
diff --git a/gdb/completer.c b/gdb/completer.c
index fd82b86..701f578 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -76,6 +76,9 @@ enum explicit_location_match_type
     /* The name of a function or method.  */
     MATCH_FUNCTION,
 
+    /* The fully-qualified name of a function or method.  */
+    MATCH_QUALIFIED,
+
     /* A line number.  */
     MATCH_LINE,
 
@@ -579,7 +582,8 @@ complete_source_filenames (const char *text)
 
 static void
 complete_address_and_linespec_locations (completion_tracker &tracker,
-					 const char *text)
+					 const char *text,
+					 symbol_name_match_type match_type)
 {
   if (*text == '*')
     {
@@ -591,7 +595,7 @@ complete_address_and_linespec_locations (completion_tracker &tracker,
     }
   else
     {
-      linespec_complete (tracker, text);
+      linespec_complete (tracker, text, match_type);
     }
 }
 
@@ -602,6 +606,7 @@ static const char *const explicit_options[] =
   {
     "-source",
     "-function",
+    "-qualified",
     "-line",
     "-label",
     NULL
@@ -638,6 +643,9 @@ collect_explicit_location_matches (completion_tracker &tracker,
   const struct explicit_location *explicit_loc
     = get_explicit_location (location);
 
+  /* True if the option expects an argument.  */
+  bool needs_arg = true;
+
   /* Note, in the various MATCH_* below, we complete on
      explicit_loc->foo instead of WORD, because only the former will
      have already skipped past any quote char.  */
@@ -656,10 +664,14 @@ collect_explicit_location_matches (completion_tracker &tracker,
       {
 	const char *function = string_or_empty (explicit_loc->function_name);
 	linespec_complete_function (tracker, function,
+				    explicit_loc->func_name_match_type,
 				    explicit_loc->source_filename);
       }
       break;
 
+    case MATCH_QUALIFIED:
+      needs_arg = false;
+      break;
     case MATCH_LINE:
       /* Nothing to offer.  */
       break;
@@ -670,6 +682,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
 	linespec_complete_label (tracker, language,
 				 explicit_loc->source_filename,
 				 explicit_loc->function_name,
+				 explicit_loc->func_name_match_type,
 				 label);
       }
       break;
@@ -678,7 +691,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
       gdb_assert_not_reached ("unhandled explicit_location_match_type");
     }
 
-  if (tracker.completes_to_completion_word (word))
+  if (!needs_arg || tracker.completes_to_completion_word (word))
     {
       tracker.discard_completions ();
       tracker.advance_custom_word_point_by (strlen (word));
@@ -867,7 +880,7 @@ location_completer (struct cmd_list_element *ignore,
       tracker.advance_custom_word_point_by (1);
     }
 
-  if (location != NULL)
+  if (completion_info.saw_explicit_location_option)
     {
       if (*copy != '\0')
 	{
@@ -907,10 +920,29 @@ location_completer (struct cmd_list_element *ignore,
 
 	}
     }
+  /* This is an address or linespec location.  */
+  else if (location != NULL)
+    {
+      /* Handle non-explicit location options.  */
+
+      int keyword = skip_keyword (tracker, explicit_options, &text);
+      if (keyword == -1)
+	complete_on_enum (tracker, explicit_options, text, text);
+      else
+	{
+	  tracker.advance_custom_word_point_by (copy - text);
+	  text = copy;
+
+	  symbol_name_match_type match_type
+	    = get_explicit_location (location.get ())->func_name_match_type;
+	  complete_address_and_linespec_locations (tracker, text, match_type);
+	}
+    }
   else
     {
-      /* This is an address or linespec location.  */
-      complete_address_and_linespec_locations (tracker, text);
+      /* No options.  */
+      complete_address_and_linespec_locations (tracker, text,
+					       symbol_name_match_type::WILD);
     }
 
   /* Add matches for option names, if either:
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 6c6825b..172d821 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1615,11 +1615,48 @@ gdb_sniff_from_mangled_name (const char *mangled, char **demangled)
   return *demangled != NULL;
 }
 
-/* C++ symbol_name_matcher_ftype implementation.  */
+/* See cp-support.h.  */
+
+unsigned int
+cp_search_name_hash (const char *search_name)
+{
+  /* cp_entire_prefix_len assumes a fully-qualified name with no
+     leading "::".  */
+  if (startswith (search_name, "::"))
+    search_name += 2;
+
+  unsigned int prefix_len = cp_entire_prefix_len (search_name);
+  if (prefix_len != 0)
+    search_name += prefix_len + 2;
+
+  return default_search_name_hash (search_name);
+}
+
+/* Helper for cp_symbol_name_matches (i.e., symbol_name_matcher_ftype
+   implementation for symbol_name_match_type::WILD matching).  Split
+   to a separate function for unit-testing convenience.
+
+   If SYMBOL_SEARCH_NAME has more scopes than LOOKUP_NAME, we try to
+   match ignoring the extra leading scopes of SYMBOL_SEARCH_NAME.
+   This allows conveniently setting breakpoints on functions/methods
+   inside any namespace/class without specifying the fully-qualified
+   name.
+
+   E.g., these match:
 
-/* Helper for cp_fq_symbol_name_matches (i.e.,
-   symbol_name_matcher_ftype implementation).  Split to a separate
-   function for unit-testing convenience.
+    [symbol search name]   [lookup name]
+    foo::bar::func         foo::bar::func
+    foo::bar::func         bar::func
+    foo::bar::func         func
+
+   While these don't:
+
+    [symbol search name]   [lookup name]
+    foo::zbar::func        bar::func
+    foo::bar::func         foo::func
+
+   See more examples in the test_cp_symbol_name_matches selftest
+   function below.
 
    See symbol_name_matcher_ftype for description of SYMBOL_SEARCH_NAME
    and COMP_MATCH_RES.
@@ -1636,8 +1673,68 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
 			  strncmp_iw_mode mode,
 			  completion_match_result *comp_match_res)
 {
+  const char *sname = symbol_search_name;
+
+  while (true)
+    {
+      if (strncmp_iw_with_mode (sname, lookup_name, lookup_name_len,
+				mode, language_cplus) == 0)
+	{
+	  if (comp_match_res != NULL)
+	    {
+	      /* Note here we set different MATCH and MATCH_FOR_LCD
+		 strings.  This is because with
+
+		  (gdb) b push_bac[TAB]
+
+		 we want the completion matches to list
+
+		  std::vector<int>::push_back(...)
+		  std::vector<char>::push_back(...)
+
+		 etc., which are SYMBOL_SEARCH_NAMEs, while we want
+		 the input line to auto-complete to
+
+		  (gdb) push_back(...)
+
+		 which is SNAME, not to
+
+		  (gdb) std::vector<
+
+		 which would be the regular common prefix between all
+		 the matches otherwise.  */
+	      comp_match_res->set_match (symbol_search_name, sname);
+	    }
+	  return true;
+	}
+
+      unsigned int len = cp_find_first_component (sname);
+
+      if (sname[len] == '\0')
+	return false;
+
+      gdb_assert (sname[len] == ':');
+      /* Skip the '::'.  */
+      sname += len + 2;
+    }
+}
+
+/* C++ symbol_name_matcher_ftype implementation.  */
+
+static bool
+cp_fq_symbol_name_matches (const char *symbol_search_name,
+			   const lookup_name_info &lookup_name,
+			   completion_match_result *comp_match_res)
+{
+  /* Get the demangled name.  */
+  const std::string &name = lookup_name.cplus ().lookup_name ();
+
+  strncmp_iw_mode mode = (lookup_name.completion_mode ()
+			  ? strncmp_iw_mode::NORMAL
+			  : strncmp_iw_mode::MATCH_PARAMS);
+
   if (strncmp_iw_with_mode (symbol_search_name,
-			    lookup_name, lookup_name_len,
+			    name.c_str (), name.size (),
 			    mode, language_cplus) == 0)
     {
       if (comp_match_res != NULL)
@@ -1648,12 +1745,13 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
   return false;
 }
 
-/* C++ symbol_name_matcher_ftype implementation.  */
+/* C++ symbol_name_matcher_ftype implementation for wild matches.
+   Defers work to cp_symbol_name_matches_1.  */
 
 static bool
-cp_fq_symbol_name_matches (const char *symbol_search_name,
-			   const lookup_name_info &lookup_name,
-			   completion_match_result *comp_match_res)
+cp_symbol_name_matches (const char *symbol_search_name,
+			const lookup_name_info &lookup_name,
+			completion_match_result *comp_match_res)
 {
   /* Get the demangled name.  */
   const std::string &name = lookup_name.cplus ().lookup_name ();
@@ -1672,7 +1770,16 @@ cp_fq_symbol_name_matches (const char *symbol_search_name,
 symbol_name_matcher_ftype *
 cp_get_symbol_name_matcher (const lookup_name_info &lookup_name)
 {
-  return cp_fq_symbol_name_matches;
+  switch (lookup_name.match_type ())
+    {
+    case symbol_name_match_type::FULL:
+    case symbol_name_match_type::EXPRESSION:
+      return cp_fq_symbol_name_matches;
+    case symbol_name_match_type::WILD:
+      return cp_symbol_name_matches;
+    }
+
+  gdb_assert_not_reached ("");
 }
 
 #if GDB_SELF_TEST
@@ -1807,6 +1914,42 @@ test_cp_symbol_name_matches ()
   CHECK_MATCH_C ("abc::def::ghi()", "abc::def::ghi ( )");
   CHECK_MATCH_C ("function()", "function()");
   CHECK_MATCH_C ("bar::function()", "bar::function()");
+
+  /* Wild matching tests follow.  */
+
+  /* Tests matching symbols in some scope.  */
+  CHECK_MATCH_C ("foo::function()", "function");
+  CHECK_MATCH_C ("foo::function(int)", "function");
+  CHECK_MATCH_C ("foo::bar::function()", "function");
+  CHECK_MATCH_C ("bar::function()", "bar::function");
+  CHECK_MATCH_C ("foo::bar::function()", "bar::function");
+  CHECK_MATCH_C ("foo::bar::function(int)", "bar::function");
+
+  /* Same, with parameters in the lookup name.  */
+  CHECK_MATCH_C ("foo::function()", "function()");
+  CHECK_MATCH_C ("foo::bar::function()", "function()");
+  CHECK_MATCH_C ("foo::function(int)", "function(int)");
+  CHECK_MATCH_C ("foo::function()", "foo::function()");
+  CHECK_MATCH_C ("foo::bar::function()", "bar::function()");
+  CHECK_MATCH_C ("foo::bar::function(int)", "bar::function(int)");
+  CHECK_MATCH_C ("bar::function()", "bar::function()");
+
+  CHECK_NOT_MATCH_C ("foo::bar::function(int)", "bar::function()");
+
+  CHECK_MATCH_C ("(anonymous namespace)::bar::function(int)",
+		 "bar::function(int)");
+  CHECK_MATCH_C ("foo::(anonymous namespace)::bar::function(int)",
+		 "function(int)");
+
+  /* Lookup scope wider than symbol scope, should not match.  */
+  CHECK_NOT_MATCH_C ("function()", "bar::function");
+  CHECK_NOT_MATCH_C ("function()", "bar::function()");
+
+  /* Explicit global scope doesn't match.  */
+  CHECK_NOT_MATCH_C ("foo::function()", "::function");
+  CHECK_NOT_MATCH_C ("foo::function()", "::function()");
+  CHECK_NOT_MATCH_C ("foo::function(int)", "::function()");
+  CHECK_NOT_MATCH_C ("foo::function(int)", "::function(int)");
 }
 
 /* If non-NULL, return STR wrapped in quotes.  Otherwise, return a
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 44d8269..010fc9b 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -116,6 +116,13 @@ extern struct symbol **make_symbol_overload_list_adl (struct type **arg_types,
 extern struct type *cp_lookup_rtti_type (const char *name,
 					 struct block *block);
 
+/* Produce an unsigned hash value from SEARCH_NAME that is compatible
+   with cp_symbol_name_matches.  Only the last component in
+   "foo::bar::function()" is considered for hashing purposes (i.e.,
+   the entire prefix is skipped), so that later on looking up for
+   "function" or "bar::function" in all namespaces is possible.  */
+extern unsigned int cp_search_name_hash (const char *search_name);
+
 /* Implement the "la_get_symbol_name_matcher" language_defn method for
    C++.  */
 extern symbol_name_matcher_ftype *cp_get_symbol_name_matcher
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 334d8c2..2572179 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4604,6 +4604,8 @@ static const char *test_symbols[] = {
   "ns::foo<char*>",
   "ns::foo<int>",
   "ns::foo<long>",
+  "ns2::tmpl<int>::foo2",
+  "(anonymous namespace)::A::B::C",
 
   /* These are used to check that the increment-last-char in the
      matching algorithm for completion doesn't match "t1_fund" when
@@ -4790,6 +4792,8 @@ test_dw2_expand_symtabs_matching_symbol ()
   {
     CHECK_MATCH ("w", symbol_name_match_type::FULL, true,
 		 EXPECT ("w1::w2"));
+    CHECK_MATCH ("w", symbol_name_match_type::WILD, true,
+		 EXPECT ("w1::w2"));
   }
 
   /* Same, with a "complicated" symbol.  */
@@ -4817,6 +4821,10 @@ test_dw2_expand_symtabs_matching_symbol ()
   {
     CHECK_MATCH ("std::zfunction(int)", symbol_name_match_type::FULL, true,
 		 EXPECT ("std::zfunction", "std::zfunction2"));
+    CHECK_MATCH ("zfunction(int)", symbol_name_match_type::WILD, true,
+		 EXPECT ("std::zfunction", "std::zfunction2"));
+    CHECK_MATCH ("zfunc", symbol_name_match_type::WILD, true,
+		 EXPECT ("std::zfunction", "std::zfunction2"));
   }
 
   /* Check that whitespace is ignored appropriately.  A symbol with a
@@ -4825,6 +4833,8 @@ test_dw2_expand_symtabs_matching_symbol ()
     static const char expected[] = "ns::foo<int>";
     CHECK_MATCH ("ns :: foo < int > ", symbol_name_match_type::FULL, false,
 		 EXPECT (expected));
+    CHECK_MATCH ("foo < int > ", symbol_name_match_type::WILD, false,
+		 EXPECT (expected));
   }
 
   /* Check that whitespace is ignored appropriately.  A symbol with a
@@ -4837,9 +4847,13 @@ test_dw2_expand_symtabs_matching_symbol ()
       {
 	CHECK_MATCH ("ns :: foo < char * >", symbol_name_match_type::FULL,
 		     completion_mode[i], EXPECT (expected));
+	CHECK_MATCH ("foo < char * >", symbol_name_match_type::WILD,
+		     completion_mode[i], EXPECT (expected));
 
 	CHECK_MATCH ("ns :: foo < char * > (int)", symbol_name_match_type::FULL,
 		     completion_mode[i], EXPECT (expected));
+	CHECK_MATCH ("foo < char * > (int)", symbol_name_match_type::WILD,
+		     completion_mode[i], EXPECT (expected));
       }
   }
 
@@ -4850,14 +4864,48 @@ test_dw2_expand_symtabs_matching_symbol ()
 		 symbol_name_match_type::FULL, true, EXPECT (expected));
     CHECK_MATCH ("ns :: foo < char * >  ( int ) &&",
 		 symbol_name_match_type::FULL, true, EXPECT (expected));
+    CHECK_MATCH ("foo < char * >  ( int ) const",
+		 symbol_name_match_type::WILD, true, EXPECT (expected));
+    CHECK_MATCH ("foo < char * >  ( int ) &&",
+		 symbol_name_match_type::WILD, true, EXPECT (expected));
   }
 
   /* Test lookup names that don't match anything.  */
   {
+    CHECK_MATCH ("bar2", symbol_name_match_type::WILD, false,
+		 {});
+
     CHECK_MATCH ("doesntexist", symbol_name_match_type::FULL, false,
 		 {});
   }
 
+  /* Some wild matching tests, exercising "(anonymous namespace)",
+     which should not be confused with a parameter list.  */
+  {
+    static const char *syms[] = {
+      "A::B::C",
+      "B::C",
+      "C",
+      "A :: B :: C ( int )",
+      "B :: C ( int )",
+      "C ( int )",
+    };
+
+    for (const char *s : syms)
+      {
+	CHECK_MATCH (s, symbol_name_match_type::WILD, false,
+		     EXPECT ("(anonymous namespace)::A::B::C"));
+      }
+  }
+
+  {
+    static const char expected[] = "ns2::tmpl<int>::foo2";
+    CHECK_MATCH ("tmp", symbol_name_match_type::WILD, true,
+		 EXPECT (expected));
+    CHECK_MATCH ("tmpl<", symbol_name_match_type::WILD, true,
+		 EXPECT (expected));
+  }
+
   SELF_CHECK (!any_mismatch);
 
 #undef EXPECT
diff --git a/gdb/guile/scm-breakpoint.c b/gdb/guile/scm-breakpoint.c
index ec75be5..f84815e 100644
--- a/gdb/guile/scm-breakpoint.c
+++ b/gdb/guile/scm-breakpoint.c
@@ -424,8 +424,10 @@ gdbscm_register_breakpoint_x (SCM self)
   pending_breakpoint_scm = self;
   location = bp_smob->spec.location;
   copy = skip_spaces (location);
-  event_location_up eloc = string_to_event_location_basic (&copy,
-							   current_language);
+  event_location_up eloc
+    = string_to_event_location_basic (&copy,
+				      current_language,
+				      symbol_name_match_type::WILD);
 
   TRY
     {
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 3f7f171..ff7671e 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -359,6 +359,7 @@ static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
 static void find_linespec_symbols (struct linespec_state *self,
 				   VEC (symtab_ptr) *file_symtabs,
 				   const char *name,
+				   symbol_name_match_type name_match_type,
 				   VEC (symbolp) **symbols,
 				   VEC (bound_minimal_symbol_d) **minsyms);
 
@@ -1865,9 +1866,12 @@ linespec_parse_basic (linespec_parser *parser)
 	  completion_tracker tmp_tracker;
 	  const char *source_filename
 	    = PARSER_EXPLICIT (parser)->source_filename;
+	  symbol_name_match_type match_type
+	    = PARSER_EXPLICIT (parser)->func_name_match_type;
 
 	  linespec_complete_function (tmp_tracker,
 				      parser->completion_word,
+				      match_type,
 				      source_filename);
 
 	  if (tmp_tracker.have_completions ())
@@ -1892,6 +1896,7 @@ linespec_parse_basic (linespec_parser *parser)
   /* Try looking it up as a function/method.  */
   find_linespec_symbols (PARSER_STATE (parser),
 			 PARSER_RESULT (parser)->file_symtabs, name,
+			 PARSER_EXPLICIT (parser)->func_name_match_type,
 			 &symbols, &minimal_symbols);
 
   if (symbols != NULL || minimal_symbols != NULL)
@@ -2383,6 +2388,7 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
 				       linespec_p result,
 				       const char *source_filename,
 				       const char *function_name,
+				       symbol_name_match_type fname_match_type,
 				       const char *label_name,
 				       struct line_offset line_offset)
 {
@@ -2412,8 +2418,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
   if (function_name != NULL)
     {
       find_linespec_symbols (self, result->file_symtabs,
-			     function_name, &symbols,
-			     &minimal_symbols);
+			     function_name, fname_match_type,
+			     &symbols, &minimal_symbols);
 
       if (symbols == NULL && minimal_symbols == NULL)
 	symbol_not_found_error (function_name,
@@ -2453,6 +2459,7 @@ convert_explicit_location_to_sals (struct linespec_state *self,
   convert_explicit_location_to_linespec (self, result,
 					 explicit_loc->source_filename,
 					 explicit_loc->function_name,
+					 explicit_loc->func_name_match_type,
 					 explicit_loc->label_name,
 					 explicit_loc->line_offset);
   return convert_linespec_to_sals (self, result);
@@ -2506,10 +2513,12 @@ convert_explicit_location_to_sals (struct linespec_state *self,
    if no file is validly specified.  Callers must check that.
    Also, the line number returned may be invalid.  */
 
-/* Parse the linespec in ARG.  */
+/* Parse the linespec in ARG.  MATCH_TYPE indicates how function names
+   should be matched.  */
 
 static std::vector<symtab_and_line>
-parse_linespec (linespec_parser *parser, const char *arg)
+parse_linespec (linespec_parser *parser, const char *arg,
+		symbol_name_match_type match_type)
 {
   linespec_token token;
   struct gdb_exception file_exception = exception_none;
@@ -2539,6 +2548,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
   parser->lexer.stream = arg;
   parser->completion_word = arg;
   parser->complete_what = linespec_complete_what::FUNCTION;
+  PARSER_EXPLICIT (parser)->func_name_match_type = match_type;
 
   /* Initialize the default symtab and line offset.  */
   initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@@ -2747,6 +2757,8 @@ linespec_parser_new (linespec_parser *parser,
   memset (parser, 0, sizeof (linespec_parser));
   parser->lexer.current.type = LSTOKEN_CONSUMED;
   memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
+  PARSER_EXPLICIT (parser)->func_name_match_type
+    = symbol_name_match_type::WILD;
   PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
   linespec_state_constructor (PARSER_STATE (parser), flags, language,
 			      search_pspace,
@@ -2828,10 +2840,10 @@ linespec_lex_to_end (const char **stringp)
 void
 linespec_complete_function (completion_tracker &tracker,
 			    const char *function,
+			    symbol_name_match_type func_match_type,
 			    const char *source_filename)
 {
   complete_symbol_mode mode = complete_symbol_mode::LINESPEC;
-  symbol_name_match_type func_match_type = symbol_name_match_type::WILD;
 
   if (source_filename != NULL)
     {
@@ -2870,7 +2882,9 @@ complete_linespec_component (linespec_parser *parser,
     {
       completion_list fn_list;
 
-      linespec_complete_function (tracker, text, source_filename);
+      symbol_name_match_type match_type
+	= PARSER_EXPLICIT (parser)->func_name_match_type;
+      linespec_complete_function (tracker, text, match_type, source_filename);
       if (source_filename == NULL)
 	{
 	  /* Haven't seen a source component, like in "b
@@ -2940,6 +2954,7 @@ linespec_complete_label (completion_tracker &tracker,
 			 const struct language_defn *language,
 			 const char *source_filename,
 			 const char *function_name,
+			 symbol_name_match_type func_name_match_type,
 			 const char *label_name)
 {
   linespec_parser parser;
@@ -2956,6 +2971,7 @@ linespec_complete_label (completion_tracker &tracker,
 					     PARSER_RESULT (&parser),
 					     source_filename,
 					     function_name,
+					     func_name_match_type,
 					     NULL, unknown_offset);
     }
   CATCH (ex, RETURN_MASK_ERROR)
@@ -2973,7 +2989,8 @@ linespec_complete_label (completion_tracker &tracker,
 /* See description in linespec.h.  */
 
 void
-linespec_complete (completion_tracker &tracker, const char *text)
+linespec_complete (completion_tracker &tracker, const char *text,
+		   symbol_name_match_type match_type)
 {
   linespec_parser parser;
   struct cleanup *cleanup;
@@ -2982,6 +2999,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
   linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
   cleanup = make_cleanup (linespec_parser_delete, &parser);
   parser.lexer.saved_arg = text;
+  PARSER_EXPLICIT (&parser)->func_name_match_type = match_type;
   PARSER_STREAM (&parser) = text;
 
   parser.completion_tracker = &tracker;
@@ -2991,7 +3009,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
      furthest completion point we managed to parse to.  */
   TRY
     {
-      parse_linespec (&parser, text);
+      parse_linespec (&parser, text, match_type);
     }
   CATCH (except, RETURN_MASK_ERROR)
     {
@@ -3039,7 +3057,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
       VEC (bound_minimal_symbol_d) *minimal_symbols;
       find_linespec_symbols (PARSER_STATE (&parser),
 			     PARSER_RESULT (&parser)->file_symtabs,
-			     func_name,
+			     func_name, match_type,
 			     &function_symbols, &minimal_symbols);
 
       PARSER_RESULT (&parser)->function_symbols = function_symbols;
@@ -3181,7 +3199,9 @@ event_location_to_sals (linespec_parser *parser,
 	PARSER_STATE (parser)->is_linespec = 1;
 	TRY
 	  {
-	    result = parse_linespec (parser, get_linespec_location (location));
+	    const linespec_location *ls = get_linespec_location (location);
+	    result = parse_linespec (parser,
+				     ls->spec_string, ls->match_type);
 	  }
 	CATCH (except, RETURN_MASK_ERROR)
 	  {
@@ -3492,7 +3512,8 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
 	  else
 	    str = saved_arg;
 
-	  self->canonical->location = new_linespec_location (&str);
+	  self->canonical->location
+	    = new_linespec_location (&str, symbol_name_match_type::FULL);
 	}
     }
 
@@ -3936,6 +3957,7 @@ symtabs_from_filename (const char *filename,
 static void
 find_function_symbols (struct linespec_state *state,
 		       VEC (symtab_ptr) *file_symtabs, const char *name,
+		       symbol_name_match_type name_match_type,
 		       VEC (symbolp) **symbols,
 		       VEC (bound_minimal_symbol_d) **minsyms)
 {
@@ -3955,8 +3977,7 @@ find_function_symbols (struct linespec_state *state,
     add_all_symbol_names_from_pspace (&info, state->search_pspace,
 				      symbol_names, FUNCTIONS_DOMAIN);
   else
-    add_matching_symbols_to_info (name, symbol_name_match_type::WILD,
-				  FUNCTIONS_DOMAIN,
+    add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
 				  &info, state->search_pspace);
 
   do_cleanups (cleanup);
@@ -3985,6 +4006,7 @@ static void
 find_linespec_symbols (struct linespec_state *state,
 		       VEC (symtab_ptr) *file_symtabs,
 		       const char *lookup_name,
+		       symbol_name_match_type name_match_type,
 		       VEC (symbolp) **symbols,
 		       VEC (bound_minimal_symbol_d) **minsyms)
 {
@@ -4002,6 +4024,7 @@ find_linespec_symbols (struct linespec_state *state,
      2) break class::method where method is in class (and not a baseclass)  */
 
   find_function_symbols (state, file_symtabs, lookup_name,
+			 name_match_type,
 			 symbols, minsyms);
 
   /* If we were unable to locate a symbol of the same name, try dividing
diff --git a/gdb/linespec.h b/gdb/linespec.h
index b955728..85beb62 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -180,14 +180,17 @@ extern const char * const linespec_keywords[];
 /* Complete a linespec.  */
 
 extern void linespec_complete (completion_tracker &tracker,
-			       const char *text);
+			       const char *text,
+			       symbol_name_match_type match_type);
 
-/* Complete a function symbol, in linespec mode.  If SOURCE_FILENAME
-   is non-NULL, limits completion to the list of functions defined in
-   source files that match SOURCE_FILENAME.  */
+/* Complete a function symbol, in linespec mode, according to
+   FUNC_MATCH_TYPE.  If SOURCE_FILENAME is non-NULL, limits completion
+   to the list of functions defined in source files that match
+   SOURCE_FILENAME.  */
 
 extern void linespec_complete_function (completion_tracker &tracker,
 					const char *function,
+					symbol_name_match_type func_match_type,
 					const char *source_filename);
 
 /* Complete a label symbol, in linespec mode.  Only labels of
@@ -199,6 +202,7 @@ extern void linespec_complete_label (completion_tracker &tracker,
 				     const struct language_defn *language,
 				     const char *source_filename,
 				     const char *function_name,
+				     symbol_name_match_type name_match_type,
 				     const char *label_name);
 
 /* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR,
diff --git a/gdb/location.c b/gdb/location.c
index 5ed3623..6752462 100644
--- a/gdb/location.c
+++ b/gdb/location.c
@@ -41,13 +41,14 @@ struct event_location
 
   union
   {
-    /* A generic "this is a string specification" for a location.
-       This representation is used by both "normal" linespecs and
-       probes.  */
+    /* A probe.  */
     char *addr_string;
-#define EL_LINESPEC(P) ((P)->u.addr_string)
 #define EL_PROBE(P) ((P)->u.addr_string)
 
+    /* A "normal" linespec.  */
+    struct linespec_location linespec_location;
+#define EL_LINESPEC(P) (&(P)->u.linespec_location)
+
     /* An address in the inferior.  */
     CORE_ADDR address;
 #define EL_ADDRESS(P) (P)->u.address
@@ -78,17 +79,20 @@ initialize_explicit_location (struct explicit_location *explicit_loc)
 {
   memset (explicit_loc, 0, sizeof (struct explicit_location));
   explicit_loc->line_offset.sign = LINE_OFFSET_UNKNOWN;
+  explicit_loc->func_name_match_type = symbol_name_match_type::WILD;
 }
 
 /* See description in location.h.  */
 
 event_location_up
-new_linespec_location (const char **linespec)
+new_linespec_location (const char **linespec,
+		       symbol_name_match_type match_type)
 {
   struct event_location *location;
 
   location = XCNEW (struct event_location);
   EL_TYPE (location) = LINESPEC_LOCATION;
+  EL_LINESPEC (location)->match_type = match_type;
   if (*linespec != NULL)
     {
       const char *p;
@@ -97,14 +101,14 @@ new_linespec_location (const char **linespec)
       linespec_lex_to_end (linespec);
       p = remove_trailing_whitespace (orig, *linespec);
       if ((p - orig) > 0)
-	EL_LINESPEC (location) = savestring (orig, p - orig);
+	EL_LINESPEC (location)->spec_string = savestring (orig, p - orig);
     }
   return event_location_up (location);
 }
 
 /* See description in location.h.  */
 
-const char *
+const linespec_location *
 get_linespec_location (const struct event_location *location)
 {
   gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION);
@@ -180,6 +184,9 @@ new_explicit_location (const struct explicit_location *explicit_loc)
   initialize_explicit_location (EL_EXPLICIT (&tmp));
   if (explicit_loc != NULL)
     {
+      EL_EXPLICIT (&tmp)->func_name_match_type
+	= explicit_loc->func_name_match_type;
+
       if (explicit_loc->source_filename != NULL)
 	{
 	  EL_EXPLICIT (&tmp)->source_filename
@@ -244,6 +251,8 @@ explicit_to_string_internal (int as_linespec,
     {
       if (need_space)
 	buf.putc (space);
+      if (explicit_loc->func_name_match_type == symbol_name_match_type::FULL)
+	buf.puts ("-qualified ");
       if (!as_linespec)
 	buf.puts ("-function ");
       buf.puts (explicit_loc->function_name);
@@ -307,8 +316,10 @@ copy_event_location (const struct event_location *src)
   switch (EL_TYPE (src))
     {
     case LINESPEC_LOCATION:
-      if (EL_LINESPEC (src) != NULL)
-	EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src));
+      EL_LINESPEC (dst)->match_type = EL_LINESPEC (src)->match_type;
+      if (EL_LINESPEC (src)->spec_string != NULL)
+	EL_LINESPEC (dst)->spec_string
+	  = xstrdup (EL_LINESPEC (src)->spec_string);
       break;
 
     case ADDRESS_LOCATION:
@@ -316,6 +327,8 @@ copy_event_location (const struct event_location *src)
       break;
 
     case EXPLICIT_LOCATION:
+      EL_EXPLICIT (dst)->func_name_match_type
+	= EL_EXPLICIT (src)->func_name_match_type;
       if (EL_EXPLICIT (src)->source_filename != NULL)
 	EL_EXPLICIT (dst)->source_filename
 	  = xstrdup (EL_EXPLICIT (src)->source_filename);
@@ -353,7 +366,7 @@ event_location_deleter::operator() (event_location *location) const
       switch (EL_TYPE (location))
 	{
 	case LINESPEC_LOCATION:
-	  xfree (EL_LINESPEC (location));
+	  xfree (EL_LINESPEC (location)->spec_string);
 	  break;
 
 	case ADDRESS_LOCATION:
@@ -388,8 +401,17 @@ event_location_to_string (struct event_location *location)
       switch (EL_TYPE (location))
 	{
 	case LINESPEC_LOCATION:
-	  if (EL_LINESPEC (location) != NULL)
-	    EL_STRING (location) = xstrdup (EL_LINESPEC (location));
+	  if (EL_LINESPEC (location)->spec_string != NULL)
+	    {
+	      linespec_location *ls = EL_LINESPEC (location);
+	      if (ls->match_type == symbol_name_match_type::FULL)
+		{
+		  EL_STRING (location)
+		    = concat ("-qualified ", ls->spec_string, (char *) NULL);
+		}
+	      else
+		EL_STRING (location) = xstrdup (ls->spec_string);
+	    }
 	  break;
 
 	case ADDRESS_LOCATION:
@@ -756,12 +778,23 @@ string_to_explicit_location (const char **argp,
 	 argument.  */
       bool have_oarg = false;
 
+      /* True if the option needs an argument.  */
+      bool need_oarg = false;
+
       /* Convenience to consistently set both OARG/HAVE_OARG from
 	 ARG.  */
       auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg)
 	{
+	  if (completion_info != NULL)
+	    {
+	      /* We do this here because the set of options that take
+		 arguments matches the set of explicit location
+		 options.  */
+	      completion_info->saw_explicit_location_option = true;
+	    }
 	  oarg = std::move (arg);
 	  have_oarg = oarg != NULL;
+	  need_oarg = true;
 	};
 
       if (strncmp (opt.get (), "-source", len) == 0)
@@ -776,6 +809,11 @@ string_to_explicit_location (const char **argp,
 							completion_info));
 	  EL_EXPLICIT (location)->function_name = oarg.release ();
 	}
+      else if (strncmp (opt.get (), "-qualified", len) == 0)
+	{
+	  EL_EXPLICIT (location)->func_name_match_type
+	    = symbol_name_match_type::FULL;
+	}
       else if (strncmp (opt.get (), "-line", len) == 0)
 	{
 	  set_oarg (explicit_location_lex_one (argp, language, NULL));
@@ -814,7 +852,7 @@ string_to_explicit_location (const char **argp,
 	 case, it provides a much better user experience to issue
 	 the "invalid argument" error before any missing
 	 argument error.  */
-      if (!have_oarg && completion_info == NULL)
+      if (need_oarg && !have_oarg && completion_info == NULL)
 	error (_("missing argument for \"%s\""), opt.get ());
     }
 
@@ -837,7 +875,8 @@ string_to_explicit_location (const char **argp,
 
 event_location_up
 string_to_event_location_basic (const char **stringp,
-				const struct language_defn *language)
+				const struct language_defn *language,
+				symbol_name_match_type match_type)
 {
   event_location_up location;
   const char *cs;
@@ -865,7 +904,7 @@ string_to_event_location_basic (const char **stringp,
       else
 	{
 	  /* Everything else is a linespec.  */
-	  location = new_linespec_location (stringp);
+	  location = new_linespec_location (stringp, match_type);
 	}
     }
 
@@ -879,6 +918,7 @@ string_to_event_location (const char **stringp,
 			  const struct language_defn *language)
 {
   const char *arg, *orig;
+  symbol_name_match_type match_type = symbol_name_match_type::WILD;
 
   /* Try an explicit location.  */
   orig = arg = *stringp;
@@ -888,15 +928,21 @@ string_to_event_location (const char **stringp,
       /* It was a valid explicit location.  Advance STRINGP to
 	 the end of input.  */
       *stringp += arg - orig;
-    }
-  else
-    {
-      /* Everything else is a "basic" linespec, address, or probe
-	 location.  */
-      location = string_to_event_location_basic (stringp, language);
+
+      /* If the user really specified a location, then we're done.  */
+      if (!event_location_empty_p (location.get ()))
+	return location;
+
+      /* Otherwise, the user _only_ specified optional flags like
+	 "-qualified", otherwise string_to_explicit_location would
+	 have thrown an error.  Save the flags for "basic" linespec
+	 parsing below and discard the explicit location.  */
+      match_type = EL_EXPLICIT (location)->func_name_match_type;
     }
 
-  return location;
+  /* Everything else is a "basic" linespec, address, or probe
+     location.  */
+  return string_to_event_location_basic (stringp, language, match_type);
 }
 
 /* See description in location.h.  */
diff --git a/gdb/location.h b/gdb/location.h
index d954eac..fcfa8fb 100644
--- a/gdb/location.h
+++ b/gdb/location.h
@@ -66,6 +66,17 @@ enum event_location_type
   PROBE_LOCATION
 };
 
+/* A traditional linespec.  */
+
+struct linespec_location
+{
+  /* Whether the function name is fully-qualified or not.  */
+  symbol_name_match_type match_type;
+
+  /* The linespec.  */
+  char *spec_string;
+};
+
 /* An explicit location.  This structure is used to bypass the
    parsing done on linespecs.  It still has the same requirements
    as linespecs, though.  For example, source_filename requires
@@ -79,6 +90,9 @@ struct explicit_location
   /* The function name.  Malloc'd.  */
   char *function_name;
 
+  /* Whether the function name is fully-qualified or not.  */
+  symbol_name_match_type func_name_match_type;
+
   /* The name of a label.  Malloc'd.  */
   char *label_name;
 
@@ -107,7 +121,7 @@ extern char *
 
 /* Return a string representation of the LOCATION.
    This function may return NULL for unspecified linespecs,
-   e.g, LOCATION_LINESPEC and addr_string is NULL.
+   e.g, LINESPEC_LOCATION and spec_string is NULL.
 
    The result is cached in LOCATION.  */
 
@@ -127,12 +141,13 @@ typedef std::unique_ptr<event_location, event_location_deleter>
 
 /* Create a new linespec location.  */
 
-extern event_location_up new_linespec_location (const char **linespec);
+extern event_location_up new_linespec_location
+  (const char **linespec, symbol_name_match_type match_type);
 
-/* Return the linespec location (a string) of the given event_location
-   (which must be of type LINESPEC_LOCATION).  */
+/* Return the linespec location of the given event_location (which
+   must be of type LINESPEC_LOCATION).  */
 
-extern const char *
+extern const linespec_location *
   get_linespec_location (const struct event_location *location);
 
 /* Create a new address location.
@@ -211,12 +226,14 @@ extern event_location_up
   string_to_event_location (const char **argp,
 			    const struct language_defn *langauge);
 
-/* Like string_to_event_location, but does not attempt to parse explicit
-   locations.  */
+/* Like string_to_event_location, but does not attempt to parse
+   explicit locations.  MATCH_TYPE indicates how function names should
+   be matched.  */
 
 extern event_location_up
   string_to_event_location_basic (const char **argp,
-				  const struct language_defn *language);
+				  const struct language_defn *language,
+				  symbol_name_match_type match_type);
 
 /* Structure filled in by string_to_explicit_location to aid the
    completer.  */
@@ -233,6 +250,11 @@ struct explicit_completion_info
      If the last option is not quoted, then both are set to NULL. */
   const char *quoted_arg_start = NULL;
   const char *quoted_arg_end = NULL;
+
+  /* True if we saw an explicit location option, as opposed to only
+     flags that affect both explicit locations and linespecs, like
+     "-qualified".  */
+  bool saw_explicit_location_option = false;
 };
 
 /* Attempt to convert the input string in *ARGP into an explicit location.
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index 833bdc0..6cb1d71 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -337,7 +337,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
     }
   else
     {
-      location = string_to_event_location_basic (&address, current_language);
+      location = string_to_event_location_basic (&address, current_language,
+						 symbol_name_match_type::WILD);
       if (*address)
 	error (_("Garbage '%s' at end of location"), address);
     }
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 86719d1..5bc073e 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -681,7 +681,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 	case bp_breakpoint:
 	  {
 	    event_location_up location
-	      = string_to_event_location_basic (&copy, current_language);
+	      = string_to_event_location_basic (&copy, current_language,
+						symbol_name_match_type::WILD);
 	    create_breakpoint (python_gdbarch,
 			       location.get (), NULL, -1, NULL,
 			       0,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 9ed9b6b..c29a46b 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -838,7 +838,8 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
     return NULL;
 
   if (arg != NULL)
-    location = string_to_event_location_basic (&arg, python_language);
+    location = string_to_event_location_basic (&arg, python_language,
+					       symbol_name_match_type::WILD);
 
   std::vector<symtab_and_line> decoded_sals;
   symtab_and_line def_sal;
diff --git a/gdb/testsuite/gdb.base/langs.exp b/gdb/testsuite/gdb.base/langs.exp
index 8dcd5ee..03c690c 100644
--- a/gdb/testsuite/gdb.base/langs.exp
+++ b/gdb/testsuite/gdb.base/langs.exp
@@ -38,7 +38,7 @@ if [get_compiler_info] {
     return -1
 }
 
-gdb_test_multiple "b langs0" "break on nonexistent function in langs.exp" {
+gdb_test_multiple "b -qualified langs0" "break on nonexistent function in langs.exp" {
 	-re "Function \"langs0\" not defined\..*Make breakpoint pending on future shared library load.*y or .n.. $" {
 
 		gdb_test "n" "" "break on nonexistent function in langs.exp"
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp
index 08f1464..50690ab 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.exp
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp
@@ -145,15 +145,42 @@ foreach test $methods {
     set func [lindex $test 0]
     set result [lindex $test 1]
 
-    gdb_test "list $func" $result
-    gdb_test "list '$func'" $result
-    if {[gdb_breakpoint $func]} {
-      pass "break $func"
+    gdb_test "list -qualified $func" $result
+    gdb_test "list -qualified '$func'" $result
+    if {[gdb_breakpoint "-qualified $func"]} {
+      pass "break -qualified $func"
     }
-    if {[gdb_breakpoint '$func']} {
-      pass "break '$func'"
+    if {[gdb_breakpoint "-qualified '$func'"]} {
+      pass "break -qualified '$func'"
     }
 }
 
+# The tests above use -qualified to explicitly pick the one "test"
+# symbol each test cares about.  Now check that both "break test(..)"
+# and "list test(..)" without -qualified find "test(..)" in all the 3
+# scopes that have the this particular overload.
+set func "test(aenum, astruct const&, aunion const***)"
+set func_re "test\\(anon_enum, anon_struct const&, anon_union const\\*\\*\\*\\)"
+set line1 [gdb_get_line_number " A::FOO::$func"]
+set line2 [gdb_get_line_number " B::$func"]
+set line3 [gdb_get_line_number " $func"]
+
+foreach f [list "$func" "'$func'"] {
+    set any "\[^\r\n\]*"
+    gdb_test \
+	"list $f" \
+	[multi_line \
+	     "file: \".*$srcfile\", line number: $line1, symbol: \"A::foo::$func_re\"" \
+	     "$line1${any}A::FOO::test${any}" \
+	     "file: \".*$srcfile\", line number: $line2, symbol: \"B::$func_re\"" \
+	     "$line2${any}B::test${any}" \
+	     "file: \".*$srcfile\", line number: $line3, symbol: \"$func_re\"" \
+	     "$line3${any}// test${any}"] \
+	"list $f"
+
+    delete_breakpoints
+    gdb_test "break $f" "\\(3 locations\\)"
+}
+
 gdb_exit
 return 0
diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp
index 640ee4f..4a6b863 100644
--- a/gdb/testsuite/gdb.cp/namespace.exp
+++ b/gdb/testsuite/gdb.cp/namespace.exp
@@ -120,7 +120,7 @@ gdb_test "break AAA::xyzq" \
 
 # Break on a function in the global namespace.
 
-gdb_test "break ::ensureOtherRefs" \
+gdb_test "break -qualified ::ensureOtherRefs" \
     "Breakpoint.*at $hex: file.*$srcfile2, line $decimal\\."
 
 # Call a function in a nested namespace
diff --git a/gdb/testsuite/gdb.cp/save-bp-qualified.cc b/gdb/testsuite/gdb.cp/save-bp-qualified.cc
new file mode 100644
index 0000000..8dc2682
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/save-bp-qualified.cc
@@ -0,0 +1,40 @@
+/* Copyright 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+struct S
+{
+  static void function ();
+};
+
+void
+S::function ()
+{
+}
+
+void
+function ()
+{
+}
+
+int
+main ()
+{
+  S::function ();
+  function ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/save-bp-qualified.exp b/gdb/testsuite/gdb.cp/save-bp-qualified.exp
new file mode 100644
index 0000000..8498f24
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/save-bp-qualified.exp
@@ -0,0 +1,74 @@
+# Copyright (C) 2011-2017 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/>.
+
+# Test "save breakpoints" + "break -qualified".
+
+standard_testfile .cc
+
+if { [build_executable "failed to prepare" ${testfile} $srcfile {debug c++}] } {
+    return -1
+}
+
+proc restart {} {
+    global testfile
+
+    clean_restart $testfile
+
+    if ![runto_main] {
+	untested "could not run to main"
+	return 0
+    }
+    # Delete all breakpoints so that the "runto_main" breakpoint above
+    # does not interfere with our testing.
+    delete_breakpoints
+
+    return 1
+}
+
+with_test_prefix "save" {
+    if ![restart] {
+	return -1
+    }
+
+    gdb_breakpoint "function" qualified
+    gdb_breakpoint "function"
+
+    # Save the breakpoints into a file.
+    if {[is_remote host]} {
+	set bps bps
+    } else {
+	set bps [standard_output_file bps]
+    }
+    remote_file host delete "$bps"
+    gdb_test "save breakpoint $bps" "" "save breakpoint bps"
+}
+
+with_test_prefix "restore" {
+    if ![restart] {
+	return -1
+    }
+
+    # Restore the breakpoints.
+    gdb_test "source $bps" "" "source bps"
+
+    # Verify that all breakpoints have been created correctly.
+    gdb_test "info break" [multi_line \
+      "Num +Type +Disp +Enb +Address +What" \
+      "$decimal +breakpoint +keep +y +$hex +in function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+      "$decimal +breakpoint +keep +y +<MULTIPLE> +" \
+      "$decimal.$decimal +y +$hex +in S::function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+      "$decimal.$decimal +y +$hex +in function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+    ]
+}
diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp
index 873dc78..4031b4a 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 looked name don'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 9cf0162..b592d29 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" {
diff --git a/gdb/testsuite/lib/completion-support.exp b/gdb/testsuite/lib/completion-support.exp
index 25332cc..c7cc1c9 100644
--- a/gdb/testsuite/lib/completion-support.exp
+++ b/gdb/testsuite/lib/completion-support.exp
@@ -30,7 +30,7 @@ namespace eval completion {
     variable keyword_list {"if" "task" "thread"}
 
     variable explicit_opts_list \
-	{"-function" "-label" "-line" "-source"}
+	{"-function" "-label" "-line" "-qualified" "-source"}
 }
 
 # Make a regular expression that matches a TAB completion list.
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 8d6972a..fc0278b 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -422,7 +422,7 @@ proc gdb_starti_cmd {args} {
 
 # Set a breakpoint at FUNCTION.  If there is an additional argument it is
 # a list of options; the supported options are allow-pending, temporary,
-# message, no-message, and passfail.
+# message, no-message, passfail and qualified.
 # The result is 1 for success, 0 for failure.
 #
 # Note: The handling of message vs no-message is messed up, but it's based
@@ -447,6 +447,10 @@ proc gdb_breakpoint { function args } {
 	set break_message "Temporary breakpoint"
     }
 
+    if {[lsearch -exact $args qualified] != -1} {
+	append break_command " -qualified"
+    }
+
     set print_pass 0
     set print_fail 1
     set no_message_loc [lsearch -exact $args no-message]
-- 
2.5.5



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]