return info;
 }
 
-/* Convert RESULT to a string.  The return value is allocated
-   using xmalloc.  ESTIMATED_LEN is used only as a guide to the
-   length of the result.  This functions handles a few cases that
-   cplus_demangle_print does not, specifically the global destructor
-   and constructor labels.  */
+/* See cp-support.h.  */
 
 gdb::unique_xmalloc_ptr<char>
 cp_comp_to_string (struct demangle_component *result, int estimated_len)
 {
   size_t err;
 
-  char *res = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI,
-                                   result, estimated_len, &err);
+  char *res = gdb_cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI,
+                                       result, estimated_len, &err);
   return gdb::unique_xmalloc_ptr<char> (res);
 }
 
   char *str;
   size_t err = 0;
 
-  str = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, 64, &err);
+  str = gdb_cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, 64, &err);
   if (str == NULL)
     return;
 
 
 
 struct cmd_list_element *maint_cplus_cmd_list = NULL;
 
-/* A list of typedefs which should not be substituted by replace_typedefs.  */
-static const char * const ignore_typedefs[] =
-  {
-    "std::istream", "std::iostream", "std::ostream", "std::string"
-  };
-
 static void
   replace_typedefs (struct demangle_parse_info *info,
                    struct demangle_component *ret_comp,
                    canonicalization_ftype *finder,
                    void *data);
 
+static struct demangle_component *
+  gdb_cplus_demangle_v3_components (const char *mangled,
+                                   int options, void **mem);
+
 /* A convenience function to copy STRING into OBSTACK, returning a pointer
    to the newly allocated string and saving the number of bytes saved in LEN.
 
   memcpy (name, ret_comp->u.s_name.s, ret_comp->u.s_name.len);
   name[ret_comp->u.s_name.len] = '\0';
 
-  /* Ignore any typedefs that should not be substituted.  */
-  for (const char *ignorable : ignore_typedefs)
-    {
-      if (strcmp (name, ignorable) == 0)
-       return 0;
-    }
-
   sym = NULL;
 
   try
     {
       struct demangle_component *ret;
 
-      ret = cplus_demangle_v3_components (mangled_name,
-                                         options, memory);
+      ret = gdb_cplus_demangle_v3_components (mangled_name,
+                                             options, memory);
       if (ret)
        {
          std::unique_ptr<demangle_parse_info> info (new demangle_parse_info);
 #endif
 
   if (crash_signal == 0)
-    result.reset (bfd_demangle (NULL, name, options));
+    result.reset (bfd_demangle (NULL, name, options | DMGL_VERBOSE));
 
 #ifdef HAVE_WORKING_FORK
   if (catch_demangler_crashes)
 
 /* See cp-support.h.  */
 
+char *
+gdb_cplus_demangle_print (int options,
+                         struct demangle_component *tree,
+                         int estimated_length,
+                         size_t *p_allocated_size)
+{
+  return cplus_demangle_print (options | DMGL_VERBOSE, tree,
+                              estimated_length, p_allocated_size);
+}
+
+/* A wrapper for cplus_demangle_v3_components that forces
+   DMGL_VERBOSE.  */
+
+static struct demangle_component *
+gdb_cplus_demangle_v3_components (const char *mangled,
+                                 int options, void **mem)
+{
+  return cplus_demangle_v3_components (mangled, options | DMGL_VERBOSE, mem);
+}
+
+/* See cp-support.h.  */
+
 unsigned int
 cp_search_name_hash (const char *search_name)
 {
 
 extern std::unique_ptr<demangle_parse_info> cp_demangled_name_to_comp
      (const char *demangled_name, std::string *errmsg);
 
+/* Convert RESULT to a string.  ESTIMATED_LEN is used only as a guide
+   to the length of the result.  */
+
 extern gdb::unique_xmalloc_ptr<char> cp_comp_to_string
   (struct demangle_component *result, int estimated_len);
 
 
 extern struct cmd_list_element *maint_cplus_cmd_list;
 
+/* Wrappers for bfd and libiberty demangling entry points.  Note they
+   all force DMGL_VERBOSE so that callers don't need to.  This is so
+   that GDB consistently uses DMGL_VERBOSE throughout -- we want
+   libiberty's demangler to expand standard substitutions to their
+   full template name.  */
+
 /* A wrapper for bfd_demangle.  */
 
 gdb::unique_xmalloc_ptr<char> gdb_demangle (const char *name, int options);
 
+/* A wrapper for cplus_demangle_print.  */
+
+extern char *gdb_cplus_demangle_print (int options,
+                                      struct demangle_component *tree,
+                                      int estimated_length,
+                                      size_t *p_allocated_size);
+
 /* Find an instance of the character C in the string S that is outside
    of all parenthesis pairs, single-quoted strings, and double-quoted
    strings.  Also, ignore the char within a template name, like a ','
 
--- /dev/null
+/* This test file is part of GDB, the GNU debugger.
+
+   Copyright 2011-2022 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/>.  */
+
+#include <string>
+
+void
+f (std::string s)
+{
+}
 
--- /dev/null
+# Copyright 2022 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 setting a breakpoint at "f(std::string)".
+#
+# GDB should be able to expand the std::string typedef, and then set
+# the breakpoint using the resulting name.  In the Itanium ABI's
+# mangling scheme, "std::string", "std::istream", "std::iostream",
+# "std::ostream" are special, though, they have corresponding standard
+# abbreviations.  The libiberty demangler only expands these standard
+# abbreviations to their full non-typedef underlying type if the
+# DMGL_VERBOSE option is requested.  By default it expands them to the
+# user-friendly "std::string", etc. typedefs.  GDB didn't use to use
+# that option, and would instead prevent expansion of the
+# "std::string" (etc.) standard-abbreviation typedefs at
+# breakpoint-set type, such that the function name used for function
+# lookup would match the "std::string" present in the function's
+# non-DMGL_VERBOSE demangled name.
+#
+# For example (DMGL_VERBOSE):
+#
+#  $ echo "_Z1fSs" | c++filt
+#  f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)
+#
+# vs (no DMGL_VERBOSE):
+#
+#  $ echo "_Z1fSs" | c++filt --no-verbose
+#  f(std::string)
+#
+# This design broke setting a breakpoint at "f(std::string)" when the
+# libstdc++ C++11 ABI was introduced, as the "f(std::string)"
+# function's mangled name no longer uses a standard substitution for
+# std::string...
+#
+# I.e., with the libstdc++ C++11 ABI, we now have (and DMGL_VERBOSE
+# makes no difference):
+#
+#  $ echo _Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE | c++filt
+#  f(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
+#
+# So nowadays, GDB always uses DMGL_VERBOSE and no longer prevents
+# std::string (etc.) typedef expansion.  This test exercises both
+# pre-C++11 and C++11 ABIs for this reason.  On non-libstdc++ systems
+# where _GLIBCXX_USE_CXX11_ABI has no effect, we just end up running
+# the test twice with whatever ABI is used.
+
+standard_testfile .cc
+
+if { [skip_cplus_tests] } { continue }
+
+# CXX11_ABI specifies the value to define _GLIBCXX_USE_CXX11_ABI as.
+
+proc test {cxx11_abi} {
+    global srcdir subdir srcfile binfile testfile
+
+    set options \
+       [list c++ debug additional_flags=-D_GLIBCXX_USE_CXX11_ABI=$cxx11_abi]
+    if { [gdb_compile \
+             "${srcdir}/${subdir}/${srcfile}" "${binfile}-${cxx11_abi}.o" \
+             object $options] != "" } {
+       untested "failed to compile"
+       return -1
+    }
+
+    clean_restart ${testfile}-${cxx11_abi}.o
+
+    # Since we're debugging an .o file, GDB doesn't figure out we're
+    # debugging C++ code and the current language when auto, is
+    # guessed as C.
+    gdb_test_no_output "set language c++"
+
+    # Get the type std::string is a typedef for.  We'll try to set a
+    # breakpoint using the expanded type too.
+    set realtype ""
+    set type "std::string"
+    gdb_test_multiple "whatis /r $type" "" {
+       -re -wrap "type = (\[^\r\n\]+)" {
+           set realtype $expect_out(1,string)
+           gdb_assert {![string eq "$realtype" "$type"]} \
+               $gdb_test_name
+       }
+    }
+
+    gdb_test "break f($type)" "$srcfile, line $::decimal\\."
+
+    if { $realtype != "" } {
+       gdb_test "break f($realtype)" "$srcfile, line $::decimal\\."
+    }
+}
+
+foreach_with_prefix _GLIBCXX_USE_CXX11_ABI {0 1} {
+    test $_GLIBCXX_USE_CXX11_ABI
+}
 
+++ /dev/null
-/* This test file is part of GDB, the GNU debugger.
-
-   Copyright 2011-2022 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/>.  */
-
-#include <string>
-
-void
-f (std::string s)
-{
-}
 
+++ /dev/null
-# Copyright 2011-2022 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 loading symbols from unrelocated C++ object files.
-
-standard_testfile .cc
-
-if { [skip_cplus_tests] } { continue }
-
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}.o" object {c++ debug}] != "" } {
-     untested "failed to compile"
-     return -1
-}
-
-clean_restart ${testfile}.o
-
-gdb_test_no_output "set breakpoint pending off"
-
-gdb_breakpoint {'f(std::string)'}
-
-gdb_test {break 'f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'} \
-        {Function ".*" not defined\.} \
-        "DMGL_VERBOSE-demangled f(std::string) is not defined"