aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/dwarf2read.c56
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.cp/anon-struct.cc58
-rw-r--r--gdb/testsuite/gdb.cp/anon-struct.exp31
-rw-r--r--gdb/valops.c19
6 files changed, 168 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3a53ad2..16eaa84 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2011-03-29 Tom Tromey <tromey@redhat.com>
+
+ * dwarf2read.c (fixup_partial_die): Handle linkage name on
+ otherwise anonymous types.
+ (dwarf2_name): Likewise.
+ * valops.c (value_struct_elt_for_reference): Refine artificial
+ type logic. Call error if j==-1.
+
2011-03-29 Andreas Tobler <andreast-list@fgznet.ch>
Fix false GCC warning.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 709e81d..df8f863 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -9363,6 +9363,25 @@ fixup_partial_die (struct partial_die_info *part_die,
|| part_die->tag == DW_TAG_union_type))
guess_partial_die_structure_name (part_die, cu);
+ /* GCC might emit a nameless struct or union that has a linkage
+ name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
+ if (part_die->name == NULL
+ && (part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_union_type
+ || part_die->tag == DW_TAG_class_type)
+ && part_die->linkage_name != NULL)
+ {
+ char *demangled;
+
+ demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES);
+ if (demangled)
+ {
+ part_die->name = obsavestring (demangled, strlen (demangled),
+ &cu->objfile->objfile_obstack);
+ xfree (demangled);
+ }
+ }
+
part_die->fixup_called = 1;
}
@@ -11960,7 +11979,11 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_name, cu);
- if (!attr || !DW_STRING (attr))
+ if ((!attr || !DW_STRING (attr))
+ && die->tag != DW_TAG_class_type
+ && die->tag != DW_TAG_interface_type
+ && die->tag != DW_TAG_structure_type
+ && die->tag != DW_TAG_union_type)
return NULL;
switch (die->tag)
@@ -12011,9 +12034,36 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
structures or unions. These were of the form "._%d" in GCC 4.1,
or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
and GCC 4.4. We work around this problem by ignoring these. */
- if (strncmp (DW_STRING (attr), "._", 2) == 0
- || strncmp (DW_STRING (attr), "<anonymous", 10) == 0)
+ if (attr && DW_STRING (attr)
+ && (strncmp (DW_STRING (attr), "._", 2) == 0
+ || strncmp (DW_STRING (attr), "<anonymous", 10) == 0))
return NULL;
+
+ /* GCC might emit a nameless typedef that has a linkage name. See
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
+ if (!attr || DW_STRING (attr) == NULL)
+ {
+ char *demangled;
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+
+ if (attr == NULL || DW_STRING (attr) == NULL)
+ return NULL;
+
+ demangled = cplus_demangle (DW_STRING (attr), DMGL_TYPES);
+
+ if (demangled)
+ {
+ /* FIXME: we already did this for the partial symbol... */
+ DW_STRING (attr)
+ = obsavestring (demangled, strlen (demangled),
+ &cu->objfile->objfile_obstack);
+ DW_STRING_IS_CANONICAL (attr) = 1;
+ xfree (demangled);
+ }
+ }
break;
default:
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index fa575d0..6cc7444 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-29 Tom Tromey <tromey@redhat.com>
+
+ * gdb.cp/anon-struct.cc: New file.
+ * gdb.cp/anon-struct.exp: New file.
+
2011-03-28 Jan Kratochvil <jan.kratochvil@redhat.com>
Test STT_GNU_IFUNC support.
diff --git a/gdb/testsuite/gdb.cp/anon-struct.cc b/gdb/testsuite/gdb.cp/anon-struct.cc
new file mode 100644
index 0000000..468ab47
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/anon-struct.cc
@@ -0,0 +1,58 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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/>.
+ */
+
+class C {
+public:
+ C() {}
+ ~C() {}
+};
+
+typedef struct {
+ C m;
+} t;
+
+t v;
+
+namespace X {
+ class C2 {
+ public:
+ C2() {}
+ };
+
+ typedef struct {
+ C2 m;
+ } t2;
+
+ t2 v2;
+}
+
+template<class T>
+class C3 {
+public:
+ ~C3() {}
+};
+
+typedef struct {
+ C3<int> m;
+} t3;
+
+t3 v3;
+
+int main()
+{
+}
diff --git a/gdb/testsuite/gdb.cp/anon-struct.exp b/gdb/testsuite/gdb.cp/anon-struct.exp
new file mode 100644
index 0000000..0afb99a
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/anon-struct.exp
@@ -0,0 +1,31 @@
+# Tests for anonymous union support.
+# Copyright 2011 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/>.
+
+set testfile anon-struct
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+ return -1
+}
+
+gdb_test "ptype t::t" "type = void \\(t \\* const\\)" \
+ "print type of t::t"
+
+gdb_test "ptype X::t2::t2" "type = void \\(X::t2 \\* const\\)" \
+ "print type of X::t2::t2"
+
+gdb_test "ptype t3::~t3" "type = void \\(t3 \\* const\\)" \
+ "print type of t3::~t3"
diff --git a/gdb/valops.c b/gdb/valops.c
index b9f5508..99115b7 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3339,25 +3339,32 @@ value_struct_elt_for_reference (struct type *domain, int offset,
int ii;
j = -1;
- for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i);
- ++ii)
+ for (ii = 0; ii < len; ++ii)
{
/* Skip artificial methods. This is necessary if,
for example, the user wants to "print
subclass::subclass" with only one user-defined
- constructor. There is no ambiguity in this
- case. */
+ constructor. There is no ambiguity in this case.
+ We are careful here to allow artificial methods
+ if they are the unique result. */
if (TYPE_FN_FIELD_ARTIFICIAL (f, ii))
- continue;
+ {
+ if (j == -1)
+ j = ii;
+ continue;
+ }
/* Desired method is ambiguous if more than one
method is defined. */
- if (j != -1)
+ if (j != -1 && !TYPE_FN_FIELD_ARTIFICIAL (f, j))
error (_("non-unique member `%s' requires "
"type instantiation"), name);
j = ii;
}
+
+ if (j == -1)
+ error (_("no matching member function"));
}
if (TYPE_FN_FIELD_STATIC_P (f, j))