OSDN Git Service

* cp-demangle.c (struct d_print_mod): Add templates field.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Nov 2003 23:33:05 +0000 (23:33 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Nov 2003 23:33:05 +0000 (23:33 +0000)
(d_make_builtin_type): Check for NULL type.
(d_make_extended_operator): Check for NULL name.
(d_make_ctor, d_make_dtor): Likewise.
(d_mangled_name): Add top_level parameter.  Change all callers.
(d_encoding): If DMGL_PARAMS is not set, strip off initial
CV-qualifiers.
(d_type): Check some return values we rely on.
(d_bare_function_type, d_array_type): Likewise.
(d_pointer_to_member_type, d_template_args): Likewise.
(d_add_substitution): Fail if argument is NULL.
(d_print_resize): Check whether buf is NULL.
(d_print_comp): Save current templates list with each modifier.
Don't pass the modifier list down when printing a template.
(d_print_cast): Don't pass the modifier list down when printing a
template.
(d_print_mod_list): Temporarily set templates list while printing
a modifier.
(d_print_mod): Check that buf is not NULL before using it.
(d_print_function_type): Print parens if there is no modifier.
(d_init_info): Permit as many substitutions as there are
characters in the mangled name.
* testsuite/demangle-expected: Add two new test cases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73970 138bc75d-0d04-0410-961f-82ee72b054a4

libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/testsuite/demangle-expected

index 358d81f..2f5f7b5 100644 (file)
@@ -1,3 +1,29 @@
+2003-11-26  Ian Lance Taylor  <ian@wasabisystems.com>
+
+       * cp-demangle.c (struct d_print_mod): Add templates field.
+       (d_make_builtin_type): Check for NULL type.
+       (d_make_extended_operator): Check for NULL name.
+       (d_make_ctor, d_make_dtor): Likewise.
+       (d_mangled_name): Add top_level parameter.  Change all callers.
+       (d_encoding): If DMGL_PARAMS is not set, strip off initial
+       CV-qualifiers.
+       (d_type): Check some return values we rely on.
+       (d_bare_function_type, d_array_type): Likewise.
+       (d_pointer_to_member_type, d_template_args): Likewise.
+       (d_add_substitution): Fail if argument is NULL.
+       (d_print_resize): Check whether buf is NULL.
+       (d_print_comp): Save current templates list with each modifier.
+       Don't pass the modifier list down when printing a template.
+       (d_print_cast): Don't pass the modifier list down when printing a
+       template.
+       (d_print_mod_list): Temporarily set templates list while printing
+       a modifier.
+       (d_print_mod): Check that buf is not NULL before using it.
+       (d_print_function_type): Print parens if there is no modifier.
+       (d_init_info): Permit as many substitutions as there are
+       characters in the mangled name.
+       * testsuite/demangle-expected: Add two new test cases.
+
 2003-11-25  Ian Lance Taylor  <ian@wasabisystems.com>
 
        * cp-demangle.c (java_demangle_v3): Pass DMGL_PARAMS to
index a0b8494..bd67958 100644 (file)
@@ -331,6 +331,8 @@ struct d_print_mod
   const struct d_comp *mod;
   /* Whether this modifier was printed.  */
   int printed;
+  /* The list of templates which applies to this modifier.  */
+  struct d_print_template *templates;
 };
 
 /* We use this structure to hold information during printing.  */
@@ -411,7 +413,7 @@ static struct d_comp *d_make_dtor PARAMS ((struct d_info *,
                                           struct d_comp *));
 static struct d_comp *d_make_template_param PARAMS ((struct d_info *, long));
 static struct d_comp *d_make_sub PARAMS ((struct d_info *, const char *));
-static struct d_comp *d_mangled_name PARAMS ((struct d_info *));
+static struct d_comp *d_mangled_name PARAMS ((struct d_info *, int));
 static int has_return_type PARAMS ((struct d_comp *));
 static int is_ctor_dtor_or_conversion PARAMS ((struct d_comp *));
 static struct d_comp *d_encoding PARAMS ((struct d_info *, int));
@@ -664,7 +666,8 @@ d_make_comp (di, type, left, right)
   struct d_comp *p;
 
   /* We check for errors here.  A typical error would be a NULL return
-     from a subroutine.  We catch here, and return NULL on upward.  */
+     from a subroutine.  We catch those here, and return NULL
+     upward.  */
   switch (type)
     {
       /* These types require two parameters.  */
@@ -766,6 +769,8 @@ d_make_builtin_type (di, type)
 {
   struct d_comp *p;
 
+  if (type == NULL)
+    return NULL;
   p = d_make_empty (di, D_COMP_BUILTIN_TYPE);
   if (p != NULL)
     p->u.s_builtin.type = type;
@@ -797,6 +802,8 @@ d_make_extended_operator (di, args, name)
 {
   struct d_comp *p;
 
+  if (name == NULL)
+    return NULL;
   p = d_make_empty (di, D_COMP_EXTENDED_OPERATOR);
   if (p != NULL)
     {
@@ -816,6 +823,8 @@ d_make_ctor (di, kind,  name)
 {
   struct d_comp *p;
 
+  if (name == NULL)
+    return NULL;
   p = d_make_empty (di, D_COMP_CTOR);
   if (p != NULL)
     {
@@ -835,6 +844,8 @@ d_make_dtor (di, kind, name)
 {
   struct d_comp *p;
 
+  if (name == NULL)
+    return NULL;
   p = d_make_empty (di, D_COMP_DTOR);
   if (p != NULL)
     {
@@ -874,17 +885,20 @@ d_make_sub (di, name)
   return p;
 }
 
-/* <mangled-name> ::= _Z <encoding> */
+/* <mangled-name> ::= _Z <encoding>
+
+   TOP_LEVEL is non-zero when called at the top level.  */
 
 static struct d_comp *
-d_mangled_name (di)
+d_mangled_name (di, top_level)
      struct d_info *di;
+     int top_level;
 {
   if (d_next_char (di) != '_')
     return NULL;
   if (d_next_char (di) != 'Z')
     return NULL;
-  return d_encoding (di, 1);
+  return d_encoding (di, top_level);
 }
 
 /* Return whether a function should have a return type.  The argument
@@ -961,10 +975,21 @@ d_encoding (di, top_level)
       struct d_comp *dc;
 
       dc = d_name (di);
+
+      if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
+       {
+         /* Strip off any initial CV-qualifiers, as they really apply
+            to the `this' parameter, and they were not output by the
+            v2 demangler without DMGL_PARAMS.  */
+         while (dc->type == D_COMP_RESTRICT
+                || dc->type == D_COMP_VOLATILE
+                || dc->type == D_COMP_CONST)
+           dc = d_left (dc);
+         return dc;
+       }
+
       peek = d_peek_char (di);
-      if (peek == '\0'
-         || peek == 'E'
-         || (top_level && (di->options & DMGL_PARAMS) == 0))
+      if (peek == '\0' || peek == 'E')
        return dc;
       return d_make_comp (di, D_COMP_TYPED_NAME, dc,
                          d_bare_function_type (di, has_return_type (dc)));
@@ -1610,9 +1635,13 @@ d_type (di)
      CV-qualifiers would cause subsets to be substitutable, so instead
      we pull them all off now.
 
-     FIXME: The ABI specifies that vendor qualifiers are handled just
-     like the standard CV-qualifiers with respect to subsetting and
-     substitution, but g++ does not appear to work this way.  */
+     FIXME: The ABI says that order-insensitive vendor qualifiers
+     should be handled in the same way, but we have no way to tell
+     which vendor qualifiers are order-insensitive and which are
+     order-sensitive.  So we just assume that they are all
+     order-sensitive.  g++ 3.4 supports only one vendor qualifier,
+     __vector, and it treats it as order-sensitive when mangling
+     names.  */
 
   peek = d_peek_char (di);
   if (peek == 'r' || peek == 'V' || peek == 'K')
@@ -1620,6 +1649,8 @@ d_type (di)
       struct d_comp **pret;
 
       pret = d_cv_qualifiers (di, &ret);
+      if (pret == NULL)
+       return NULL;
       *pret = d_type (di);
       if (! d_add_substitution (di, ret))
        return NULL;
@@ -1703,7 +1734,7 @@ d_type (di)
               a new substitution candidate.  However, if the
               substitution was followed by template arguments, then
               the whole thing is a substitution candidate.  */
-           if (ret->type == D_COMP_SUB_STD)
+           if (ret != NULL && ret->type == D_COMP_SUB_STD)
              can_subst = 0;
          }
       }
@@ -1836,6 +1867,8 @@ d_bare_function_type (di, has_return_type)
       else
        {
          *ptl = d_make_comp (di, D_COMP_ARGLIST, type, NULL);
+         if (*ptl == NULL)
+           return NULL;
          ptl = &d_right (*ptl);
        }
     }
@@ -1893,6 +1926,8 @@ d_array_type (di)
        }
       while (IS_DIGIT (peek));
       dim = d_make_name (di, s, d_str (di) - s);
+      if (dim == NULL)
+       return NULL;
     }
   else
     {
@@ -1936,6 +1971,8 @@ d_pointer_to_member_type (di)
      avoid calling add_substitution() in d_type().  */
 
   pmem = d_cv_qualifiers (di, &mem);
+  if (pmem == NULL)
+    return NULL;
   *pmem = d_type (di);
 
   return d_make_comp (di, D_COMP_PTRMEM_TYPE, cl, mem);
@@ -1999,6 +2036,8 @@ d_template_args (di)
        return NULL;
 
       *pal = d_make_comp (di, D_COMP_TEMPLATE_ARGLIST, a, NULL);
+      if (*pal == NULL)
+       return NULL;
       pal = &d_right (*pal);
 
       if (d_peek_char (di) == 'E')
@@ -2152,7 +2191,7 @@ d_expr_primary (di)
   if (d_next_char (di) != 'L')
     return NULL;
   if (d_peek_char (di) == '_')
-    ret = d_mangled_name (di);
+    ret = d_mangled_name (di, 0);
   else
     {
       struct d_comp *type;
@@ -2247,6 +2286,8 @@ d_add_substitution (di, dc)
      struct d_info *di;
      struct d_comp *dc;
 {
+  if (dc == NULL)
+    return 0;
   if (di->next_sub >= di->num_subs)
     return 0;
   di->subs[di->next_sub] = dc;
@@ -2341,6 +2382,8 @@ d_print_resize (dpi, add)
 {
   size_t need;
 
+  if (dpi->buf == NULL)
+    return;
   need = dpi->len + add;
   while (need > dpi->alc)
     {
@@ -2505,6 +2548,7 @@ d_print_comp (dpi, dc)
        dpi->modifiers = &dpm;
        dpm.mod = typed_name;
        dpm.printed = 0;
+       dpm.templates = dpi->templates;
 
        /* If typed_name is a template, then it applies to the
           function type as well.  */
@@ -2545,15 +2589,29 @@ d_print_comp (dpi, dc)
       }
 
     case D_COMP_TEMPLATE:
-      d_print_comp (dpi, d_left (dc));
-      d_append_char (dpi, '<');
-      d_print_comp (dpi, d_right (dc));
-      /* Avoid generating two consecutive '>' characters, to avoid the
-        C++ syntactic ambiguity.  */
-      if (dpi->buf[dpi->len - 1] == '>')
-       d_append_char (dpi, ' ');
-      d_append_char (dpi, '>');
-      return;
+      {
+       struct d_print_mod *hold_dpm;
+
+       /* Don't push modifiers into a template definition.  Doing so
+          could give the wrong definition for a template argument.
+          Instead, treat the template essentially as a name.  */
+
+       hold_dpm = dpi->modifiers;
+       dpi->modifiers = NULL;
+
+       d_print_comp (dpi, d_left (dc));
+       d_append_char (dpi, '<');
+       d_print_comp (dpi, d_right (dc));
+       /* Avoid generating two consecutive '>' characters, to avoid
+          the C++ syntactic ambiguity.  */
+       if (dpi->buf != NULL && dpi->buf[dpi->len - 1] == '>')
+         d_append_char (dpi, ' ');
+       d_append_char (dpi, '>');
+
+       dpi->modifiers = hold_dpm;
+
+       return;
+      }
 
     case D_COMP_TEMPLATE_PARAM:
       {
@@ -2692,6 +2750,7 @@ d_print_comp (dpi, dc)
        dpi->modifiers = &dpm;
        dpm.mod = dc;
        dpm.printed = 0;
+       dpm.templates = dpi->templates;
 
        d_print_comp (dpi, d_left (dc));
 
@@ -2729,6 +2788,7 @@ d_print_comp (dpi, dc)
            dpi->modifiers = &dpm;
            dpm.mod = dc;
            dpm.printed = 0;
+           dpm.templates = dpi->templates;
 
            d_print_comp (dpi, d_left (dc));
 
@@ -2756,6 +2816,7 @@ d_print_comp (dpi, dc)
        dpi->modifiers = &dpm;
        dpm.mod = dc;
        dpm.printed = 0;
+       dpm.templates = dpi->templates;
 
        d_print_comp (dpi, d_right (dc));
 
@@ -2789,6 +2850,7 @@ d_print_comp (dpi, dc)
        dpi->modifiers = &dpm;
        dpm.mod = dc;
        dpm.printed = 0;
+       dpm.templates = dpi->templates;
 
        d_print_comp (dpi, target_type);
 
@@ -3035,29 +3097,36 @@ d_print_mod_list (dpi, mods)
      struct d_print_info *dpi;
      struct d_print_mod *mods;
 {
+  struct d_print_template *hold_dpt;
+
   if (mods == NULL || mods->printed || d_print_saw_error (dpi))
     return;
 
+  mods->printed = 1;
+
+  hold_dpt = dpi->templates;
+  dpi->templates = mods->templates;
+
   if (mods->mod->type == D_COMP_FUNCTION_TYPE)
     {
-      mods->printed = 1;
       d_print_function_type (dpi, mods->mod, mods->next);
+      dpi->templates = hold_dpt;
       return;
     }
   else if (mods->mod->type == D_COMP_ARRAY_TYPE)
     {
-      mods->printed = 1;
       d_print_array_type (dpi, mods->mod, mods->next);
+      dpi->templates = hold_dpt;
       return;
     }
 
-  mods->printed = 1;
-
   d_print_mod (dpi, mods->mod);
 
+  dpi->templates = hold_dpt;
+
   d_print_mod_list (dpi, mods->next);
 }
+
 /* Print a modifier.  */
 
 static void
@@ -3095,7 +3164,7 @@ d_print_mod (dpi, mod)
       d_append_string (dpi, "imaginary ");
       return;
     case D_COMP_PTRMEM_TYPE:
-      if (dpi->buf[dpi->len - 1] != '(')
+      if (dpi->buf != NULL && dpi->buf[dpi->len - 1] != '(')
        d_append_char (dpi, ' ');
       d_print_comp (dpi, d_left (mod));
       d_append_string (dpi, "::*");
@@ -3119,51 +3188,48 @@ d_print_function_type (dpi, dc, mods)
      const struct d_comp *dc;
      struct d_print_mod *mods;
 {
-  if (mods != NULL)
+  int need_paren;
+  int saw_mod;
+  struct d_print_mod *p;
+
+  need_paren = 0;
+  saw_mod = 0;
+  for (p = mods; p != NULL; p = p->next)
     {
-      int need_paren;
-      int saw_mod;
-      struct d_print_mod *p;
+      if (p->printed)
+       break;
 
-      need_paren = 0;
-      saw_mod = 0;
-      for (p = mods; p != NULL; p = p->next)
+      saw_mod = 1;
+      switch (p->mod->type)
        {
-         if (p->printed)
-           break;
-
-         saw_mod = 1;
-         switch (p->mod->type)
-           {
-           case D_COMP_RESTRICT:
-           case D_COMP_VOLATILE:
-           case D_COMP_CONST:
-           case D_COMP_VENDOR_TYPE_QUAL:
-           case D_COMP_POINTER:
-           case D_COMP_REFERENCE:
-           case D_COMP_COMPLEX:
-           case D_COMP_IMAGINARY:
-           case D_COMP_PTRMEM_TYPE:
-             need_paren = 1;
-             break;
-           default:
-             break;
-           }
-         if (need_paren)
-           break;
+       case D_COMP_RESTRICT:
+       case D_COMP_VOLATILE:
+       case D_COMP_CONST:
+       case D_COMP_VENDOR_TYPE_QUAL:
+       case D_COMP_POINTER:
+       case D_COMP_REFERENCE:
+       case D_COMP_COMPLEX:
+       case D_COMP_IMAGINARY:
+       case D_COMP_PTRMEM_TYPE:
+         need_paren = 1;
+         break;
+       default:
+         break;
        }
+      if (need_paren)
+       break;
+    }
 
-      if (d_left (dc) != NULL && ! saw_mod)
-       need_paren = 1;
+  if (d_left (dc) != NULL && ! saw_mod)
+    need_paren = 1;
 
-      if (need_paren)
-       d_append_char (dpi, '(');
+  if (need_paren)
+    d_append_char (dpi, '(');
 
-      d_print_mod_list (dpi, mods);
+  d_print_mod_list (dpi, mods);
 
-      if (need_paren)
-       d_append_char (dpi, ')');
-    }
+  if (need_paren)
+    d_append_char (dpi, ')');
 
   d_append_char (dpi, '(');
 
@@ -3252,6 +3318,7 @@ d_print_cast (dpi, dc)
     d_print_comp (dpi, d_left (dc));
   else
     {
+      struct d_print_mod *hold_dpm;
       struct d_print_template dpt;
 
       /* It appears that for a templated cast operator, we need to put
@@ -3259,6 +3326,9 @@ d_print_cast (dpi, dc)
         not for the parameters.  The effect is that we need to handle
         the template printing here.  FIXME: Verify this.  */
 
+      hold_dpm = dpi->modifiers;
+      dpi->modifiers = NULL;
+
       dpt.next = dpi->templates;
       dpi->templates = &dpt;
       dpt.template = d_left (dc);
@@ -3271,9 +3341,11 @@ d_print_cast (dpi, dc)
       d_print_comp (dpi, d_right (d_left (dc)));
       /* Avoid generating two consecutive '>' characters, to avoid
         the C++ syntactic ambiguity.  */
-      if (dpi->buf[dpi->len - 1] == '>')
+      if (dpi->buf != NULL && dpi->buf[dpi->len - 1] == '>')
        d_append_char (dpi, ' ');
       d_append_char (dpi, '>');
+
+      dpi->modifiers = hold_dpm;
     }
 }
 
@@ -3301,9 +3373,8 @@ d_init_info (mangled, options, len, di)
   di->next_comp = 0;
 
   /* Similarly, we can not need more substitutions than there are
-     chars in the mangled string divided by 2, since it takes at least
-     two chars to refer to a substitution.  */
-  di->num_subs = (len + 1) / 2;
+     chars in the mangled string.  */
+  di->num_subs = len;
   di->subs = (struct d_comp **) malloc (di->num_subs
                                        * sizeof (struct d_comp *));
   di->next_sub = 0;
@@ -3381,7 +3452,7 @@ d_demangle (mangled, options, palc)
     }
 
   if (! type)
-    dc = d_mangled_name (&di);
+    dc = d_mangled_name (&di, 1);
   else
     dc = d_type (&di);
 
@@ -3584,7 +3655,7 @@ is_ctor_or_dtor (mangled, ctor_kind, dtor_kind)
   if (! d_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di))
     return 0;
 
-  dc = d_mangled_name (&di);
+  dc = d_mangled_name (&di, 1);
 
   if (dc == NULL)
     return 0;
index c73ea30..bfe9253 100644 (file)
@@ -2879,6 +2879,14 @@ void f<1>(A<(1) + (((int)(-((float)3f800000))))>)
 _ZNK11__gnu_debug16_Error_formatter14_M_format_wordImEEvPciPKcT_
 void __gnu_debug::_Error_formatter::_M_format_word<unsigned long>(char*, int, char const*, unsigned long) const
 #
+# The new demangler used to core dump on this.
+--format=gnu-v3
+_ZSt18uninitialized_copyIN9__gnu_cxx17__normal_iteratorIPSt4pairISsPFbP6sqlitePPcEESt6vectorIS9_SaIS9_EEEESE_ET0_T_SG_SF_
+__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > > std::uninitialized_copy<__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > > >(__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >)
+# The new demangler used to fail on this.
+--format=gnu-v3
+_Z1fP1cIPFiiEE
+f(c<int (*)(int)>*)
 # 
 # This caused an infinite loop.
 # We still don't demangle this correctly, but at least we don't hang.