aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/cp-name-parser.y12
-rw-r--r--gdb/cp-support.c45
-rw-r--r--gdb/cp-support.h16
-rw-r--r--gdb/testsuite/gdb.cp/break-f-std-string.cc (renamed from gdb/testsuite/gdb.cp/no-dmgl-verbose.cc)0
-rw-r--r--gdb/testsuite/gdb.cp/break-f-std-string.exp105
-rw-r--r--gdb/testsuite/gdb.cp/no-dmgl-verbose.exp35
6 files changed, 154 insertions, 59 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 6410363..34c691d 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -1948,19 +1948,15 @@ allocate_info (void)
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);
}
@@ -2060,7 +2056,7 @@ cp_print (struct demangle_component *result)
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;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index f520558..71c1463 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -70,18 +70,16 @@ static void add_symbol_overload_list_qualified
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.
@@ -146,13 +144,6 @@ inspect_type (struct demangle_parse_info *info,
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
@@ -670,8 +661,8 @@ mangled_name_to_comp (const char *mangled_name, int options,
{
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);
@@ -1635,7 +1626,7 @@ gdb_demangle (const char *name, int options)
#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)
@@ -1670,6 +1661,28 @@ gdb_demangle (const char *name, int options)
/* 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)
{
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 4fbd53c..2e0ad50 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -175,6 +175,9 @@ struct type *cp_find_type_baseclass_by_name (struct type *parent_type,
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);
@@ -186,10 +189,23 @@ extern void cp_merge_demangle_parse_infos (struct demangle_parse_info *,
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 ','
diff --git a/gdb/testsuite/gdb.cp/no-dmgl-verbose.cc b/gdb/testsuite/gdb.cp/break-f-std-string.cc
index 454ab4c..454ab4c 100644
--- a/gdb/testsuite/gdb.cp/no-dmgl-verbose.cc
+++ b/gdb/testsuite/gdb.cp/break-f-std-string.cc
diff --git a/gdb/testsuite/gdb.cp/break-f-std-string.exp b/gdb/testsuite/gdb.cp/break-f-std-string.exp
new file mode 100644
index 0000000..0869912
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/break-f-std-string.exp
@@ -0,0 +1,105 @@
+# 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
+}
diff --git a/gdb/testsuite/gdb.cp/no-dmgl-verbose.exp b/gdb/testsuite/gdb.cp/no-dmgl-verbose.exp
deleted file mode 100644
index 14f11dd..0000000
--- a/gdb/testsuite/gdb.cp/no-dmgl-verbose.exp
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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"