gdb
authorTom Tromey <tromey@redhat.com>
Tue, 29 Mar 2011 17:04:31 +0000 (17:04 +0000)
committerTom Tromey <tromey@redhat.com>
Tue, 29 Mar 2011 17:04:31 +0000 (17:04 +0000)
* 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.
gdb/testsuite
* gdb.cp/anon-struct.cc: New file.
* gdb.cp/anon-struct.exp: New file.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/anon-struct.cc [new file with mode: 0644]
gdb/testsuite/gdb.cp/anon-struct.exp [new file with mode: 0644]
gdb/valops.c

index 3a53ad21ad14e8ca31dd6693f2724dc5693979a8..16eaa84e23b94022bde2b28452777e390fb506cd 100644 (file)
@@ -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.
index 709e81d7a841253b0743fb8770ea189c23abd38d..df8f863583afcf9d4f1af1e29a261680ce45c05c 100644 (file)
@@ -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:
index fa575d01674f407ac1cdf604bbfcf0eb67309c19..6cc74449a7dd6f8cff3b4cca0ff34ec235b6593f 100644 (file)
@@ -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 (file)
index 0000000..468ab47
--- /dev/null
@@ -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 (file)
index 0000000..0afb99a
--- /dev/null
@@ -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"
index b9f55081a1dc283034612f5666177e10fe442094..99115b73c0a9d7752fc5799cb3c3511628856022 100644 (file)
@@ -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))