public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436)
  2017-11-27 17:13 [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
  2017-11-27 17:13 ` [PATCH v2 1/3] Handle custom completion match prefix / LCD Pedro Alves
@ 2017-11-27 17:13 ` Pedro Alves
  2017-11-28  3:47   ` Keith Seitz
  2017-11-27 17:14 ` [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
  2017-11-27 17:33 ` [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
  3 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2017-11-27 17:13 UTC (permalink / raw)
  To: gdb-patches

In v2:

  - Nothing really changed.  This is still here because it depends on
    infrastructure added by patch #1.

  - Documentation bits were already approved:
    https://sourceware.org/ml/gdb-patches/2017-06/msg00664.html

  - I've addressed Keith's nit at:
    https://sourceware.org/ml/gdb-patches/2017-08/msg00206.html
~~~~~~

Trying to set a breakpoint in a function with an ABI tag does not work
currently.  E.g., debugging gdb itself, we see this with the
"string_printf" function:

 (top-gdb) b string_print                               [TAB]
 (top-gdb) b string_printf[abi:cxx11](char const*, ...) [RET]
 No source file named string_printf[abi.
 Make breakpoint pending on future shared library load? (y or [n])

Quoting doesn't help:
 (top-gdb) b 'string_printf[abi:cxx11]'(char const*, ...)
 malformed linespec error: unexpected string, "(char const*, ...)"
 (top-gdb) b 'string_printf[abi:cxx11](char const*, ...)'
 No source file named string_printf[abi.
 Make breakpoint pending on future shared library load? (y or [n]) n

This patch fixes this, and takes it a bit further.

The actual symbol name as demangled by libiberty's demangler is really

 string_printf[abi:cxx11](char const*, ...)

however, this patch makes it possible to set the breakpoint with

 string_printf(char const*, ...)

too.  I.e., ignoring the ABI tag.

And to match, it teaches the completer to complete the symbol name
without the ABI tag, i.e.,

  "string_pri<TAB>"  -> "string_printf(char const*, ...)"

If however, you really want to break on a symbol with the tag, then
you simply start writing the tag, and GDB will preserve it, like:

  "string_printf[a<TAB>"  -> "string_printf[abi:cxx11](char const*, ...)"

Grows the gdb.linespec/ tests like this:

  -# of expected passes           8977
  +# of expected passes           9176

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	PR c++/19436
	* NEWS: Mention setting breakpoints on functions with C++ ABI
	tags.
	* completer.h (completion_match_for_lcd) <match,
	mark_ignored_range>: New methods.
	<finish>: Consider ignored ranges.
	<clear>: Clear ignored ranges.
	<m_ignored_ranges, m_finished_storage>: New fields.
	* cp-support.c (cp_search_name_hash): Ignore ABI tags.
	(cp_symbol_name_matches_1, cp_fq_symbol_name_matches): Pass the
	completion_match_for_lcd pointer to strncmp_iw_with_mode.
	(test_cp_symbol_name_cmp): Add [abi:...] tags unit tests.
	* language.c (default_symbol_name_matcher): Pass the
	completion_match_for_lcd pointer to strncmp_iw_with_mode.
	* linespec.c (linespec_lexer_lex_string): Don't tokenize ABI tags.
	* utils.c (skip_abi_tag): New function.
	(strncmp_iw_with_mode): Add completion_match_for_lcd parameter.
	Handle ABI tags.
	* utils.h (strncmp_iw_with_mode): Add completion_match_for_lcd
	parameter.

gdb/testsuite/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	PR c++/19436
	* gdb.linespec/cpls-abi-tag.cc: New file.
	* gdb.linespec/cpls-abi-tag.exp: New file.

gdb/doc/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	PR c++/19436
	* gdb.texinfo (Debugging C Plus Plus): Document setting
	breakpoints in functions with ABI tags.
---
 gdb/doc/gdb.texinfo                         |  43 +++++
 gdb/NEWS                                    |  22 +++
 gdb/completer.h                             |  62 +++++-
 gdb/cp-support.c                            |  53 +++++-
 gdb/language.c                              |   5 +-
 gdb/linespec.c                              |   5 +
 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc  |  93 +++++++++
 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp | 286 ++++++++++++++++++++++++++++
 gdb/utils.c                                 |  96 +++++++++-
 gdb/utils.h                                 |  16 +-
 10 files changed, 663 insertions(+), 18 deletions(-)
 create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc
 create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7a71739..4f55222 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15128,6 +15128,49 @@ the same notation that is used to declare such symbols in C@t{++}: type
 also use the @value{GDBN} command-line word completion facilities to list the
 available choices, or to finish the type list for you.
 @xref{Completion,, Command Completion}, for details on how to do this.
+
+@item @r{Breakpoints in functions with ABI tags}
+
+The GNU C@t{++} compiler introduced the notion of ABI ``tags'', which
+correspond to changes in the ABI of a type, function, or variable that
+would not otherwise be reflected in a mangled name.  See
+@url{https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/}
+for more detail.
+
+The ABI tags are visible in C@t{++} demangled names.  For example, a
+function that returns a std::string:
+
+@smallexample
+std::string function(int);
+@end smallexample
+
+@noindent
+when compiled for the C++11 ABI is marked with the @code{cxx11} ABI
+tag, and @value{GDBN} displays the symbol like this:
+
+@smallexample
+function[abi:cxx11](int)
+@end smallexample
+
+You can set a breakpoint on such functions simply as if they had no
+tag.  For example:
+
+@smallexample
+(gdb) b function(int)
+Breakpoint 2 at 0x40060d: file main.cc, line 10.
+(gdb) info breakpoints
+Num     Type           Disp Enb Address    What
+1       breakpoint     keep y   0x0040060d in function[abi:cxx11](int)
+                                           at main.cc:10
+@end smallexample
+
+On the rare occasion you need to disambiguate between different ABI
+tags, you can do so by simply including the ABI tag in the function
+name, like:
+
+@smallexample
+(@value{GDBP}) b ambiguous[abi:other_tag](int)
+@end smallexample
 @end table
 
 @node Decimal Floating Point
diff --git a/gdb/NEWS b/gdb/NEWS
index 984fd96..06df528 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -72,6 +72,28 @@
   program, the "break -q B::func" command sets a breakpoint on
   "B::func", only.
 
+* Breakpoints on functions marked with C++ ABI tags
+
+  GDB can now set breakpoints on functions marked with C++ ABI tags
+  (e.g., [abi:cxx11]).  See here for a description of ABI tags:
+  https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/
+
+  Functions with a C++11 abi tag are demangled/displayed like this:
+
+    function[abi:cxx11](int)
+            ^^^^^^^^^^^
+
+  You can now set a breakpoint on such functions simply as if they had
+  no tag, like:
+
+    (gdb) b function(int)
+
+  Or if you need to disambiguate between tags, like:
+
+    (gdb) b function[abi:other_tag](int)
+
+  Tab completion was adjusted accordingly as well.
+
 * Python Scripting
 
   ** New events gdb.new_inferior, gdb.inferior_deleted, and
diff --git a/gdb/completer.h b/gdb/completer.h
index f756412..9ce70bf 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -122,28 +122,82 @@ private:
    "b push_ba" on a C++ program usually completes to
    std::vector<...>::push_back, std::string::push_back etc.  In such
    case, the symbol comparison routine will set the LCD match to point
-   into the "push_back" substring within the symbol's name string.  */
+   into the "push_back" substring within the symbol's name string.
+   Also, in some cases, the symbol comparison routine will want to
+   ignore parts of the symbol name for LCD purposes, such as for
+   example symbols with abi tags in C++.  In such cases, the symbol
+   comparison routine will set MARK_IGNORED_RANGE to mark the ignored
+   substrings of the matched string.  The resulting LCD string with
+   the ignored parts stripped out is computed at the end of a
+   completion match sequence iff we had a positive match.  */
 
 class completion_match_for_lcd
 {
 public:
+  /* Get the resulting LCD, after a successful match.  */
+  const char *match ()
+  { return m_match; }
+
   /* Set the match for LCD.  See m_match's description.  */
   void set_match (const char *match)
   { m_match = match; }
 
-  /* Get the resulting LCD, after a successful match.  */
+  /* Mark the range between [BEGIN, END) as ignored.  */
+  void mark_ignored_range (const char *begin, const char *end)
+  { m_ignored_ranges.emplace_back (begin, end); }
+
+  /* Get the resulting LCD, after a successful match.  If there are
+     ignored ranges, then this builds a new string with the ignored
+     parts removed (and stores it internally).  As such, the result of
+     this call is only good for the current completion match
+     sequence.  */
   const char *finish ()
-  { return m_match; }
+  {
+    if (m_ignored_ranges.empty ())
+      return m_match;
+    else
+      {
+	m_finished_storage.clear ();
+
+	const char *prev = m_match;
+	for (const auto &range : m_ignored_ranges)
+	  {
+	    m_finished_storage.append (prev, range.first);
+	    prev = range.second;
+	  }
+	m_finished_storage.append (prev);
+
+	return m_finished_storage.c_str ();
+      }
+  }
 
   /* Prepare for another completion matching sequence.  */
   void clear ()
-  { m_match = NULL; }
+  {
+    m_match = NULL;
+    m_ignored_ranges.clear ();
+  }
 
 private:
   /* The completion match result for LCD.  This is usually either a
      pointer into to a substring within a symbol's name, or to the
      storage of the pairing completion_match object.  */
   const char *m_match;
+
+  /* The ignored substring ranges within M_MATCH.  E.g., if we were
+     looking for completion matches for C++ functions starting with
+       "functio"
+     and successfully match:
+       "function[abi:cxx11](int)"
+     the ignored ranges vector will contain an entry that delimits the
+     "[abi:cxx11]" substring, such that calling finish() results in:
+       "function(int)"
+   */
+  std::vector<std::pair<const char *, const char *>> m_ignored_ranges;
+
+  /* Storage used by the finish() method, if it has to compute a new
+     string.  */
+  std::string m_finished_storage;
 };
 
 /* Convenience aggregate holding info returned by the symbol name
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 172d821..34a8439 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1629,7 +1629,23 @@ cp_search_name_hash (const char *search_name)
   if (prefix_len != 0)
     search_name += prefix_len + 2;
 
-  return default_search_name_hash (search_name);
+  unsigned int hash = 0;
+  for (const char *string = search_name; *string != '\0'; ++string)
+    {
+      string = skip_spaces (string);
+
+      if (*string == '(')
+	break;
+
+      /* Ignore ABI tags such as "[abi:cxx11].  */
+      if (*string == '['
+	  && startswith (string + 1, "abi:")
+	  && string[5] != ':')
+	break;
+
+      hash = SYMBOL_HASH_NEXT (hash, *string);
+    }
+  return hash;
 }
 
 /* Helper for cp_symbol_name_matches (i.e., symbol_name_matcher_ftype
@@ -1674,11 +1690,13 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
 			  completion_match_result *comp_match_res)
 {
   const char *sname = symbol_search_name;
+  completion_match_for_lcd *match_for_lcd
+    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
 
   while (true)
     {
       if (strncmp_iw_with_mode (sname, lookup_name, lookup_name_len,
-				mode, language_cplus) == 0)
+				mode, language_cplus, match_for_lcd) == 0)
 	{
 	  if (comp_match_res != NULL)
 	    {
@@ -1728,14 +1746,15 @@ cp_fq_symbol_name_matches (const char *symbol_search_name,
 {
   /* Get the demangled name.  */
   const std::string &name = lookup_name.cplus ().lookup_name ();
-
+  completion_match_for_lcd *match_for_lcd
+    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
   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,
 			    name.c_str (), name.size (),
-			    mode, language_cplus) == 0)
+			    mode, language_cplus, match_for_lcd) == 0)
     {
       if (comp_match_res != NULL)
 	comp_match_res->set_match (symbol_search_name);
@@ -1950,6 +1969,32 @@ test_cp_symbol_name_matches ()
   CHECK_NOT_MATCH_C ("foo::function()", "::function()");
   CHECK_NOT_MATCH_C ("foo::function(int)", "::function()");
   CHECK_NOT_MATCH_C ("foo::function(int)", "::function(int)");
+
+  /* Test ABI tag matching/ignoring.  */
+
+  /* If the symbol name has an ABI tag, but the lookup name doesn't,
+     then the ABI tag in the symbol name is ignored.  */
+  CHECK_MATCH_C ("function[abi:foo]()", "function");
+  CHECK_MATCH_C ("function[abi:foo](int)", "function");
+  CHECK_MATCH_C ("function[abi:foo]()", "function ()");
+  CHECK_NOT_MATCH_C ("function[abi:foo]()", "function (int)");
+
+  CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo](int)", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo] ()");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] ()");
+  CHECK_NOT_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] (int)");
+
+  CHECK_MATCH_C ("function  [abi:foo][abi:bar] ( )", "function [abi:foo]");
+
+  /* If the symbol name does not have an ABI tag, while the lookup
+     name has one, then there's no match.  */
+  CHECK_NOT_MATCH_C ("function()", "function[abi:foo]()");
+  CHECK_NOT_MATCH_C ("function()", "function[abi:foo]");
 }
 
 /* If non-NULL, return STR wrapped in quotes.  Otherwise, return a
diff --git a/gdb/language.c b/gdb/language.c
index c05b703..c3872fc 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -707,13 +707,14 @@ default_symbol_name_matcher (const char *symbol_search_name,
 			     completion_match_result *comp_match_res)
 {
   const std::string &name = lookup_name.name ();
-
+  completion_match_for_lcd *match_for_lcd
+    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
   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, name.c_str (), name.size (),
-			    mode, language_minimal) == 0)
+			    mode, language_minimal, match_for_lcd) == 0)
     {
       if (comp_match_res != NULL)
 	comp_match_res->set_match (symbol_search_name);
diff --git a/gdb/linespec.c b/gdb/linespec.c
index fca3efd..83600bb 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -748,6 +748,11 @@ linespec_lexer_lex_string (linespec_parser *parser)
 	      if (PARSER_STREAM (parser)[1] == ':')
 		++(PARSER_STREAM (parser));
 
+	      /* Do not tokenize ABI tags such as "[abi:cxx11]".  */
+	      else if (PARSER_STREAM (parser) - start > 4
+		       && startswith (PARSER_STREAM (parser) - 4, "[abi"))
+		++(PARSER_STREAM (parser));
+
 	      /* Do not tokenify if the input length so far is one
 		 (i.e, a single-letter drive name) and the next character
 		 is a directory separator.  This allows Windows-style
diff --git a/gdb/testsuite/gdb.linespec/cpls-abi-tag.cc b/gdb/testsuite/gdb.linespec/cpls-abi-tag.cc
new file mode 100644
index 0000000..3916eda
--- /dev/null
+++ b/gdb/testsuite/gdb.linespec/cpls-abi-tag.cc
@@ -0,0 +1,93 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 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/>.  */
+
+#define ABI1 __attribute__ ((abi_tag ("tag1")))
+#define ABI2 __attribute__ ((abi_tag ("tag2")))
+#define ABI3 __attribute__ ((abi_tag ("tag3")))
+
+void ABI1
+test_abi_tag_function (int)
+{
+}
+
+void ABI1
+test_abi_tag_ovld_function ()
+{
+}
+
+void ABI1
+test_abi_tag_ovld_function (int)
+{
+}
+
+/* Code for the overload functions, different ABI tag test.  */
+
+void
+test_abi_tag_ovld2_function ()
+{
+}
+
+void ABI1
+test_abi_tag_ovld2_function (short)
+{
+}
+
+void ABI2
+test_abi_tag_ovld2_function (int)
+{
+}
+
+void ABI2
+test_abi_tag_ovld2_function (long)
+{
+}
+
+struct ABI1 test_abi_tag_struct
+{
+  ABI2 test_abi_tag_struct ();
+  ABI2 ~test_abi_tag_struct ();
+};
+
+test_abi_tag_struct::test_abi_tag_struct ()
+{}
+
+test_abi_tag_struct::~test_abi_tag_struct ()
+{}
+
+ABI3 test_abi_tag_struct s;
+
+/* Code for the abi-tag in parameters test.  */
+
+struct ABI2 abi_tag_param_struct1
+{};
+
+struct ABI2 abi_tag_param_struct2
+{};
+
+void
+test_abi_tag_in_params (abi_tag_param_struct1)
+{}
+
+void
+test_abi_tag_in_params (abi_tag_param_struct1, abi_tag_param_struct2)
+{}
+
+int
+main ()
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.linespec/cpls-abi-tag.exp b/gdb/testsuite/gdb.linespec/cpls-abi-tag.exp
new file mode 100644
index 0000000..9a0dab3
--- /dev/null
+++ b/gdb/testsuite/gdb.linespec/cpls-abi-tag.exp
@@ -0,0 +1,286 @@
+# Copyright 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/>.
+
+# This file is part of the gdb testsuite.
+
+# Test ABI tag support in linespecs.
+
+load_lib completion-support.exp
+
+standard_testfile cpls-abi-tag.cc
+
+if {[prepare_for_testing "failed to prepare" $testfile \
+	 [list $srcfile] {c++ debug}]} {
+    return -1
+}
+
+gdb_test_no_output "set max-completions unlimited"
+
+# Check that the explicit location completer manages to find the next
+# option name after a -function option, when the -function's argument
+# is a function with an ABI tag.
+
+proc check_explicit_skips_function_argument {function} {
+    test_gdb_complete_unique \
+	"b -function $function -sour" \
+	"b -function $function -source"
+}
+
+# The ABI tag tests.
+
+proc_with_prefix test_abi_tag {} {
+    with_test_prefix "completion" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Complete all prefixes between "_funcio" and the full
+	    # prototype.  The ABI tag is not considered for actual
+	    # completion.
+
+	    with_test_prefix "skip tag" {
+		# set location "test_abi_tag_function\[abi:tag1\](int)"
+		set location "test_abi_tag_function(int)"
+		set line "$cmd_prefix $location"
+		set start [index_after "_functio" $line]
+		test_complete_prefix_range $line $start
+	    }
+
+	    # Now the same, but start completing at the [.  In that case,
+	    # GDB considers the ABI tag as part of actual completion.
+	    with_test_prefix "at tag" {
+		set location "test_abi_tag_function\[abi:tag1\](int)"
+		set line "$cmd_prefix $location"
+		set start [index_after "_function" $line]
+		test_complete_prefix_range $line $start
+	    }
+
+	    # Same, but with extra spaces.  Note that the original spaces in
+	    # the input line are preserved after completion.
+
+	    with_test_prefix "spaces" {
+		test_gdb_complete_unique \
+		    "$cmd_prefix test_abi_tag_function \[abi:tag1\] (" \
+		    "$cmd_prefix test_abi_tag_function \[abi:tag1\] (int)"
+
+		test_gdb_complete_unique \
+		    "$cmd_prefix test_abi_tag_function \[abi:tag1\] ( int " \
+		    "$cmd_prefix test_abi_tag_function \[abi:tag1\] ( int )"
+	    }
+	}
+    }
+
+    with_test_prefix "set breakpoints" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Test setting breakpoints.  If the symbol name has an ABI
+	    # tag, but the input linespec doesn't, then the ABI tag in the
+	    # symbol name is ignored.
+	    set linespec_list {
+		"test_abi_tag_function"
+		"test_abi_tag_function[abi:tag1]"
+		"test_abi_tag_function[abi:tag1](int)"
+		"test_abi_tag_function [abi:tag1]"
+		"test_abi_tag_function [abi:tag1] ( int )"
+		"test_abi_tag_function(int)"
+		"test_abi_tag_function (int)"
+		"test_abi_tag_function ( int )"
+	    }
+	    foreach linespec $linespec_list {
+		check_bp_locations_match_list \
+		    "$cmd_prefix $linespec" [list $location]
+	    }
+	}
+    }
+
+    with_test_prefix "set breakpoints wrong ABI tag" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Test setting breakpoints with the wrong ABI tag.  Should
+	    # fail to create the breakpoints.  Completion should not find
+	    # any match either.
+	    set linespec_list {
+		"test_abi_tag_function[abi:tag2]"
+		"test_abi_tag_function[abi:tag2](int)"
+		"test_abi_tag_function [abi:tag2]"
+		"test_abi_tag_function [abi:tag2] ( int )"
+	    }
+	    foreach linespec $linespec_list {
+		check_setting_bp_fails "$cmd_prefix $linespec"
+		test_gdb_complete_none "$cmd_prefix $linespec"
+	    }
+
+	}
+    }
+
+    # Test completion of overloaded functions with ABI tags.
+    with_test_prefix "completion of overloaded functions" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    set completion_list {
+		"test_abi_tag_ovld_function[abi:tag1]()"
+		"test_abi_tag_ovld_function[abi:tag1](int)"
+	    }
+
+	    # If the input string does not include the ABI tag, then
+	    # actual completion ignores it.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_ovld_f" "unction(" \
+		$completion_list
+
+	    # Otherwise, it's considered.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_ovld_function\[" "abi:tag1\](" \
+		$completion_list
+
+	}
+    }
+
+    # Test setting breakpoints on overloaded functions with ABI tags.
+    with_test_prefix "breakpoints on overloaded functions" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    set completion_list {
+		"test_abi_tag_ovld_function[abi:tag1]()"
+		"test_abi_tag_ovld_function[abi:tag1](int)"
+	    }
+	    set location_list {
+		"test_abi_tag_ovld_function"
+		"test_abi_tag_ovld_function[abi:tag1]"
+	    }
+	    foreach linespec $location_list {
+		check_bp_locations_match_list \
+		    "$cmd_prefix $linespec" $completion_list
+	    }
+
+	}
+    }
+
+    with_test_prefix "completion of overloaded functions different abi" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Test completion of overloaded functions with ABI tags.
+	    set completion_list {
+		"test_abi_tag_ovld2_function()"
+		"test_abi_tag_ovld2_function[abi:tag1](short)"
+		"test_abi_tag_ovld2_function[abi:tag2](int)"
+		"test_abi_tag_ovld2_function[abi:tag2](long)"
+	    }
+
+	    # If the input string does not include the ABI tag, then
+	    # actual completion ignores it.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_ovld2_f" "unction(" \
+		$completion_list
+
+	    # Otherwise, it's considered.  Match stops at the part of
+	    # the tag that diverges, and the completion list only
+	    # shows matches with ABI tags.
+	    set completion_list {
+		"test_abi_tag_ovld2_function[abi:tag1](short)"
+		"test_abi_tag_ovld2_function[abi:tag2](int)"
+		"test_abi_tag_ovld2_function[abi:tag2](long)"
+	    }
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_ovld2_function\[" "abi:tag" \
+		$completion_list
+
+	    # If you disambiguate, matches include only locations for
+	    # the specified tag.
+	    set completion_list {
+		"test_abi_tag_ovld2_function[abi:tag2](int)"
+		"test_abi_tag_ovld2_function[abi:tag2](long)"
+	    }
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_ovld2_function\[abi:tag2" "\](" \
+		$completion_list
+
+	    test_gdb_complete_unique \
+		"$cmd_prefix test_abi_tag_ovld2_function\[abi:tag1" \
+		"$cmd_prefix test_abi_tag_ovld2_function\[abi:tag1\](short)"
+	}
+    }
+
+    with_test_prefix "completion of struct prefixes with tags" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Test completion of methods of structs with ABI tags.
+	    set completion_list {
+		"test_abi_tag_struct[abi:tag1]::test_abi_tag_struct[abi:tag2]()"
+		"test_abi_tag_struct[abi:tag1]::~test_abi_tag_struct[abi:tag2]()"
+	    }
+
+	    # If the input string does not include the ABI tag, then
+	    # actual completion ignores it.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_struc" "t::" \
+		$completion_list
+
+	    # Otherwise, it's considered.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_struct\[" "abi:tag1\]::" \
+		$completion_list
+
+	    # Mix and match different abi tag positions.
+	    test_gdb_complete_unique \
+		"$cmd_prefix test_abi_tag_struct::t" \
+		"$cmd_prefix test_abi_tag_struct::test_abi_tag_struct()"
+
+	    test_gdb_complete_unique \
+		"$cmd_prefix test_abi_tag_struct\[abi:tag1\]::t" \
+		"$cmd_prefix test_abi_tag_struct\[abi:tag1\]::test_abi_tag_struct()"
+
+	    test_gdb_complete_unique \
+		"$cmd_prefix test_abi_tag_struct\[abi:tag1\]::test_abi_tag_struct\[" \
+		"$cmd_prefix test_abi_tag_struct\[abi:tag1\]::test_abi_tag_struct\[abi:tag2\]()"
+	}
+    }
+
+    with_test_prefix "abi tag in parameters" {
+	foreach cmd_prefix {"b" "b -function"} {
+	    # Complete all prefixes between "_funcio" and the full
+	    # prototype.  The ABI tag is not considered for actual
+	    # completion.
+
+	    set completion_list {
+		"test_abi_tag_in_params(abi_tag_param_struct1[abi:tag2])"
+		"test_abi_tag_in_params(abi_tag_param_struct1[abi:tag2], abi_tag_param_struct2[abi:tag2])"
+	    }
+	    # If the input string does not include the ABI tag, then
+	    # actual completion ignores it.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_in_para" "ms(abi_tag_param_struct1" \
+		$completion_list
+
+	    # If OTOH the input string includes the ABI tag, then it
+	    # is considered.
+	    test_gdb_complete_multiple \
+		"$cmd_prefix " "test_abi_tag_in_params(abi_tag_param_struct1\[ab" "i:tag2\]"\
+		$completion_list
+
+	    set location_list {
+		"test_abi_tag_in_params(abi_tag_param_struct1[abi:tag2], abi_tag_param_struct2[abi:tag2])"
+	    }
+
+	    set tags {"" "\[abi:tag2\]"}
+	    foreach tag1 $tags {
+		foreach tag2 $tags {
+		    set linespec "test_abi_tag_in_params(abi_tag_param_struct1${tag1}, abi_tag_param_struct2${tag2})"
+		    check_bp_locations_match_list \
+			"$cmd_prefix $linespec" $location_list
+		}
+	    }
+	}
+    }
+
+    # Check that the explicit location completer manages to find the
+    # option name after -function, when the -function's argument is a
+    # function with an ABI tag.
+    check_explicit_skips_function_argument \
+	"test_abi_tag_function\[abi:unknown\](int)"
+}
+
+test_abi_tag
diff --git a/gdb/utils.c b/gdb/utils.c
index 3e817ed..98ef6ac 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2247,12 +2247,40 @@ cp_is_operator (const char *string, const char *start)
 	  && !valid_identifier_name_char (string[CP_OPERATOR_LEN]));
 }
 
+/* If *NAME points at an ABI tag, skip it and return true.  Otherwise
+   leave *NAME unmodified and return false.  (see GCC's abi_tag
+   attribute), such names are demangled as e.g.,
+   "function[abi:cxx11]()".  */
+
+static bool
+skip_abi_tag (const char **name)
+{
+  const char *p = *name;
+
+  if (startswith (p, "[abi:"))
+    {
+      p += 5;
+
+      while (valid_identifier_name_char (*p))
+	p++;
+
+      if (*p == ']')
+	{
+	  p++;
+	  *name = p;
+	  return true;
+	}
+    }
+  return false;
+}
+
 /* See utils.h.  */
 
 int
 strncmp_iw_with_mode (const char *string1, const char *string2,
 		      size_t string2_len, strncmp_iw_mode mode,
-		      enum language language)
+		      enum language language,
+		      completion_match_for_lcd *match_for_lcd)
 {
   const char *string1_start = string1;
   const char *end_str2 = string2 + string2_len;
@@ -2271,6 +2299,37 @@ strncmp_iw_with_mode (const char *string1, const char *string2,
 	  skip_spaces = false;
 	}
 
+      /* Skip [abi:cxx11] tags in the symbol name if the lookup name
+	 doesn't include them.  E.g.:
+
+	 string1: function[abi:cxx1](int)
+	 string2: function
+
+	 string1: function[abi:cxx1](int)
+	 string2: function(int)
+
+	 string1: Struct[abi:cxx1]::function()
+	 string2: Struct::function()
+
+	 string1: function(Struct[abi:cxx1], int)
+	 string2: function(Struct, int)
+      */
+      if (string2 == end_str2
+	  || (*string2 != '[' && !valid_identifier_name_char (*string2)))
+	{
+	  const char *abi_start = string1;
+
+	  /* There can be more than one tag.  */
+	  while (*string1 == '[' && skip_abi_tag (&string1))
+	    ;
+
+	  if (match_for_lcd != NULL && abi_start != string1)
+	    match_for_lcd->mark_ignored_range (abi_start, string1);
+
+	  while (isspace (*string1))
+	    string1++;
+	}
+
       if (*string1 == '\0' || string2 == end_str2)
 	break;
 
@@ -2405,7 +2464,40 @@ strncmp_iw_with_mode (const char *string1, const char *string2,
   if (string2 == end_str2)
     {
       if (mode == strncmp_iw_mode::NORMAL)
-	return 0;
+	{
+	  /* Strip abi tag markers from the matched symbol name.
+	     Usually the ABI marker will be found on function name
+	     (automatically added because the function returns an
+	     object marked with an ABI tag).  However, it's also
+	     possible to see a marker in one of the function
+	     parameters, for example.
+
+	     string2 (lookup name):
+	       func
+	     symbol name:
+	       function(some_struct[abi:cxx11], int)
+
+	     and for completion LCD computation we want to say that
+	     the match was for:
+	       function(some_struct, int)
+	  */
+	  if (match_for_lcd != NULL)
+	    {
+	      while ((string1 = strstr (string1, "[abi:")) != NULL)
+		{
+		  const char *abi_start = string1;
+
+		  /* There can be more than one tag.  */
+		  while (skip_abi_tag (&string1) && *string1 == '[')
+		    ;
+
+		  if (abi_start != string1)
+		    match_for_lcd->mark_ignored_range (abi_start, string1);
+		}
+	    }
+
+	  return 0;
+	}
       else
 	return (*string1 != '\0' && *string1 != '(');
     }
diff --git a/gdb/utils.h b/gdb/utils.h
index dff4b17..349ab93 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -49,15 +49,19 @@ enum class strncmp_iw_mode
 /* Helper for strcmp_iw and strncmp_iw.  Exported so that languages
    can implement both NORMAL and MATCH_PARAMS variants in a single
    function and defer part of the work to strncmp_iw_with_mode.
+
    LANGUAGE is used to implement some context-sensitive
    language-specific comparisons.  For example, for C++,
    "string1=operator()" should not match "string2=operator" even in
-   MATCH_PARAMS mode.  */
-extern int strncmp_iw_with_mode (const char *string1,
-				 const char *string2,
-				 size_t string2_len,
-				 strncmp_iw_mode mode,
-				 enum language language);
+   MATCH_PARAMS mode.
+
+   MATCH_FOR_LCD is passed down so that the function can mark parts of
+   the symbol name as ignored for completion matching purposes (e.g.,
+   to handle abi tags).  */
+extern int strncmp_iw_with_mode
+  (const char *string1, const char *string2, size_t string2_len,
+   strncmp_iw_mode mode, enum language language,
+   completion_match_for_lcd *match_for_lcd = NULL);
 
 /* Do a strncmp() type operation on STRING1 and STRING2, ignoring any
    differences in whitespace.  STRING2_LEN is STRING2's length.
-- 
2.5.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags
@ 2017-11-27 17:13 Pedro Alves
  2017-11-27 17:13 ` [PATCH v2 1/3] Handle custom completion match prefix / LCD Pedro Alves
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Pedro Alves @ 2017-11-27 17:13 UTC (permalink / raw)
  To: gdb-patches

Here's v2 of the series originally posted here:

  [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more
  https://sourceware.org/ml/gdb-patches/2017-06/msg00012.html

Most of the series is in, except that bits that I was really
originally after.  :-)

What remains is:

 - teaching GDB to set breakpoints on all namespaces/classes/scopes by
   default, along with a new option "break -qualified" to override the
   behavior.
 - fix setting breakpoints on symbols with [abi:cxx11] tags.

In this version I've addressed Keith's comments, and implemented his
suggestion of making "-qualified" work with linespecs too, instead of
just with explicit locations:
  https://sourceware.org/ml/gdb-patches/2017-11/msg00618.html

In v1, tests and documentation changes were in separate patches, but
since now we're down to only two distinct improvements, I've moved
tests and docs changes to the patches that actually implements each
feature.  The documentation for the ABI tags patch (patch #3) has not
changed since the previous version, and was already reviewed and
approved.  The documentation for the wild matching feature was changed
since the last revision, so may benefit from review again.

Blurb from v1 with already-merged bits stripped follows:

A few months back I was looking at making GDB use gnulib's C++
namespace mode, because the default mode has gnulib define its
replacements using macros, like "#define open rpl_open".  In C++
that's a bad idea, given that using names like "open", "close",
etc. in classes and namespaces is the natural thing to do.  E.g.,
"struct target_ops::to_open" could be "class target::open".

After experimentation, I concluded that the best would be to wrap all
of GDB in:

 namespace gdb {
 }

and so I tried it:
 https://github.com/palves/gdb/commits/palves/cxx-gdb-namespace

however, when I actually got it working and started debugging that
GDB, I immediately got frustrated with GDB's C++ support.  I.e., the
dog food didn't taste so good.

The problem was that now you'd always need to prefix every function
name with "gdb::".  I.e., "b gdb::internal_error", etc., etc.  And it
gets annoying pretty fast.

I thought that GDB should be able to do better.  I thought that maybe
GDB could infer the namespace from local context, so you'd still be
able to do "b foo", and that would find "gdb::foo".  However, that
doesn't work well, because you want to be able to conveniently set
breakpoints before starting a program, when there's no frame yet.
And, running to main doesn't help, because main is not in any
namespace.  Also, the direction linespecs / setting breakpoints is
aiming, is in not relying in local context at all.  Instead, match the
most possible, and let users filter it down if they want.  I.e., e.g.,
"b foo" sets locations in all "foo" functions in the program in all
compilation units, no matter whether they're both extern or static
function, no matter where you're currently stopped in the program.
Likewise "b source.c:foo" looks at all source files named "source.c",
not just the current source if it happens to have that name.  You can
set set a breakpoint on a C++ symbol named "some_klass::method()",
even if the current frame's language is C, not C++.  Etc., etc.

The idea then occurred to me.  How about we make GDB ignore leading
namespaces when setting breakpoints?  I.e., just like "b foo" sets a
breakpoint on all "foo"s in the program, and you can zoom in on
specific "foo" functions by specifying a source file to scope the
symbol search, like "b source.c:foo", by default we'd make "b foo" set
a breakpoint on all functions and methods named "foo" too, like
"A::foo", "B::A::foo", "(anonymous namespace)::foo", and of course
global "foo".  And then if you scope the name, like "A::foo", GDB
would find both "A::foo", and "B::A::foo", but not the others.  Etc.,
etc.  E.g.,:

  (gdb) b function[TAB]
  A::function()
  B::A::function()
  function()
  (anonymous namespace)::function()
  (gdb) b function
  Breakpoint 1 at 0x4005ce: function. (4 locations)

  (gdb) b A::function[TAB]
  A::function()
  B::A::function()
  (gdb) b function
  Breakpoint 1 at 0x4005ce: function. (2 locations)

That sounded quite promising to me.  Turns out that that's what lldb
does too, so I started experimenting with doing the same in GDB.
Along the way, I realized that gdb's Ada support has always behaved
like that...  ada-lang.c calls it "wild matching" vs "full matching"
(see full_match and wild_match).  So it's not really a new idea for
GDB.  The problem is that Ada does that on its own little ada-lang.c
corner, out of view..  

Actually, above I'm showing TAB completion.  But there's more to that.
Once it got it working for setting breakpoints, I realized that TAB
completion would need to be adjusted too.  TAB completion goes via
different symbol search code paths...  I required adjustment because
while "b foo[RET]" would find all functions named "foo", "b foo[TAB]"
would only show symbols that start with "foo"...

Fixing that required virtually rewriting how GDB interacts with
readline for completion.  Most of that rework is already in master,
but one issue is not addressed yet, which is that you want this to
happen:

  (gdb) b func[TAB]      # expands input line to ...
  (gdb) b function(      # ... this
  (gdb) b function([TAB] # another tab now shows you the candidates
  A::B::function(int)
  A::C::function(long)

Notice how the input line above was expanded to "function(", but,
that's not actually the common leading prefix between all completion
candidates!  If we'd let readline compute what it calls the "lowest
common denominator", then this is what you'd see:

  (gdb) b func[TAB]      # expands input line to ...
  (gdb) b A::            # ... this...

which is obviously bogus.

And then on top of the above, the series fixes setting breakpoints on
symbols with [abi:cxx11] tags.

Pedro Alves (3):
  Handle custom completion match prefix / LCD
  Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild
    matching]
  Breakpoints in symbols with ABI tags (PR c++/19436)

 gdb/doc/gdb.texinfo                         |  86 +++++-
 gdb/NEWS                                    |  42 +++
 gdb/ada-lang.c                              |  22 +-
 gdb/ax-gdb.c                                |   3 +-
 gdb/breakpoint.c                            |  32 ++-
 gdb/c-lang.c                                |   2 +-
 gdb/completer.c                             |  61 +++-
 gdb/completer.h                             | 139 ++++++++-
 gdb/cp-support.c                            | 218 +++++++++++++-
 gdb/cp-support.h                            |   7 +
 gdb/dwarf2read.c                            |  48 ++++
 gdb/guile/scm-breakpoint.c                  |   6 +-
 gdb/language.c                              |  11 +-
 gdb/language.h                              |   3 +-
 gdb/linespec.c                              |  52 +++-
 gdb/linespec.h                              |  12 +-
 gdb/location.c                              |  95 +++++--
 gdb/location.h                              |  38 ++-
 gdb/mi/mi-cmd-break.c                       |   3 +-
 gdb/python/py-breakpoint.c                  |   3 +-
 gdb/python/python.c                         |   3 +-
 gdb/symtab.c                                |  11 +-
 gdb/symtab.h                                |  20 +-
 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.linespec/cpcompletion.exp | 423 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc  |  93 ++++++
 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp | 286 +++++++++++++++++++
 gdb/testsuite/gdb.linespec/explicit.exp     |  80 +++---
 gdb/testsuite/lib/completion-support.exp    |   2 +-
 gdb/utils.c                                 |  96 ++++++-
 gdb/utils.h                                 |  16 +-
 33 files changed, 1782 insertions(+), 174 deletions(-)
 create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc
 create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp

-- 
2.5.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/3] Handle custom completion match prefix / LCD
  2017-11-27 17:13 [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
@ 2017-11-27 17:13 ` Pedro Alves
  2017-11-28  1:42   ` Keith Seitz
  2017-11-27 17:13 ` [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436) Pedro Alves
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2017-11-27 17:13 UTC (permalink / raw)
  To: gdb-patches

In v2:

  - Addresses Keith's review.  The main change is that it adds a
    convenience method to completion_match_result to set both regular
    match and the match for LCD.  This is the new
    completion_match_result::set_match method.
    Basically, this folds in this patch:
~~~~~~


A following patch will add support for wild matching for C++ symbols,
making completing on "b push_ba" on a C++ program complete to
std::vector<...>::push_back, std::string::push_back etc., like:

 (gdb) b push_ba[TAB]
 std::vector<...>::push_back(....)
 std::string<...>::push_back(....)

Currently, we compute the "lowest common denominator" between all
completion candidates (what the input line is adjusted to) as the
common prefix of all matches.  That's problematic with wild matching
as above, as then we'd end up with TAB changing the input line to
"b std::", losing the original input, like:

 (gdb) b push_ba[TAB]
 std::vector<...>::push_back(....)
 std::string<...>::push_back(....)
 (gdb) b std::

while obviously we'd want it to adjust itself to "b push_back(" instead:

 (gdb) b push_ba[TAB]
 std::vector<...>::push_back(....)
 std::string<...>::push_back(....)
 (gdb) b push_back(

This patch adds the core code necessary to support this, though
nothing really makes use of it yet in this patch.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* ada-lang.c (ada_lookup_name_info::matches): Change type of
	parameter from completion_match to completion_match_result.
	Adjust.
	(do_wild_match, do_full_match, ada_symbol_name_matches): Likewise.
	* completer.c (completion_tracker::maybe_add_completion): Add
	match_for_lcd parameter and use it.
	(completion_tracker::add_completion): Likewise.
	* completer.h (class completion_match_for_lcd): New class.
	(completion_match_result::match_for_lcd): New field.
	(completion_match_result::set_match): New method.
	(completion_tracker): Add comments.
	(completion_tracker::add_completion): Add match_for_lcd parameter.
	(completion_tracker::reset_completion_match_result): Reset
	match_for_lcd too.
	(completion_tracker::maybe_add_completion): Add match_for_lcd
	parameter.
	(completion_tracker::m_lowest_common_denominator_unique): Extend
	comments.
	* cp-support.c (cp_symbol_name_matches_1)
	(cp_fq_symbol_name_matches): Change type of parameter from
	completion_match to completion_match_result.  Adjust.
	* language.c (default_symbol_name_matcher): Change type of
	parameter from completion_match to completion_match_result.
	Adjust.
	* language.h (completion_match_for_lcd): Forward declare.
	(default_symbol_name_matcher): Change type of parameter from
	completion_match to completion_match_result.
	* symtab.c (compare_symbol_name): Adjust.
	(completion_list_add_name): Pass the match_for_lcd to the tracker.
	* symtab.h (ada_lookup_name_info::matches): Change type of
	parameter from completion_match to completion_match_result.
	(symbol_name_matcher_ftype): Likewise, and update comments.
---
 gdb/ada-lang.c   | 22 +++++++--------
 gdb/completer.c  | 17 +++++++++---
 gdb/completer.h  | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 gdb/cp-support.c | 10 +++----
 gdb/language.c   |  6 ++--
 gdb/language.h   |  3 +-
 gdb/symtab.c     | 11 ++++++--
 gdb/symtab.h     | 20 ++++++++-----
 8 files changed, 135 insertions(+), 39 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3265c21..38d1ce6 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -6357,7 +6357,7 @@ bool
 ada_lookup_name_info::matches
   (const char *sym_name,
    symbol_name_match_type match_type,
-   completion_match *comp_match) const
+   completion_match_result *comp_match_res) const
 {
   bool match = false;
   const char *text = m_encoded_name.c_str ();
@@ -6415,15 +6415,12 @@ ada_lookup_name_info::matches
   if (!match)
     return false;
 
-  if (comp_match != NULL)
+  if (comp_match_res != NULL)
     {
-      std::string &match_str = comp_match->storage ();
+      std::string &match_str = comp_match_res->match.storage ();
 
       if (!m_encoded_p)
-	{
-	  match_str = ada_decode (sym_name);
-	  comp_match->set_match (match_str.c_str ());
-	}
+	match_str = ada_decode (sym_name);
       else
 	{
 	  if (m_verbatim_p)
@@ -6431,8 +6428,9 @@ ada_lookup_name_info::matches
 	  else
 	    match_str = sym_name;
 
-	  comp_match->set_match (match_str.c_str ());
 	}
+
+      comp_match_res->set_match (match_str.c_str ());
     }
 
   return true;
@@ -13925,7 +13923,7 @@ static const struct exp_descriptor ada_exp_descriptor = {
 static bool
 do_wild_match (const char *symbol_search_name,
 	       const lookup_name_info &lookup_name,
-	       completion_match *match)
+	       completion_match_result *comp_match_res)
 {
   return wild_match (symbol_search_name, ada_lookup_name (lookup_name));
 }
@@ -13935,7 +13933,7 @@ do_wild_match (const char *symbol_search_name,
 static bool
 do_full_match (const char *symbol_search_name,
 	       const lookup_name_info &lookup_name,
-	       completion_match *match)
+	       completion_match_result *comp_match_res)
 {
   return full_match (symbol_search_name, ada_lookup_name (lookup_name));
 }
@@ -14005,11 +14003,11 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
 static bool
 ada_symbol_name_matches (const char *symbol_search_name,
 			 const lookup_name_info &lookup_name,
-			 completion_match *match)
+			 completion_match_result *comp_match_res)
 {
   return lookup_name.ada ().matches (symbol_search_name,
 				     lookup_name.match_type (),
-				     match);
+				     comp_match_res);
 }
 
 /* Implement the "la_get_symbol_name_matcher" language_defn method for
diff --git a/gdb/completer.c b/gdb/completer.c
index f9ece59..fd82b86 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1502,7 +1502,9 @@ completion_tracker::~completion_tracker ()
 /* See completer.h.  */
 
 bool
-completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
+completion_tracker::maybe_add_completion
+  (gdb::unique_xmalloc_ptr<char> name,
+   completion_match_for_lcd *match_for_lcd)
 {
   void **slot;
 
@@ -1515,7 +1517,13 @@ completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
   slot = htab_find_slot (m_entries_hash, name.get (), INSERT);
   if (*slot == HTAB_EMPTY_ENTRY)
     {
-      const char *match_for_lcd_str = name.get ();
+      const char *match_for_lcd_str = NULL;
+
+      if (match_for_lcd != NULL)
+	match_for_lcd_str = match_for_lcd->finish ();
+
+      if (match_for_lcd_str == NULL)
+	match_for_lcd_str = name.get ();
 
       recompute_lowest_common_denominator (match_for_lcd_str);
 
@@ -1529,9 +1537,10 @@ completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
 /* See completer.h.  */
 
 void
-completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name)
+completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name,
+				    completion_match_for_lcd *match_for_lcd)
 {
-  if (!maybe_add_completion (std::move (name)))
+  if (!maybe_add_completion (std::move (name), match_for_lcd))
     throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached."));
 }
 
diff --git a/gdb/completer.h b/gdb/completer.h
index 38fee6b..f756412 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -116,12 +116,56 @@ private:
   std::string m_storage;
 };
 
+/* The result of a successful completion match, but for least common
+   denominator (LCD) computation.  Some completers provide matches
+   that don't start with the completion "word".  E.g., completing on
+   "b push_ba" on a C++ program usually completes to
+   std::vector<...>::push_back, std::string::push_back etc.  In such
+   case, the symbol comparison routine will set the LCD match to point
+   into the "push_back" substring within the symbol's name string.  */
+
+class completion_match_for_lcd
+{
+public:
+  /* Set the match for LCD.  See m_match's description.  */
+  void set_match (const char *match)
+  { m_match = match; }
+
+  /* Get the resulting LCD, after a successful match.  */
+  const char *finish ()
+  { return m_match; }
+
+  /* Prepare for another completion matching sequence.  */
+  void clear ()
+  { m_match = NULL; }
+
+private:
+  /* The completion match result for LCD.  This is usually either a
+     pointer into to a substring within a symbol's name, or to the
+     storage of the pairing completion_match object.  */
+  const char *m_match;
+};
+
 /* Convenience aggregate holding info returned by the symbol name
    matching routines (see symbol_name_matcher_ftype).  */
 struct completion_match_result
 {
   /* The completion match candidate.  */
   completion_match match;
+
+  /* The completion match, for LCD computation purposes.  */
+  completion_match_for_lcd match_for_lcd;
+
+  /* Convenience that sets both MATCH and MATCH_FOR_LCD.  M_FOR_LCD is
+     optional.  If not specified, defaults to M.  */
+  void set_match (const char *m, const char *m_for_lcd = NULL)
+  {
+    match.set_match (m);
+    if (m_for_lcd == NULL)
+      match_for_lcd.set_match (m);
+    else
+      match_for_lcd.set_match (m_for_lcd);
+  }
 };
 
 /* The final result of a completion that is handed over to either
@@ -188,6 +232,21 @@ public:
      that necessitates the time consuming expansion of many symbol
      tables.
 
+   - The completer's idea of least common denominator (aka the common
+     prefix) between all completion matches to hand over to readline.
+     Some completers provide matches that don't start with the
+     completion "word".  E.g., completing on "b push_ba" on a C++
+     program usually completes to std::vector<...>::push_back,
+     std::string::push_back etc.  If all matches happen to start with
+     "std::", then readline would figure out that the lowest common
+     denominator is "std::", and thus would do a partial completion
+     with that.  I.e., it would replace "push_ba" in the input buffer
+     with "std::", losing the original "push_ba", which is obviously
+     undesirable.  To avoid that, such completers pass the substring
+     of the match that matters for common denominator computation as
+     MATCH_FOR_LCD argument to add_completion.  The end result is
+     passed to readline in gdb_rl_attempted_completion_function.
+
    - The custom word point to hand over to readline, for completers
      that parse the input string in order to dynamically adjust
      themselves depending on exactly what they're completing.  E.g.,
@@ -205,7 +264,8 @@ public:
   /* Add the completion NAME to the list of generated completions if
      it is not there already.  If too many completions were already
      found, this throws an error.  */
-  void add_completion (gdb::unique_xmalloc_ptr<char> name);
+  void add_completion (gdb::unique_xmalloc_ptr<char> name,
+		       completion_match_for_lcd *match_for_lcd = NULL);
 
   /* Add all completions matches in LIST.  Elements are moved out of
      LIST.  */
@@ -268,6 +328,7 @@ public:
 
     /* Clear any previous match.  */
     res.match.clear ();
+    res.match_for_lcd.clear ();
     return m_completion_match_result;
   }
 
@@ -290,10 +351,19 @@ private:
   /* Add the completion NAME to the list of generated completions if
      it is not there already.  If false is returned, too many
      completions were found.  */
-  bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name);
+  bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name,
+			     completion_match_for_lcd *match_for_lcd);
 
   /* Given a new match, recompute the lowest common denominator (LCD)
-     to hand over to readline.  */
+     to hand over to readline.  Normally readline computes this itself
+     based on the whole set of completion matches.  However, some
+     completers want to override readline, in order to be able to
+     provide a LCD that is not really a prefix of the matches, but the
+     lowest common denominator of some relevant substring of each
+     match.  E.g., "b push_ba" completes to
+     "std::vector<..>::push_back", "std::string::push_back", etc., and
+     in this case we want the lowest common denominator to be
+     "push_back" instead of "std::".  */
   void recompute_lowest_common_denominator (const char *new_match);
 
   /* Completion match outputs returned by the symbol name matching
@@ -348,8 +418,13 @@ private:
      See intro.  */
   char *m_lowest_common_denominator = NULL;
 
-  /* If true, the LCD is unique.  I.e., all completion candidates had
-     the same string.  */
+  /* If true, the LCD is unique.  I.e., all completions had the same
+     MATCH_FOR_LCD substring, even if the completions were different.
+     For example, if "break function<tab>" found "a::function()" and
+     "b::function()", the LCD will be "function()" in both cases and
+     so we want to tell readline to complete the line with
+     "function()", instead of showing all the possible
+     completions.  */
   bool m_lowest_common_denominator_unique = false;
 };
 
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 368112a..6c6825b 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1634,14 +1634,14 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
 			  const char *lookup_name,
 			  size_t lookup_name_len,
 			  strncmp_iw_mode mode,
-			  completion_match *match)
+			  completion_match_result *comp_match_res)
 {
   if (strncmp_iw_with_mode (symbol_search_name,
 			    lookup_name, lookup_name_len,
 			    mode, language_cplus) == 0)
     {
-      if (match != NULL)
-	match->set_match (symbol_search_name);
+      if (comp_match_res != NULL)
+	comp_match_res->set_match (symbol_search_name);
       return true;
     }
 
@@ -1653,7 +1653,7 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
 static bool
 cp_fq_symbol_name_matches (const char *symbol_search_name,
 			   const lookup_name_info &lookup_name,
-			   completion_match *match)
+			   completion_match_result *comp_match_res)
 {
   /* Get the demangled name.  */
   const std::string &name = lookup_name.cplus ().lookup_name ();
@@ -1664,7 +1664,7 @@ cp_fq_symbol_name_matches (const char *symbol_search_name,
 
   return cp_symbol_name_matches_1 (symbol_search_name,
 				   name.c_str (), name.size (),
-				   mode, match);
+				   mode, comp_match_res);
 }
 
 /* See cp-support.h.  */
diff --git a/gdb/language.c b/gdb/language.c
index 2a1419c..c05b703 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -704,7 +704,7 @@ default_get_string (struct value *value, gdb_byte **buffer, int *length,
 bool
 default_symbol_name_matcher (const char *symbol_search_name,
 			     const lookup_name_info &lookup_name,
-			     completion_match *match)
+			     completion_match_result *comp_match_res)
 {
   const std::string &name = lookup_name.name ();
 
@@ -715,8 +715,8 @@ default_symbol_name_matcher (const char *symbol_search_name,
   if (strncmp_iw_with_mode (symbol_search_name, name.c_str (), name.size (),
 			    mode, language_minimal) == 0)
     {
-      if (match != NULL)
-	match->set_match (symbol_search_name);
+      if (comp_match_res != NULL)
+	comp_match_res->set_match (symbol_search_name);
       return true;
     }
   else
diff --git a/gdb/language.h b/gdb/language.h
index 34f5692..47ad8da 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -37,6 +37,7 @@ struct type_print_options;
 struct lang_varobj_ops;
 struct parser_state;
 struct compile_instance;
+struct completion_match_for_lcd;
 
 #define MAX_FORTRAN_DIMS  7	/* Maximum number of F77 array dims.  */
 
@@ -629,7 +630,7 @@ void c_get_string (struct value *value, gdb_byte **buffer, int *length,
 extern bool default_symbol_name_matcher
   (const char *symbol_search_name,
    const lookup_name_info &lookup_name,
-   completion_match *match);
+   completion_match_result *comp_match_res);
 
 /* Get LANG's symbol_name_matcher method for LOOKUP_NAME.  Returns
    default_symbol_name_matcher if not set.  */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3d59367..7db9bd7 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4698,7 +4698,7 @@ compare_symbol_name (const char *symbol_name, language symbol_language,
   symbol_name_matcher_ftype *name_match
     = language_get_symbol_name_matcher (lang, lookup_name);
 
-  return name_match (symbol_name, lookup_name, &match_res.match);
+  return name_match (symbol_name, lookup_name, &match_res);
 }
 
 /*  See symtab.h.  */
@@ -4751,7 +4751,14 @@ completion_list_add_name (completion_tracker &tracker,
 
     gdb::unique_xmalloc_ptr<char> completion (newobj);
 
-    tracker.add_completion (std::move (completion));
+    /* Here we pass the match-for-lcd object to add_completion.  Some
+       languages match the user text against substrings of symbol
+       names in some cases.  E.g., in C++, "b push_ba" completes to
+       "std::vector::push_back", "std::string::push_back", etc., and
+       in this case we want the completion lowest common denominator
+       to be "push_back" instead of "std::".  */
+    tracker.add_completion (std::move (completion),
+			    &match_res.match_for_lcd);
   }
 }
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e5aae2a..239a479 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -84,7 +84,7 @@ class ada_lookup_name_info final
      otherwise.  If non-NULL, store the matching results in MATCH.  */
   bool matches (const char *symbol_search_name,
 		symbol_name_match_type match_type,
-		completion_match *match) const;
+		completion_match_result *comp_match_res) const;
 
   /* The Ada-encoded lookup name.  */
   const std::string &lookup_name () const
@@ -295,15 +295,21 @@ private:
 
    SYMBOL_SEARCH_NAME should be a symbol's "search" name.
 
-   On success and if non-NULL, MATCH is set to point to the symbol
-   name as should be presented to the user as a completion match list
-   element.  In most languages, this is the same as the symbol's
-   search name, but in some, like Ada, the display name is dynamically
-   computed within the comparison routine.  */
+   On success and if non-NULL, COMP_MATCH_RES->match is set to point
+   to the symbol name as should be presented to the user as a
+   completion match list element.  In most languages, this is the same
+   as the symbol's search name, but in some, like Ada, the display
+   name is dynamically computed within the comparison routine.
+
+   Also, on success and if non-NULL, COMP_MATCH_RES->match_for_lcd
+   points to the part of SYMBOL_SEARCH_NAME that was considered to match
+   LOOKUP_NAME.  E.g., in C++, in linespec/wild mode, if the symbol is
+   "foo::function()" and LOOKUP_NAME is "function(", MATCH_FOR_LCD
+   points to "function()" inside SYMBOL_SEARCH_NAME.  */
 typedef bool (symbol_name_matcher_ftype)
   (const char *symbol_search_name,
    const lookup_name_info &lookup_name,
-   completion_match *match);
+   completion_match_result *comp_match_res);
 
 /* Some of the structures in this file are space critical.
    The space-critical structures are:
-- 
2.5.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-27 17:13 [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
  2017-11-27 17:13 ` [PATCH v2 1/3] Handle custom completion match prefix / LCD Pedro Alves
  2017-11-27 17:13 ` [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436) Pedro Alves
@ 2017-11-27 17:14 ` Pedro Alves
  2017-11-27 17:47   ` Eli Zaretskii
  2017-11-28  0:01   ` Pedro Alves
  2017-11-27 17:33 ` [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
  3 siblings, 2 replies; 14+ messages in thread
From: Pedro Alves @ 2017-11-27 17:14 UTC (permalink / raw)
  To: gdb-patches

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

  - Documentation bits were tweaked accordingly, so may benefit from
    another review.
~~~~~~

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 (ls_parser::match_type): New field.
	(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_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.linespec/explicit.exp: Test -qualified.
	* lib/completion-support.exp (completion::explicit_opts_list): Add
	"-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                              |  47 +++-
 gdb/linespec.h                              |  12 +-
 gdb/location.c                              |  95 +++++--
 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.linespec/cpcompletion.exp | 423 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.linespec/explicit.exp     |  80 +++---
 gdb/testsuite/lib/completion-support.exp    |   2 +-
 23 files changed, 992 insertions(+), 125 deletions(-)

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..fca3efd 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -302,6 +302,9 @@ struct ls_parser
   struct linespec result;
 #define PARSER_RESULT(PPTR) (&(PPTR)->result)
 
+  /* Whether to do full matching or wild matching.  */
+  symbol_name_match_type match_type;
+
   /* What the parser believes the current word point should complete
      to.  */
   linespec_complete_what complete_what;
@@ -359,6 +362,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);
 
@@ -1868,6 +1872,7 @@ linespec_parse_basic (linespec_parser *parser)
 
 	  linespec_complete_function (tmp_tracker,
 				      parser->completion_word,
+				      parser->match_type,
 				      source_filename);
 
 	  if (tmp_tracker.have_completions ())
@@ -1892,6 +1897,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->match_type,
 			 &symbols, &minimal_symbols);
 
   if (symbols != NULL || minimal_symbols != NULL)
@@ -2383,6 +2389,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 +2419,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 +2460,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 +2514,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 +2549,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->match_type = match_type;
 
   /* Initialize the default symtab and line offset.  */
   initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@@ -2828,10 +2839,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 +2881,8 @@ complete_linespec_component (linespec_parser *parser,
     {
       completion_list fn_list;
 
-      linespec_complete_function (tracker, text, source_filename);
+      linespec_complete_function (tracker, text, parser->match_type,
+				  source_filename);
       if (source_filename == NULL)
 	{
 	  /* Haven't seen a source component, like in "b
@@ -2940,6 +2952,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 +2969,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 +2987,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 +2997,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.match_type = match_type;
   PARSER_STREAM (&parser) = text;
 
   parser.completion_tracker = &tracker;
@@ -2991,7 +3007,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 +3055,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, parser.match_type,
 			     &function_symbols, &minimal_symbols);
 
       PARSER_RESULT (&parser)->function_symbols = function_symbols;
@@ -3181,7 +3197,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 +3510,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 +3955,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 +3975,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 +4004,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 +4022,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..d764f4c 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
@@ -245,7 +252,12 @@ explicit_to_string_internal (int as_linespec,
       if (need_space)
 	buf.putc (space);
       if (!as_linespec)
-	buf.puts ("-function ");
+	{
+	  if (explicit_loc->func_name_match_type
+	      == symbol_name_match_type::FULL)
+	    buf.puts ("-qualified ");
+	  buf.puts ("-function ");
+	}
       buf.puts (explicit_loc->function_name);
       need_space = 1;
     }
@@ -307,8 +319,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 +330,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 +369,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 +404,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 +781,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 +812,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 +855,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 +878,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 +907,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 +921,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 +931,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.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.
-- 
2.5.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags
  2017-11-27 17:13 [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
                   ` (2 preceding siblings ...)
  2017-11-27 17:14 ` [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
@ 2017-11-27 17:33 ` Pedro Alves
  3 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2017-11-27 17:33 UTC (permalink / raw)
  To: gdb-patches

And as usual, I forgot to mention that I also pushed this to the:

  users/palves/cxx-breakpoint-improvements-v2

branch.

Thanks,
Pedro Alves

On 11/27/2017 05:13 PM, Pedro Alves wrote:
> Here's v2 of the series originally posted here:
> 
>   [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more
>   https://sourceware.org/ml/gdb-patches/2017-06/msg00012.html
> 
> Most of the series is in, except that bits that I was really
> originally after.  :-)
> 
> What remains is:
> 
>  - teaching GDB to set breakpoints on all namespaces/classes/scopes by
>    default, along with a new option "break -qualified" to override the
>    behavior.
>  - fix setting breakpoints on symbols with [abi:cxx11] tags.
> 
> In this version I've addressed Keith's comments, and implemented his
> suggestion of making "-qualified" work with linespecs too, instead of
> just with explicit locations:
>   https://sourceware.org/ml/gdb-patches/2017-11/msg00618.html
> 
> In v1, tests and documentation changes were in separate patches, but
> since now we're down to only two distinct improvements, I've moved
> tests and docs changes to the patches that actually implements each
> feature.  The documentation for the ABI tags patch (patch #3) has not
> changed since the previous version, and was already reviewed and
> approved.  The documentation for the wild matching feature was changed
> since the last revision, so may benefit from review again.
> 
> Blurb from v1 with already-merged bits stripped follows:
> 
> A few months back I was looking at making GDB use gnulib's C++
> namespace mode, because the default mode has gnulib define its
> replacements using macros, like "#define open rpl_open".  In C++
> that's a bad idea, given that using names like "open", "close",
> etc. in classes and namespaces is the natural thing to do.  E.g.,
> "struct target_ops::to_open" could be "class target::open".
> 
> After experimentation, I concluded that the best would be to wrap all
> of GDB in:
> 
>  namespace gdb {
>  }
> 
> and so I tried it:
>  https://github.com/palves/gdb/commits/palves/cxx-gdb-namespace
> 
> however, when I actually got it working and started debugging that
> GDB, I immediately got frustrated with GDB's C++ support.  I.e., the
> dog food didn't taste so good.
> 
> The problem was that now you'd always need to prefix every function
> name with "gdb::".  I.e., "b gdb::internal_error", etc., etc.  And it
> gets annoying pretty fast.
> 
> I thought that GDB should be able to do better.  I thought that maybe
> GDB could infer the namespace from local context, so you'd still be
> able to do "b foo", and that would find "gdb::foo".  However, that
> doesn't work well, because you want to be able to conveniently set
> breakpoints before starting a program, when there's no frame yet.
> And, running to main doesn't help, because main is not in any
> namespace.  Also, the direction linespecs / setting breakpoints is
> aiming, is in not relying in local context at all.  Instead, match the
> most possible, and let users filter it down if they want.  I.e., e.g.,
> "b foo" sets locations in all "foo" functions in the program in all
> compilation units, no matter whether they're both extern or static
> function, no matter where you're currently stopped in the program.
> Likewise "b source.c:foo" looks at all source files named "source.c",
> not just the current source if it happens to have that name.  You can
> set set a breakpoint on a C++ symbol named "some_klass::method()",
> even if the current frame's language is C, not C++.  Etc., etc.
> 
> The idea then occurred to me.  How about we make GDB ignore leading
> namespaces when setting breakpoints?  I.e., just like "b foo" sets a
> breakpoint on all "foo"s in the program, and you can zoom in on
> specific "foo" functions by specifying a source file to scope the
> symbol search, like "b source.c:foo", by default we'd make "b foo" set
> a breakpoint on all functions and methods named "foo" too, like
> "A::foo", "B::A::foo", "(anonymous namespace)::foo", and of course
> global "foo".  And then if you scope the name, like "A::foo", GDB
> would find both "A::foo", and "B::A::foo", but not the others.  Etc.,
> etc.  E.g.,:
> 
>   (gdb) b function[TAB]
>   A::function()
>   B::A::function()
>   function()
>   (anonymous namespace)::function()
>   (gdb) b function
>   Breakpoint 1 at 0x4005ce: function. (4 locations)
> 
>   (gdb) b A::function[TAB]
>   A::function()
>   B::A::function()
>   (gdb) b function
>   Breakpoint 1 at 0x4005ce: function. (2 locations)
> 
> That sounded quite promising to me.  Turns out that that's what lldb
> does too, so I started experimenting with doing the same in GDB.
> Along the way, I realized that gdb's Ada support has always behaved
> like that...  ada-lang.c calls it "wild matching" vs "full matching"
> (see full_match and wild_match).  So it's not really a new idea for
> GDB.  The problem is that Ada does that on its own little ada-lang.c
> corner, out of view..  
> 
> Actually, above I'm showing TAB completion.  But there's more to that.
> Once it got it working for setting breakpoints, I realized that TAB
> completion would need to be adjusted too.  TAB completion goes via
> different symbol search code paths...  I required adjustment because
> while "b foo[RET]" would find all functions named "foo", "b foo[TAB]"
> would only show symbols that start with "foo"...
> 
> Fixing that required virtually rewriting how GDB interacts with
> readline for completion.  Most of that rework is already in master,
> but one issue is not addressed yet, which is that you want this to
> happen:
> 
>   (gdb) b func[TAB]      # expands input line to ...
>   (gdb) b function(      # ... this
>   (gdb) b function([TAB] # another tab now shows you the candidates
>   A::B::function(int)
>   A::C::function(long)
> 
> Notice how the input line above was expanded to "function(", but,
> that's not actually the common leading prefix between all completion
> candidates!  If we'd let readline compute what it calls the "lowest
> common denominator", then this is what you'd see:
> 
>   (gdb) b func[TAB]      # expands input line to ...
>   (gdb) b A::            # ... this...
> 
> which is obviously bogus.
> 
> And then on top of the above, the series fixes setting breakpoints on
> symbols with [abi:cxx11] tags.
> 
> Pedro Alves (3):
>   Handle custom completion match prefix / LCD
>   Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild
>     matching]
>   Breakpoints in symbols with ABI tags (PR c++/19436)
> 
>  gdb/doc/gdb.texinfo                         |  86 +++++-
>  gdb/NEWS                                    |  42 +++
>  gdb/ada-lang.c                              |  22 +-
>  gdb/ax-gdb.c                                |   3 +-
>  gdb/breakpoint.c                            |  32 ++-
>  gdb/c-lang.c                                |   2 +-
>  gdb/completer.c                             |  61 +++-
>  gdb/completer.h                             | 139 ++++++++-
>  gdb/cp-support.c                            | 218 +++++++++++++-
>  gdb/cp-support.h                            |   7 +
>  gdb/dwarf2read.c                            |  48 ++++
>  gdb/guile/scm-breakpoint.c                  |   6 +-
>  gdb/language.c                              |  11 +-
>  gdb/language.h                              |   3 +-
>  gdb/linespec.c                              |  52 +++-
>  gdb/linespec.h                              |  12 +-
>  gdb/location.c                              |  95 +++++--
>  gdb/location.h                              |  38 ++-
>  gdb/mi/mi-cmd-break.c                       |   3 +-
>  gdb/python/py-breakpoint.c                  |   3 +-
>  gdb/python/python.c                         |   3 +-
>  gdb/symtab.c                                |  11 +-
>  gdb/symtab.h                                |  20 +-
>  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.linespec/cpcompletion.exp | 423 ++++++++++++++++++++++++++++
>  gdb/testsuite/gdb.linespec/cpls-abi-tag.cc  |  93 ++++++
>  gdb/testsuite/gdb.linespec/cpls-abi-tag.exp | 286 +++++++++++++++++++
>  gdb/testsuite/gdb.linespec/explicit.exp     |  80 +++---
>  gdb/testsuite/lib/completion-support.exp    |   2 +-
>  gdb/utils.c                                 |  96 ++++++-
>  gdb/utils.h                                 |  16 +-
>  33 files changed, 1782 insertions(+), 174 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc
>  create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-27 17:14 ` [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
@ 2017-11-27 17:47   ` Eli Zaretskii
  2017-11-28  0:01   ` Pedro Alves
  1 sibling, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2017-11-27 17:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> From: Pedro Alves <palves@redhat.com>
> Date: Mon, 27 Nov 2017 17:13:43 +0000
> 
>   - Documentation bits were tweaked accordingly, so may benefit from
>     another review.

Reviewed; still OK.

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-27 17:14 ` [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
  2017-11-27 17:47   ` Eli Zaretskii
@ 2017-11-28  0:01   ` Pedro Alves
  2017-11-28  0:14     ` [PATCH v2.1 " Pedro Alves
  1 sibling, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2017-11-28  0:01 UTC (permalink / raw)
  To: GDB Patches

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.

From 35d4e973c62fd51ad8554286aa2d984d63761b6c Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Mon, 27 Nov 2017 23:48:33 +0000
Subject: [PATCH] save-breakpoints

---
 gdb/linespec.c                             | 22 +++++----
 gdb/location.c                             |  9 ++--
 gdb/testsuite/gdb.cp/save-bp-qualified.cc  | 40 ++++++++++++++++
 gdb/testsuite/gdb.cp/save-bp-qualified.exp | 74 ++++++++++++++++++++++++++++++
 gdb/testsuite/lib/gdb.exp                  |  6 ++-
 5 files changed, 134 insertions(+), 17 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/linespec.c b/gdb/linespec.c
index 83600bb..c3e616f 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -302,9 +302,6 @@ struct ls_parser
   struct linespec result;
 #define PARSER_RESULT(PPTR) (&(PPTR)->result)
 
-  /* Whether to do full matching or wild matching.  */
-  symbol_name_match_type match_type;
-
   /* What the parser believes the current word point should complete
      to.  */
   linespec_complete_what complete_what;
@@ -1874,10 +1871,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,
-				      parser->match_type,
+				      match_type,
 				      source_filename);
 
 	  if (tmp_tracker.have_completions ())
@@ -1902,7 +1901,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->match_type,
+			 PARSER_EXPLICIT (parser)->func_name_match_type,
 			 &symbols, &minimal_symbols);
 
   if (symbols != NULL || minimal_symbols != NULL)
@@ -2554,7 +2553,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->match_type = match_type;
+  PARSER_EXPLICIT (parser)->func_name_match_type = match_type;
 
   /* Initialize the default symtab and line offset.  */
   initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@@ -2763,6 +2762,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,
@@ -2886,8 +2887,9 @@ complete_linespec_component (linespec_parser *parser,
     {
       completion_list fn_list;
 
-      linespec_complete_function (tracker, text, parser->match_type,
-				  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
@@ -3002,7 +3004,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.match_type = match_type;
+  PARSER_EXPLICIT (&parser)->func_name_match_type = match_type;
   PARSER_STREAM (&parser) = text;
 
   parser.completion_tracker = &tracker;
@@ -3060,7 +3062,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, parser.match_type,
+			     func_name, match_type,
 			     &function_symbols, &minimal_symbols);
 
       PARSER_RESULT (&parser)->function_symbols = function_symbols;
diff --git a/gdb/location.c b/gdb/location.c
index d764f4c..6752462 100644
--- a/gdb/location.c
+++ b/gdb/location.c
@@ -251,13 +251,10 @@ 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)
-	{
-	  if (explicit_loc->func_name_match_type
-	      == symbol_name_match_type::FULL)
-	    buf.puts ("-qualified ");
-	  buf.puts ("-function ");
-	}
+	buf.puts ("-function ");
       buf.puts (explicit_loc->function_name);
       need_space = 1;
     }
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/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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-28  0:01   ` Pedro Alves
@ 2017-11-28  0:14     ` Pedro Alves
  2017-11-28  2:50       ` Keith Seitz
  0 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2017-11-28  0:14 UTC (permalink / raw)
  To: GDB Patches

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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/3] Handle custom completion match prefix / LCD
  2017-11-27 17:13 ` [PATCH v2 1/3] Handle custom completion match prefix / LCD Pedro Alves
@ 2017-11-28  1:42   ` Keith Seitz
  0 siblings, 0 replies; 14+ messages in thread
From: Keith Seitz @ 2017-11-28  1:42 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 11/27/2017 09:13 AM, Pedro Alves wrote:
> In v2:
> 
>   - Addresses Keith's review.  The main change is that it adds a
>     convenience method to completion_match_result to set both regular
>     match and the match for LCD.  This is the new
>     completion_match_result::set_match method.

That looks okay to me.

Thanks!

Keith

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-28  0:14     ` [PATCH v2.1 " Pedro Alves
@ 2017-11-28  2:50       ` Keith Seitz
  2017-11-28 12:39         ` Pedro Alves
  0 siblings, 1 reply; 14+ messages in thread
From: Keith Seitz @ 2017-11-28  2:50 UTC (permalink / raw)
  To: Pedro Alves, GDB Patches

On 11/27/2017 04:14 PM, Pedro Alves wrote:
> 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.

Hahaha. If I had a dime for every time I (almost?) forgot to check
"save-breakpoints," I'd have a couple of bucks by now...

>> 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.
> 

Just one little comment.

> 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);
>      }

At first, the use of ::WILD here seemed odd to me. MI is to be used by user
interfaces like Eclipse, I wondered why Eclipse would need WILD-card access
to symbol names.

But then I remembered that having access to full source code "database" is not
(or should not) be a requirement for using MI.

So that leaves me to assume that we intend a follow-on patch to address
adding a "-qualified"-like flag for MI, too. Not requesting changes. Just
thinking aloud.

[I would guess the same for the similar python and guile changes.]

Am I in left field?

That said, LGTM.

Keith

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436)
  2017-11-27 17:13 ` [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436) Pedro Alves
@ 2017-11-28  3:47   ` Keith Seitz
  0 siblings, 0 replies; 14+ messages in thread
From: Keith Seitz @ 2017-11-28  3:47 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 11/27/2017 09:13 AM, Pedro Alves wrote:
> In v2:
> 
>   - Nothing really changed.  This is still here because it depends on
>     infrastructure added by patch #1.

Still looks good!

Keith

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-28  2:50       ` Keith Seitz
@ 2017-11-28 12:39         ` Pedro Alves
  2017-11-28 17:35           ` Keith Seitz
  0 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2017-11-28 12:39 UTC (permalink / raw)
  To: Keith Seitz, GDB Patches

On 11/28/2017 02:50 AM, Keith Seitz wrote:
> On 11/27/2017 04:14 PM, Pedro Alves wrote:
>> 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.
> 
> Hahaha. If I had a dime for every time I (almost?) forgot to check
> "save-breakpoints," I'd have a couple of bucks by now...
> 
>>> 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.
>>
> 
> Just one little comment.
> 
>> 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);
>>      }
> 
> At first, the use of ::WILD here seemed odd to me. MI is to be used by user
> interfaces like Eclipse, I wondered why Eclipse would need WILD-card access
> to symbol names.

My rationale here was to make that setting breakpoints via MI (the GUI) and
via CLI (the GDB console) find the same locations, by default.  My thinking is that
setting breakpoints by function name is something that usually frontends don't
do -- they usually set breakpoints by source filename + line number.  But
when setting a breakpoint by function name, in response to the user
typing some function name in some input line widget, it'll be better
to make CLI and the frontend agree on locations.

> 
> But then I remembered that having access to full source code "database" is not
> (or should not) be a requirement for using MI.
> 
> So that leaves me to assume that we intend a follow-on patch to address
> adding a "-qualified"-like flag for MI, too. Not requesting changes. Just
> thinking aloud.

Right, I had this unfinished patchlet here (missing tests, docs, etc...):

MI and --qualified
---

 gdb/mi/mi-cmd-break.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index 6cb1d71..75449e8 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -189,7 +189,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
       IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
       TRACEPOINT_OPT,
       EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
-      EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
+      EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT,
+      QUALIFIED_OPT,
     };
   static const struct mi_opt opts[] =
   {
@@ -205,6 +206,7 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
     {"-function", EXPLICIT_FUNC_OPT, 1},
     {"-label", EXPLICIT_LABEL_OPT, 1},
     {"-line", EXPLICIT_LINE_OPT, 1},
+    {"-qualified", QUALIFIED_OPT, 0},
     { 0, 0, 0 }
   };
 
@@ -263,6 +265,9 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
 	  is_explicit = 1;
 	  explicit_loc.line_offset = linespec_parse_line_offset (oarg);
 	  break;
+	case QUALIFIED_OPT:
+	  explicit_loc.func_name_match_type = symbol_name_match_type::FULL;
+	  break;
 	}
     }
 
@@ -337,8 +342,9 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
     }
   else
     {
-      location = string_to_event_location_basic (&address, current_language,
-						 symbol_name_match_type::WILD);
+      location
+	= string_to_event_location_basic (&address, current_language,
+					  explicit_loc.func_name_match_type);
       if (*address)
 	error (_("Garbage '%s' at end of location"), address);
     }


which seems to work fine.  We get:

-break-insert --qualified main
^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0000000000400501",func="main",file="main.c",fullname="/home/pedro/gdb/tests/main.c",line="5",thread-groups=["i1"],times="0",original-location="-qualified main"}
(gdb) 
-break-insert --qualified --function main
^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x0000000000400501",func="main",file="main.c",fullname="/home/pedro/gdb/tests/main.c",line="5",thread-groups=["i1"],times="0",original-location="-qualified -function main"}
(gdb) 

Really not sure it's worth the bother to try to treat single-dash
"-qualified" as part of the linespec, as in:

  "-break-insert LINESPEC" =>
  "-break-insert -qualified function"

(I think we could get that working by using mi_getopt_allow_unknown.)

I assume a frontend would want to wire this up to a toggle checkbox:

 [line widget for function name]  [X] qualified 

> 
> [I would guess the same for the similar python and guile changes.]

*nod*

Here I'm assuming we'll get most of it for free too given Phil's
Python explicit locations work, though I haven't looked much at
it, to be honest.

(My thinking was to focus/settle on the core/CLI bits ignoring
those, and address those after, maybe even after the branch
is cut.)

> 
> Am I in left field?
> 
> That said, LGTM.

Alright, let me know what think of the above.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-28 12:39         ` Pedro Alves
@ 2017-11-28 17:35           ` Keith Seitz
  2017-11-29 19:52             ` Pedro Alves
  0 siblings, 1 reply; 14+ messages in thread
From: Keith Seitz @ 2017-11-28 17:35 UTC (permalink / raw)
  To: Pedro Alves, GDB Patches

On 11/28/2017 04:39 AM, Pedro Alves wrote:
> 
> Alright, let me know what think of the above.

I was just seeking a sanity check (*my* sanity). This is a similar situation to explicit locations. Not every `interface' has access to those yet, either.

So, please, don't hesitate to push this!

Keith

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2.1 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
  2017-11-28 17:35           ` Keith Seitz
@ 2017-11-29 19:52             ` Pedro Alves
  0 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2017-11-29 19:52 UTC (permalink / raw)
  To: Keith Seitz, GDB Patches


On 11/28/2017 05:35 PM, Keith Seitz wrote:
> On 11/28/2017 04:39 AM, Pedro Alves wrote:
>>
>> Alright, let me know what think of the above.
> 
> I was just seeking a sanity check (*my* sanity). This is a similar situation to explicit locations. Not every `interface' has access to those yet, either.
> 
> So, please, don't hesitate to push this!

Yeah, I'm a bit hesitant, since I consider this a big
change.  :-)  But I asked around on IRC to double-check
if anyone had last-minute comments, and everyone seemed
pretty cool about it, so I pushed it in now.  Hurray!

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2017-11-29 19:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-27 17:13 [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves
2017-11-27 17:13 ` [PATCH v2 1/3] Handle custom completion match prefix / LCD Pedro Alves
2017-11-28  1:42   ` Keith Seitz
2017-11-27 17:13 ` [PATCH v2 3/3] Breakpoints in symbols with ABI tags (PR c++/19436) Pedro Alves
2017-11-28  3:47   ` Keith Seitz
2017-11-27 17:14 ` [PATCH v2 2/3] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Pedro Alves
2017-11-27 17:47   ` Eli Zaretskii
2017-11-28  0:01   ` Pedro Alves
2017-11-28  0:14     ` [PATCH v2.1 " Pedro Alves
2017-11-28  2:50       ` Keith Seitz
2017-11-28 12:39         ` Pedro Alves
2017-11-28 17:35           ` Keith Seitz
2017-11-29 19:52             ` Pedro Alves
2017-11-27 17:33 ` [PATCH v2 0/3] C++ debugging improvements: wild matching and ABI tags Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).