RFC: fix PR 12707

Tom Tromey
2013-01-14T19:31:20Z

This patch fixes PR 12707.
It probably needs various preceding patches, though I didn't really
check in detail.

The bug here is that "set print demangle off" hasn't worked properly
since the physname patches went in.

The basic problem is something Doug pointed out a while ago: the DWARF
reader puts the demangled name into the general_symbol_info, and the
demangled name in the cplus_specific structure is empty.

While looking into this I also noticed that the physname code is
generally avoiding the demangled name hash. This is not ideal, because
it means that names that don't require the physname treatment (that is,
ones with a linkage name) are using more memory than is strictly
necessary.

The situation here is still not totally ideal:
* There are still some physname bugs, see bugzilla
* gdb calls cplus_demangle in many places with different options.
This seems like it ought to cause bugs. (See below for an instance.)
* The name-setting code in new_symbol_full is now a mess; though
I argue with 3 or 4 "get a DWARF name" functions we were already well
down this road.

Regression testing this showed two things. First, the py-symbol.exp
test is clearly wrong.

Second, I had to change cmpd-minsyms.exp to account for the symtab.c
change, which in turn was required to align symbol_find_demangled_name
with what dwarf2read.c is doing.

This is the one bit I am unsure about.

Built and regtested on x86-64.
New test case included.

Tom

PR symtab/12707:
* dwarf2read.c (new_symbol_full): Preserve the mangled name.
* symtab.c (symbol_find_demangled_name): Pass DMGL_RET_DROP
to cplus_demangle.

* gdb.cp/cmpd-minsyms.exp: Don't expect return type.
* gdb.cp/print-demangle.exp: New file.
* gdb.python/py-symbol.exp: Fix expected linkage name.
---
gdb/dwarf2read.c | 52 ++++++++++++++++++++++++------
gdb/symtab.c | 2 +-
gdb/testsuite/gdb.cp/cmpd-minsyms.exp | 6 +--
gdb/testsuite/gdb.cp/print-demangle.exp | 32 +++++++++++++++++++
gdb/testsuite/gdb.python/py-symbol.exp | 2 +-
5 files changed, 77 insertions(+), 17 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/print-demangle.exp

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4357746..76e3a79 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -15746,7 +15746,6 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
name = dwarf2_name (die, cu);
if (name)
{
- const char *linkagename;
int suppress_add = 0;

if (space)
@@ -15757,16 +15756,47 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,

/* Cache this symbol's name and the name's demangled form (if any). */
SYMBOL_SET_LANGUAGE (sym, cu->language);
- linkagename = dwarf2_physname (name, die, cu);
- SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
-
- /* Fortran does not have mangling standard and the mangling does differ
- between gfortran, iFort etc. */
- if (cu->language == language_fortran
- && symbol_get_demangled_name (&(sym->ginfo)) == NULL)
- symbol_set_demangled_name (&(sym->ginfo),
- dwarf2_full_name (name, die, cu),
- NULL);
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+
+ if (cu->language != language_fortran
+ && (attr != NULL && DW_STRING (attr) != NULL)
+ /* If this DIE does not need a namespace, but we have a
+ mangled form, then we may be seeing a static variable in
+ a method -- but we don't want to use the ordinary
+ demangler in this case. */
+ && die_needs_namespace (die, cu))
+ {
+ /* Let the symtab code do the demangling. The main benefit
+ of this approach is better caching. */
+ SYMBOL_SET_NAMES (sym, DW_STRING (attr), strlen (DW_STRING (attr)),
+ 0, objfile);
+ }
+ else
+ {
+ const char *physname;
+
+ physname = dwarf2_physname (name, die, cu);
+ /* If we have a mangled form, make sure to preserve it. */
+ if (cu->language != language_fortran
+ && attr != NULL && DW_STRING (attr) != NULL)
+ {
+ SYMBOL_LINKAGE_NAME (sym) = DW_STRING (attr);
+ symbol_set_demangled_name (&(sym->ginfo), physname, objfile);
+ }
+ else
+ SYMBOL_SET_NAMES (sym, physname, strlen (physname), 0, objfile);
+
+ /* Fortran does not have mangling standard and the mangling
+ does differ between gfortran, iFort etc. */
+ if (cu->language == language_fortran
+ && symbol_get_demangled_name (&(sym->ginfo)) == NULL)
+ symbol_set_demangled_name (&(sym->ginfo),
+ dwarf2_full_name (name, die, cu),
+ objfile);
+ }

/* Default assumptions.
Use the passed type or decode it from the die. */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 59ef4c1..5e0f5d4 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -586,7 +586,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
|| gsymbol->language == language_auto)
{
demangled =
- cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+ cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_RET_DROP);
if (demangled != NULL)
{
gsymbol->language = language_cplus;
diff --git a/gdb/testsuite/gdb.cp/cmpd-minsyms.exp b/gdb/testsuite/gdb.cp/cmpd-minsyms.exp
index 49ee0ed..e6dc4d2 100644
--- a/gdb/testsuite/gdb.cp/cmpd-minsyms.exp
+++ b/gdb/testsuite/gdb.cp/cmpd-minsyms.exp
@@ -43,15 +43,13 @@ foreach sym $min_syms {
gdb_test_no_output "set language c++"

# A list of minimal symbol names to check.
-# Note that GDB<char>::even_harder<int>(char) is quoted and includes
-# the return type. This is necessary because this is the demangled name
-# of the minimal symbol.
+# Note that GDB<char>::even_harder<int>(char) is quoted.
set min_syms [list \
"GDB<int>::operator ==" \
"GDB<int>::operator==(GDB<int> const&)" \
"GDB<char>::harder(char)" \
"GDB<int>::harder(int)" \
- {"int GDB<char>::even_harder<int>(char)"} \
+ {"GDB<char>::even_harder<int>(char)"} \
"GDB<int>::simple()"]

foreach sym $min_syms {
diff --git a/gdb/testsuite/gdb.cp/print-demangle.exp b/gdb/testsuite/gdb.cp/print-demangle.exp
new file mode 100644
index 0000000..b60e029
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/print-demangle.exp
@@ -0,0 +1,32 @@
+# Copyright (C) 2013 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/>.
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile bool.cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+ return -1
+}
+
+runto_main
+
+gdb_breakpoint "return_true"
+
+gdb_continue_to_breakpoint "return_true"
+
+gdb_test_no_output "set print demangle off"
+
+gdb_test "frame" " _Z11return_truev .*"
diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp
index f67af54..a9fdff7 100644
--- a/gdb/testsuite/gdb.python/py-symbol.exp
+++ b/gdb/testsuite/gdb.python/py-symbol.exp
@@ -142,7 +142,7 @@ gdb_test "python print (cplusfunc.is_argument)" "False" "Test func.is_argument"
gdb_test "python print (cplusfunc.is_function)" "True" "Test func.is_function"
gdb_test "python print (cplusfunc.name)" "SimpleClass::valueofi().*" "Test func.name"
gdb_test "python print (cplusfunc.print_name)" "SimpleClass::valueofi().*" "Test func.print_name"
-gdb_test "python print (cplusfunc.linkage_name)" "SimpleClass::valueofi().*" "Test func.linkage_name"
+gdb_test "python print (cplusfunc.linkage_name)" _ZN11SimpleClass8valueofiEv "Test func.linkage_name"
gdb_test "python print (cplusfunc.addr_class == gdb.SYMBOL_LOC_BLOCK)" "True" "Test func.addr_class"

# Test is_valid when the objfile is unloaded. This must be the last
--
1.7.7.6