OSDN Git Service

gdb
authorTom Tromey <tromey@redhat.com>
Tue, 31 Mar 2009 20:20:58 +0000 (20:20 +0000)
committerTom Tromey <tromey@redhat.com>
Tue, 31 Mar 2009 20:20:58 +0000 (20:20 +0000)
2009-03-31  Daniel Jacobowitz  <dan@codesourcery.com>
    Keith Seitz  <keiths@redhat.com>
    Jan Kratochvil  <jan.kratochvil@redhat.com>

PR gdb/6817
* Makefile.in (dbxread.o): Update.
* dbxread.c (read_dbx_symtab): Use cp_canonicalize_string.
* dwarf2read.c (GDB_FORM_cached_string): New.
(read_partial_die): Use dwarf2_canonicalize_name.
(dwarf2_linkage_name): Use dwarf2_name.
(dwarf2_canonicalize_name): New.
(dwarf2_name): Use dwarf2_canonicalize_name.
(dwarf_form_name, dump_die): Handle GDB_FORM_cached_string.
* stabsread.c (define_symbol, read_type): Use cp_canonicalize_string.
* symtab.c (lookup_symbol_in_language): Canonicalize input before
searching.
* cp-name-parser.y: operator() requires two parameters,
according to libiberty.
* minsyms.c (lookup_minimal_symbol): Canonicalize input
before searching.
* NEWS: Update.

gdb/testsuite

2009-03-31  Daniel Jacobowitz  <dan@codesourcery.com>
    Jan Kratochvil  <jan.kratochvil@redhat.com>

PR gdb/931
* gdb.cp/gdb1355.exp (f_li, f_lui, f_si, f_sui): Allow canonical
output.
* gdb.cp/templates.exp: Allow canonical output.  Remove KFAILs
for gdb/931.
* dw2-strp.S (DW_AT_language): Change to C++.
(DW_TAG_variable (name ""), Abbrev code 7, .Lemptyname): New.

12 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/cp-name-parser.y
gdb/dbxread.c
gdb/dwarf2read.c
gdb/minsyms.c
gdb/stabsread.c
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/gdb1355.exp
gdb/testsuite/gdb.cp/templates.exp
gdb/testsuite/gdb.dwarf2/dw2-strp.S

index ec689f5..1ff05ab 100644 (file)
@@ -1,3 +1,25 @@
+2009-03-31  Daniel Jacobowitz  <dan@codesourcery.com>
+           Keith Seitz  <keiths@redhat.com>
+           Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       PR gdb/6817
+       * Makefile.in (dbxread.o): Update.
+       * dbxread.c (read_dbx_symtab): Use cp_canonicalize_string.
+       * dwarf2read.c (GDB_FORM_cached_string): New.
+       (read_partial_die): Use dwarf2_canonicalize_name.
+       (dwarf2_linkage_name): Use dwarf2_name.
+       (dwarf2_canonicalize_name): New.
+       (dwarf2_name): Use dwarf2_canonicalize_name.
+       (dwarf_form_name, dump_die): Handle GDB_FORM_cached_string.
+       * stabsread.c (define_symbol, read_type): Use cp_canonicalize_string.
+       * symtab.c (lookup_symbol_in_language): Canonicalize input before
+       searching.
+       * cp-name-parser.y: operator() requires two parameters,
+       according to libiberty.
+       * minsyms.c (lookup_minimal_symbol): Canonicalize input
+       before searching.
+       * NEWS: Update.
+
 2009-03-31  Joel Brobecker  <brobecker@adacore.com>
 
        Provide support for (Ada) task-specific breakpoints.
index a8ddd45..589eeed 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -93,6 +93,19 @@ have also been fixed.
 From the user's standpoint, all unqualified instances of True and False
 are treated as the standard definitions, regardless of context.
 
+* GDB now parses C++ symbol and type names more flexibly.  For
+example, given:
+
+   template<typename T> class C { };
+   C<char const *> c;
+
+GDB will now correctly handle all of:
+
+   ptype C<char const *>
+   ptype C<char const*>
+   ptype C<const char *>
+   ptype C<const char*>
+
 * New features in the GDB remote stub, gdbserver
 
   - The "--wrapper" command-line argument tells gdbserver to use a
index 0b5069d..b70ad21 100644 (file)
@@ -499,7 +499,7 @@ operator    :       OPERATOR NEW
                |       OPERATOR ARROW
                        { $$ = make_operator ("->", 2); }
                |       OPERATOR '(' ')'
-                       { $$ = make_operator ("()", 0); }
+                       { $$ = make_operator ("()", 2); }
                |       OPERATOR '[' ']'
                        { $$ = make_operator ("[]", 2); }
                ;
index 115bdef..d520266 100644 (file)
@@ -1188,6 +1188,8 @@ read_dbx_symtab (struct objfile *objfile)
   struct internal_nlist nlist;
   CORE_ADDR text_addr;
   int text_size;
+  char *sym_name;
+  int sym_len;
 
   char *namestring;
   int nsl;
@@ -1681,6 +1683,28 @@ pos %d"),
          if (!p)
            continue;                   /* Not a debugging symbol.   */
 
+         sym_len = 0;
+         if (psymtab_language == language_cplus)
+           {
+             char *new_name, *name = alloca (p - namestring + 1);
+             memcpy (name, namestring, p - namestring);
+             name[p - namestring] = '\0';
+             new_name = cp_canonicalize_string (name);
+             if (new_name != NULL)
+               {
+                 sym_len = strlen (new_name);
+                 sym_name = obsavestring (new_name, sym_len,
+                                          &objfile->objfile_obstack);
+                 xfree (new_name);
+               }
+           }
+
+         if (sym_len == 0)
+           {
+             sym_name = namestring;
+             sym_len = p - namestring;
+           }
+
          /* Main processing section for debugging symbols which
             the initial read through the symbol tables needs to worry
             about.  If we reach this point, the symbol which we are
@@ -1698,7 +1722,7 @@ pos %d"),
                namestring = gdbarch_static_transform_name (gdbarch,
                                                            namestring);
 
-             add_psymbol_to_list (namestring, p - namestring,
+             add_psymbol_to_list (sym_name, sym_len,
                                   VAR_DOMAIN, LOC_STATIC,
                                   &objfile->static_psymbols,
                                   0, nlist.n_value,
@@ -1710,7 +1734,7 @@ pos %d"),
                                         data_sect_index);
              /* The addresses in these entries are reported to be
                 wrong.  See the code that reads 'G's for symtabs. */
-             add_psymbol_to_list (namestring, p - namestring,
+             add_psymbol_to_list (sym_name, sym_len,
                                   VAR_DOMAIN, LOC_STATIC,
                                   &objfile->global_psymbols,
                                   0, nlist.n_value,
@@ -1728,7 +1752,7 @@ pos %d"),
                  || (p == namestring + 1
                      && namestring[0] != ' '))
                {
-                 add_psymbol_to_list (namestring, p - namestring,
+                 add_psymbol_to_list (sym_name, sym_len,
                                       STRUCT_DOMAIN, LOC_TYPEDEF,
                                       &objfile->static_psymbols,
                                       nlist.n_value, 0,
@@ -1736,7 +1760,7 @@ pos %d"),
                  if (p[2] == 't')
                    {
                      /* Also a typedef with the same name.  */
-                     add_psymbol_to_list (namestring, p - namestring,
+                     add_psymbol_to_list (sym_name, sym_len,
                                           VAR_DOMAIN, LOC_TYPEDEF,
                                           &objfile->static_psymbols,
                                           nlist.n_value, 0,
@@ -1749,7 +1773,7 @@ pos %d"),
            case 't':
              if (p != namestring)      /* a name is there, not just :T... */
                {
-                 add_psymbol_to_list (namestring, p - namestring,
+                 add_psymbol_to_list (sym_name, sym_len,
                                       VAR_DOMAIN, LOC_TYPEDEF,
                                       &objfile->static_psymbols,
                                       nlist.n_value, 0,
@@ -1829,7 +1853,7 @@ pos %d"),
 
            case 'c':
              /* Constant, e.g. from "const" in Pascal.  */
-             add_psymbol_to_list (namestring, p - namestring,
+             add_psymbol_to_list (sym_name, sym_len,
                                   VAR_DOMAIN, LOC_CONST,
                                   &objfile->static_psymbols, nlist.n_value,
                                   0, psymtab_language, objfile);
@@ -1893,7 +1917,7 @@ pos %d"),
                  pst->textlow = nlist.n_value;
                  textlow_not_set = 0;
                }
-             add_psymbol_to_list (namestring, p - namestring,
+             add_psymbol_to_list (sym_name, sym_len,
                                   VAR_DOMAIN, LOC_BLOCK,
                                   &objfile->static_psymbols,
                                   0, nlist.n_value,
@@ -1961,7 +1985,7 @@ pos %d"),
                  pst->textlow = nlist.n_value;
                  textlow_not_set = 0;
                }
-             add_psymbol_to_list (namestring, p - namestring,
+             add_psymbol_to_list (sym_name, sym_len,
                                   VAR_DOMAIN, LOC_BLOCK,
                                   &objfile->global_psymbols,
                                   0, nlist.n_value,
index 9ec4efa..9fd2f0c 100644 (file)
@@ -523,6 +523,15 @@ struct attr_abbrev
     ENUM_BITFIELD(dwarf_form) form : 16;
   };
 
+/* Additional GDB-specific attribute forms.  */
+enum
+  {
+    /* A string which has been updated to GDB's internal
+       representation (e.g. converted to canonical form) and does not
+       need to be updated again.  */
+    GDB_FORM_cached_string = 0xff
+  };
+
 /* Attributes have a name and a value */
 struct attribute
   {
@@ -993,6 +1002,9 @@ static void process_die (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 
+static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
+                                      struct obstack *);
+
 static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
 static struct die_info *dwarf2_extension (struct die_info *die,
@@ -5946,10 +5958,23 @@ read_partial_die (struct partial_die_info *part_die,
       switch (attr.name)
        {
        case DW_AT_name:
-
-         /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name.  */
-         if (part_die->name == NULL)
-           part_die->name = DW_STRING (&attr);
+         switch (part_die->tag)
+           {
+           case DW_TAG_compile_unit:
+             /* Compilation units have a DW_AT_name that is a filename, not
+                a source language identifier.  */
+           case DW_TAG_enumeration_type:
+           case DW_TAG_enumerator:
+             /* These tags always have simple identifiers already; no need
+                to canonicalize them.  */
+             part_die->name = DW_STRING (&attr);
+             break;
+           default:
+             part_die->name
+               = dwarf2_canonicalize_name (DW_STRING (&attr), cu,
+                                           &cu->comp_unit_obstack);
+             break;
+           }
          break;
        case DW_AT_comp_dir:
          if (part_die->dirname == NULL)
@@ -8199,10 +8224,29 @@ dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
-  attr = dwarf2_attr (die, DW_AT_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return NULL;
+  return dwarf2_name (die, cu);
+}
+
+/* Get name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
+                         struct obstack *obstack)
+{
+  if (name && cu->language == language_cplus)
+    {
+      char *canon_name = cp_canonicalize_string (name);
+
+      if (canon_name != NULL)
+       {
+         if (strcmp (canon_name, name) != 0)
+           name = obsavestring (canon_name, strlen (canon_name),
+                                obstack);
+         xfree (canon_name);
+       }
+    }
+
+  return name;
 }
 
 /* Get name of a die, return NULL if not found.  */
@@ -8213,9 +8257,29 @@ 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))
-    return DW_STRING (attr);
-  return NULL;
+  if (!attr || !DW_STRING (attr))
+    return NULL;
+
+  switch (die->tag)
+    {
+    case DW_TAG_compile_unit:
+      /* Compilation units have a DW_AT_name that is a filename, not
+        a source language identifier.  */
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+      /* These tags always have simple identifiers already; no need
+        to canonicalize them.  */
+      return DW_STRING (attr);
+    default:
+      if (attr->form != GDB_FORM_cached_string)
+       {
+         DW_STRING (attr)
+           = dwarf2_canonicalize_name (DW_STRING (attr), cu,
+                                       &cu->objfile->objfile_obstack);
+         attr->form = GDB_FORM_cached_string;
+       }
+      return DW_STRING (attr);
+    }
 }
 
 /* Return the die that this die in an extension of, or NULL if there
@@ -8710,6 +8774,8 @@ dwarf_form_name (unsigned form)
       return "DW_FORM_ref_udata";
     case DW_FORM_indirect:
       return "DW_FORM_indirect";
+    case GDB_FORM_cached_string:
+      return "GDB_FORM_cached_string";
     default:
       return "DW_FORM_<unknown>";
     }
@@ -9255,6 +9321,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
          break;
        case DW_FORM_string:
        case DW_FORM_strp:
+       case GDB_FORM_cached_string:
          fprintf_unfiltered (f, "string: \"%s\"",
                   DW_STRING (&die->attrs[i])
                   ? DW_STRING (&die->attrs[i]) : "");
index bf776b3..e4b0f31 100644 (file)
@@ -48,6 +48,8 @@
 #include "value.h"
 #include "cp-abi.h"
 #include "target.h"
+#include "cp-support.h"
+#include "language.h"
 
 /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
    At the end, copy them all into one newly allocated location on an objfile's
@@ -187,6 +189,9 @@ lookup_minimal_symbol (const char *name, const char *sfile,
   unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
   unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
+  int needtofreename = 0;
+  const char *modified_name;
+
   if (sfile != NULL)
     {
       char *p = strrchr (sfile, '/');
@@ -194,6 +199,18 @@ lookup_minimal_symbol (const char *name, const char *sfile,
        sfile = p + 1;
     }
 
+  /* For C++, canonicalize the input name. */
+  modified_name = name;
+  if (current_language->la_language == language_cplus)
+    {
+      char *cname = cp_canonicalize_string (name);
+      if (cname)
+       {
+         modified_name = cname;
+         needtofreename = 1;
+       }
+    }
+
   for (objfile = object_files;
        objfile != NULL && found_symbol == NULL;
        objfile = objfile->next)
@@ -218,9 +235,16 @@ lookup_minimal_symbol (const char *name, const char *sfile,
                  int match;
 
                  if (pass == 1)
-                   match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0;
+                   {
+                     match = strcmp (SYMBOL_LINKAGE_NAME (msymbol),
+                                     modified_name) == 0;
+                   }
                  else
-                   match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, name);
+                   {
+                     match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
+                                                         modified_name);
+                   }
+
                  if (match)
                    {
                     switch (MSYMBOL_TYPE (msymbol))
@@ -259,6 +283,10 @@ lookup_minimal_symbol (const char *name, const char *sfile,
            }
        }
     }
+
+  if (needtofreename)
+    xfree ((void *) modified_name);
+
   /* External symbols are best.  */
   if (found_symbol)
     return found_symbol;
index 2d7eb15..17dfce4 100644 (file)
@@ -589,6 +589,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
   int deftype;
   int synonym = 0;
   int i;
+  char *new_name = NULL;
 
   /* We would like to eliminate nameless symbols, but keep their types.
      E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer
@@ -683,9 +684,21 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     {
     normal:
       SYMBOL_LANGUAGE (sym) = current_subfile->language;
-      SYMBOL_SET_NAMES (sym, string, p - string, objfile);
       if (SYMBOL_LANGUAGE (sym) == language_cplus)
-       cp_scan_for_anonymous_namespaces (sym);
+       {
+         char *name = alloca (p - string + 1);
+         memcpy (name, string, p - string);
+         name[p - string] = '\0';
+         new_name = cp_canonicalize_string (name);
+         cp_scan_for_anonymous_namespaces (sym);
+       }
+      if (new_name != NULL)
+       {
+         SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), objfile);
+         xfree (new_name);
+       }
+      else
+       SYMBOL_SET_NAMES (sym, string, p - string, objfile);
     }
   p++;
 
@@ -1519,18 +1532,35 @@ again:
              if (*p != ':')
                return error_type (pp, objfile);
            }
-         to = type_name =
-           (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1);
-
-         /* Copy the name.  */
-         from = *pp + 1;
-         while (from < p)
-           *to++ = *from++;
-         *to = '\0';
+         type_name = NULL;
+         if (current_subfile->language == language_cplus)
+           {
+             char *new_name, *name = alloca (p - *pp + 1);
+             memcpy (name, *pp, p - *pp);
+             name[p - *pp] = '\0';
+             new_name = cp_canonicalize_string (name);
+             if (new_name != NULL)
+               {
+                 type_name = obsavestring (new_name, strlen (new_name),
+                                           &objfile->objfile_obstack);
+                 xfree (new_name);
+               }
+           }
+         if (type_name == NULL)
+           {
+             to = type_name =
+               (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1);
+
+             /* Copy the name.  */
+             from = *pp + 1;
+             while (from < p)
+               *to++ = *from++;
+             *to = '\0';
+           }
 
          /* Set the pointer ahead of the name which we just read, and
             the colon.  */
-         *pp = from + 1;
+         *pp = p + 1;
        }
 
         /* If this type has already been declared, then reuse the same
index 7fff68a..622ddd3 100644 (file)
@@ -55,6 +55,7 @@
 #include "gdb_stat.h"
 #include <ctype.h>
 #include "cp-abi.h"
+#include "cp-support.h"
 #include "observer.h"
 #include "gdb_assert.h"
 #include "solist.h"
@@ -1213,6 +1214,17 @@ lookup_symbol_in_language (const char *name, const struct block *block,
          modified_name = demangled_name;
          make_cleanup (xfree, demangled_name);
        }
+      else
+       {
+         /* If we were given a non-mangled name, canonicalize it
+            according to the language (so far only for C++).  */
+         demangled_name = cp_canonicalize_string (name);
+         if (demangled_name)
+           {
+             modified_name = demangled_name;
+             make_cleanup (xfree, demangled_name);
+           }
+       }
     }
   else if (lang == language_java)
     {
index cf1378f..016bf54 100644 (file)
@@ -1,3 +1,14 @@
+2009-03-31  Daniel Jacobowitz  <dan@codesourcery.com>
+           Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       PR gdb/931
+       * gdb.cp/gdb1355.exp (f_li, f_lui, f_si, f_sui): Allow canonical
+       output.
+       * gdb.cp/templates.exp: Allow canonical output.  Remove KFAILs
+       for gdb/931.
+       * dw2-strp.S (DW_AT_language): Change to C++.
+       (DW_TAG_variable (name ""), Abbrev code 7, .Lemptyname): New.
+
 2009-03-31  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.ada/tasks: New testcase.
index 77687a6..8028bce 100644 (file)
@@ -68,11 +68,11 @@ set s_tail  ".*"
 
 set f_i     "${ws}int m_int;"
 set f_c     "${ws}char m_char;"
-set f_li    "${ws}long int m_long_int;"
+set f_li    "${ws}long( int)? m_long_int;"
 set f_ui    "${ws}unsigned int m_unsigned_int;"
-set f_lui   "${ws}long unsigned int m_long_unsigned_int;"
-set f_si    "${ws}short int m_short_int;"
-set f_sui   "${ws}short unsigned int m_short_unsigned_int;"
+set f_lui   "${ws}(long unsigned int|unsigned long) m_long_unsigned_int;"
+set f_si    "${ws}short( int)? m_short_int;"
+set f_sui   "${ws}(short unsigned int|unsigned short) m_short_unsigned_int;"
 set f_uc    "${ws}unsigned char m_unsigned_char;"
 set f_f     "${ws}float m_float;"
 set f_d     "${ws}double m_double;"
index cd9b770..f49caff 100644 (file)
@@ -329,13 +329,11 @@ gdb_expect {
 
 send_gdb "print Foo<volatile char *>::foo\n"   
 gdb_expect {   
-    -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<volatile char ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" }
+    -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" }
     -re "No symbol \"Foo<volatile char \\*>\" in current context.\r\n$gdb_prompt $"
     {
-       # This used to be a kfail gdb/33.  That problem has been
-       # fixed, but now gdb/931 and gdb/1512 are rearing their ugly
-       # heads.
-       kfail "gdb/931" "print Foo<volatile char *>::foo"
+       # This used to be a kfail gdb/33 and then kfail gdb/931.
+       fail "print Foo<volatile char *>::foo"
     }
     -re "$gdb_prompt $"                     { fail "print Foo<volatile char *>::foo" }
     timeout                             { fail "(timeout) print Foo<volatile char *>::foo" }
@@ -343,13 +341,11 @@ gdb_expect {
 
 send_gdb "print Foo<volatile char*>::foo\n"   
 gdb_expect {   
-    -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<volatile char ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char*>::foo" }
+    -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char*>::foo" }
     -re "No symbol \"Foo<volatile char\\*>\" in current context.\r\n$gdb_prompt $"
     {
-       # This used to be a kfail gdb/33.  That problem has been
-       # fixed, but now gdb/931 and gdb/1512 are rearing their ugly
-       # heads.
-       kfail "gdb/931" "print Foo<volatile char*>::foo"
+       # This used to be a kfail gdb/33 and then kfail gdb/931.
+       fail "print Foo<volatile char*>::foo"
     }
     -re "$gdb_prompt $"                     { fail "print Foo<volatile char*>::foo" }
     timeout                             { fail "(timeout) print Foo<volatile char*>::foo" }
@@ -459,7 +455,7 @@ send_gdb "ptype quxint\n"
 gdb_expect {   
    -re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
    -re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
-   -re "type = class Qux<int, ?\\(char ?\\*\\)\\(& ?string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
+   -re "type = class Qux<int, ?\\(char ?\\*\\)\\(& ?\\(?string\\)?\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
    -re "type = class Qux<int, ?& ?\\(string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
        kfail "gdb/1512" "ptype quxint"
    }
index a1602a5..293cc1b 100644 (file)
@@ -28,7 +28,8 @@
        /* CU die */
        .uleb128        1                       /* Abbrev: DW_TAG_compile_unit */
        .4byte          .Lproducer              /* DW_AT_producer */
-       .byte           1                       /* DW_AT_language (C) */
+       /* Use C++ to exploit a bug in parsing DW_AT_name "".  */
+       .byte           4                       /* DW_AT_language (C++) -  */
 
 .Larray_type:
        .uleb128        2                       /* Abbrev: DW_TAG_array_type */
 .Lconst_type:
        .uleb128        6                       /* Abbrev: DW_TAG_const_type */
        .4byte          .Larray_type-.Lcu1_begin/* DW_AT_type */
+
+       .uleb128        7                       /* Abbrev: DW_TAG_variable (name "") */
+       .4byte          .Lemptyname             /* DW_AT_name */
+
        .byte           0                       /* End of children of CU */
 .Lcu1_end:
 
        .uleb128        0x13                    /* DW_FORM_ref4 */
        .byte           0x0                     /* Terminator */
        .byte           0x0                     /* Terminator */
+
+       .uleb128        7                       /* Abbrev code */
+       .uleb128        0x34                    /* DW_TAG_variable */
+       .byte           0x0                     /* DW_children_no */
+       .uleb128        0x3                     /* DW_AT_name */
+       .uleb128        0xe                     /* DW_FORM_strp */
+       .byte           0x0                     /* Terminator */
+       .byte           0x0                     /* Terminator */
+
        .byte           0x0                     /* Terminator */
 
 /* String table */
        .string         "a_string"
 .Lvarcontents:
        .string         "hello world!\n"
+.Lemptyname:
+       .string         ""