cplus-dem.c (INTBUF_SIZE): New macro.
authorMark Mitchell <mark@codesourcery.com>
Tue, 19 Oct 1999 17:52:52 +0000 (17:52 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 19 Oct 1999 17:52:52 +0000 (17:52 +0000)
* cplus-dem.c (INTBUF_SIZE): New macro.
(string_append_template_idx): New function.
(demangle_expression): Likewise.
(demangle_integral_value): Use it.
(demangle_real_value): New function, split out from ...
(demangle_template_value_parm): ... here.  Use
string_append_template_idx.  Use demangle_real_value.
(demangle_template): Use string_append_template_idx.
(demangle_qualified): Use consume_count_with_underscores.
(get_count): Tweak formatting.
(do_type): Use string_append_template_idx.

From-SVN: r30091

libiberty/ChangeLog
libiberty/cplus-dem.c
libiberty/testsuite/demangle-expected

index 7fa6594..78180af 100644 (file)
@@ -1,3 +1,17 @@
+1999-10-19  Mark Mitchell  <mark@codesourcery.com>
+
+       * cplus-dem.c (INTBUF_SIZE): New macro.
+       (string_append_template_idx): New function.
+       (demangle_expression): Likewise.
+       (demangle_integral_value): Use it.
+       (demangle_real_value): New function, split out from ...
+       (demangle_template_value_parm): ... here.  Use
+       string_append_template_idx.  Use demangle_real_value.
+       (demangle_template): Use string_append_template_idx.
+       (demangle_qualified): Use consume_count_with_underscores.
+       (get_count): Tweak formatting.
+       (do_type): Use string_append_template_idx.
+       
 1999-10-18  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * calloc.c: Add a public domain notice.
index 6a6bc1a..7e8c74f 100644 (file)
@@ -53,6 +53,10 @@ char * realloc ();
 
 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
 
+/* A value at least one greater than the maximum number of characters
+   that will be output when using the `%d' format with `printf'.  */
+#define INTBUF_SIZE 32
+
 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
 
 static const char *mystrstr PARAMS ((const char *, const char *));
@@ -347,6 +351,9 @@ string_prepend PARAMS ((string *, const char *));
 static void
 string_prependn PARAMS ((string *, const char *, int));
 
+static void
+string_append_template_idx PARAMS ((string *, int));
+
 static int
 get_count PARAMS ((const char **, int *));
 
@@ -425,9 +432,16 @@ static const char*
 demangle_qualifier PARAMS ((int));
 
 static int
+demangle_expression PARAMS ((struct work_stuff *, const char **, string *, 
+                            type_kind_t));
+
+static int
 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
                                 string *));
 
+static int
+demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
+
 static void
 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
                                  string *));
@@ -1348,87 +1362,155 @@ demangle_template_template_parm (work, mangled, tname)
 }
 
 static int
-demangle_integral_value (work, mangled, s)
+demangle_expression (work, mangled, s, tk)
      struct work_stuff *work;
      const char** mangled;
      string* s;
+     type_kind_t tk;
 {
+  int need_operator = 0;
   int success;
 
-  if (**mangled == 'E')
+  success = 1;
+  string_appendn (s, "(", 1);
+  (*mangled)++;
+  while (success && **mangled != 'W' && **mangled != '\0')
     {
-      int need_operator = 0;
-
-      success = 1;
-      string_appendn (s, "(", 1);
-      (*mangled)++;
-      while (success && **mangled != 'W' && **mangled != '\0')
+      if (need_operator)
        {
-         if (need_operator)
-           {
-             size_t i;
-             size_t len;
+         size_t i;
+         size_t len;
 
-             success = 0;
+         success = 0;
 
-             len = strlen (*mangled);
+         len = strlen (*mangled);
 
-             for (i = 0;
-                  i < sizeof (optable) / sizeof (optable [0]);
-                  ++i)
-               {
-                 size_t l = strlen (optable[i].in);
+         for (i = 0;
+              i < sizeof (optable) / sizeof (optable [0]);
+              ++i)
+           {
+             size_t l = strlen (optable[i].in);
 
-                 if (l <= len
-                     && memcmp (optable[i].in, *mangled, l) == 0)
-                   {
-                     string_appendn (s, " ", 1);
-                     string_append (s, optable[i].out);
-                     string_appendn (s, " ", 1);
-                     success = 1;
-                     (*mangled) += l;
-                     break;
-                   }
+             if (l <= len
+                 && memcmp (optable[i].in, *mangled, l) == 0)
+               {
+                 string_appendn (s, " ", 1);
+                 string_append (s, optable[i].out);
+                 string_appendn (s, " ", 1);
+                 success = 1;
+                 (*mangled) += l;
+                 break;
                }
-
-             if (!success)
-               break;
            }
-         else
-           need_operator = 1;
 
-         success = demangle_template_value_parm (work, mangled, s,
-                                                 tk_integral);
+         if (!success)
+           break;
        }
-
-      if (**mangled != 'W')
-         success = 0;
       else
-       {
-         string_appendn (s, ")", 1);
-         (*mangled)++;
-       }
+       need_operator = 1;
+
+      success = demangle_template_value_parm (work, mangled, s, tk);
+    }
+
+  if (**mangled != 'W')
+    success = 0;
+  else
+    {
+      string_appendn (s, ")", 1);
+      (*mangled)++;
     }
+
+  return success;
+}
+
+static int
+demangle_integral_value (work, mangled, s)
+     struct work_stuff *work;
+     const char** mangled;
+     string* s;
+{
+  int success;
+
+  if (**mangled == 'E')
+    success = demangle_expression (work, mangled, s, tk_integral);
   else if (**mangled == 'Q' || **mangled == 'K')
     success = demangle_qualified (work, mangled, s, 0, 1);
   else
     {
+      int value;
+
       success = 0;
 
+      /* Negative numbers are indicated with a leading `m'.  */
       if (**mangled == 'm')
        {
          string_appendn (s, "-", 1);
          (*mangled)++;
        }
+
+      /* Read the rest of the number.  */
+      value = consume_count_with_underscores (mangled);
+      if (value != -1)
+       {
+         char buf[INTBUF_SIZE];
+         sprintf (buf, "%d", value);
+         string_append (s, buf);
+
+         /* If the next character is an underscore, skip it.  */
+         if (**mangled == '_')
+           (*mangled)++;
+
+         /* All is well.  */
+         success = 1;
+       }
+    }
+
+  return success;
+}
+
+/* Demangle the real value in MANGLED.  */
+
+static int
+demangle_real_value (work, mangled, s)
+     struct work_stuff *work;
+     const char **mangled;
+     string* s;
+{
+  if (**mangled == 'E')
+    return demangle_expression (work, mangled, s, tk_real);
+
+  if (**mangled == 'm')
+    {
+      string_appendn (s, "-", 1);
+      (*mangled)++;
+    }
+  while (isdigit ((unsigned char)**mangled))
+    {
+      string_appendn (s, *mangled, 1);
+      (*mangled)++;
+    }
+  if (**mangled == '.') /* fraction */
+    {
+      string_appendn (s, ".", 1);
+      (*mangled)++;
+      while (isdigit ((unsigned char)**mangled))
+       {
+         string_appendn (s, *mangled, 1);
+         (*mangled)++;
+       }
+    }
+  if (**mangled == 'e') /* exponent */
+    {
+      string_appendn (s, "e", 1);
+      (*mangled)++;
       while (isdigit ((unsigned char)**mangled))
        {
          string_appendn (s, *mangled, 1);
          (*mangled)++;
-         success = 1;
        }
     }
 
-  return success;
+  return 1;
 }
 
 static int
@@ -1454,11 +1536,7 @@ demangle_template_value_parm (work, mangled, s, tk)
       if (work->tmpl_argvec)
        string_append (s, work->tmpl_argvec[idx]);
       else
-       {
-         char buf[10];
-         sprintf(buf, "T%d", idx);
-         string_append (s, buf);
-       }
+       string_append_template_idx (s, idx);
     }
   else if (tk == tk_integral)
     success = demangle_integral_value (work, mangled, s);
@@ -1494,38 +1572,7 @@ demangle_template_value_parm (work, mangled, s, tk)
        success = 0;
     }
   else if (tk == tk_real)
-    {
-      if (**mangled == 'm')
-       {
-         string_appendn (s, "-", 1);
-         (*mangled)++;
-       }
-      while (isdigit ((unsigned char)**mangled))
-       {
-         string_appendn (s, *mangled, 1);
-         (*mangled)++;
-       }
-      if (**mangled == '.') /* fraction */
-       {
-         string_appendn (s, ".", 1);
-         (*mangled)++;
-         while (isdigit ((unsigned char)**mangled))
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-      if (**mangled == 'e') /* exponent */
-       {
-         string_appendn (s, "e", 1);
-         (*mangled)++;
-         while (isdigit ((unsigned char)**mangled))
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-    }
+    success = demangle_real_value (work, mangled, s);
   else if (tk == tk_pointer || tk == tk_reference)
     {
       if (**mangled == 'Q')
@@ -1623,11 +1670,9 @@ demangle_template (work, mangled, tname, trawname, is_type, remember)
            }
          else
            {
-             char buf[10];
-             sprintf(buf, "T%d", idx);
-             string_append (tname, buf);
+             string_append_template_idx (tname, idx);
              if (trawname)
-               string_append (trawname, buf);
+               string_append_template_idx (trawname, idx);
            }
        }
       else
@@ -2696,7 +2741,6 @@ demangle_qualified (work, mangled, result, isfuncname, append)
 {
   int qualifiers = 0;
   int success = 1;
-  const char *p;
   char num[2];
   string temp;
   string last_name;
@@ -2728,19 +2772,10 @@ demangle_qualified (work, mangled, result, isfuncname, append)
       /* GNU mangled name with more than 9 classes.  The count is preceded
         by an underscore (to distinguish it from the <= 9 case) and followed
         by an underscore.  */
-      p = *mangled + 2;
-      qualifiers = atoi (p);
-      if (!isdigit ((unsigned char)*p) || *p == '0')
-       success = 0;
-
-      /* Skip the digits.  */
-      while (isdigit ((unsigned char)*p))
-       ++p;
-
-      if (*p != '_')
+      (*mangled)++;
+      qualifiers = consume_count_with_underscores (mangled);
+      if (qualifiers == -1)
        success = 0;
-
-      *mangled = p + 1;
       break;
 
     case '1':
@@ -2931,9 +2966,7 @@ get_count (type, count)
   int n;
 
   if (!isdigit ((unsigned char)**type))
-    {
-      return (0);
-    }
+    return (0);
   else
     {
       *count = **type - '0';
@@ -3230,11 +3263,7 @@ do_type (work, mangled, result)
        if (work->tmpl_argvec)
          string_append (result, work->tmpl_argvec[idx]);
        else
-         {
-           char buf[10];
-           sprintf(buf, "T%d", idx);
-           string_append (result, buf);
-         }
+         string_append_template_idx (result, idx);
 
        success = 1;
       }
@@ -4353,6 +4382,16 @@ string_prependn (p, s, n)
     }
 }
 
+static void
+string_append_template_idx (s, idx)
+     string *s;
+     int idx;
+{
+  char buf[INTBUF_SIZE + 1 /* 'T' */];
+  sprintf(buf, "T%d", idx);
+  string_append (s, buf);
+}
+
 /* To generate a standalone demangler program for testing purposes,
    just compile and link this file with -DMAIN and libiberty.a.  When
    run, it demangles each command line arg, or each stdin string, and
index 0156d27..d3a1fe4 100644 (file)
@@ -2474,3 +2474,15 @@ C<Test, Test::output> call<Test>(Test &)
 --format=gnu
 fn__FPQ21n1cPMQ21n1cFPQ21n1c_i
 fn(n::c *, int (n::c::*)(n::c *))
+#
+--format=gnu
+f__FGt3Bar1i21i
+f(Bar<2>, i)
+#
+--format=gnu
+f__FGt3Bar1i_21_i
+f(Bar<21>, int)
+#
+--format=gnu
+f__FGt3Bar1i24XY_t
+f(Bar<2>, XY_t)