home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Atari / Gnu / gdb36p4s.zoo / cplusdem.c < prev    next >
C/C++ Source or Header  |  1993-05-25  |  30KB  |  1,495 lines

  1. /* Demangler for GNU C++ 
  2.    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
  3.    written by James Clark (jjc@jclark.uucp)
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* This is for g++ 1.36.1 (November 6 version). It will probably
  20.    require changes for any other version.
  21.  
  22.    Modified for g++ 1.36.2 (November 18 version).
  23.  
  24.    Modified for g++ 1.90.06 (December 31 version).
  25.  
  26.    Modified for g++ 1.95.03 (November 13 version).  */
  27.  
  28. /* This file exports one function
  29.  
  30.    char *cplus_demangle (const char *name, int ansi)
  31.  
  32.    If NAME is a mangled function name produced by GNU C++, then
  33.    a pointer to a malloced string giving a C++ representation
  34.    of the name will be returned; otherwise NULL will be returned.
  35.    It is the caller's responsibility to free the string which
  36.    is returned.
  37.  
  38.    If ANSI is non-zero, then ANSI qualifiers such as `const',
  39.    `void', and the ellipses operator `...' are output.  Otherwise
  40.    they are not.
  41.  
  42.    For example,
  43.    
  44.    cplus_demangle ("_foo__1Ai")
  45.    
  46.    returns
  47.  
  48.    "A::foo(int)"
  49.  
  50.    This file imports xmalloc and xrealloc, which are like malloc and
  51.    realloc except that they generate a fatal error if there is no
  52.    available memory. */
  53.  
  54. /* #define nounderscore 1 *//* define this is names don't start with _ */
  55.  
  56. #include <stdio.h>
  57. #include <ctype.h>
  58.  
  59. /* GDB-specific, FIXME.  */
  60. #include "defs.h"
  61.  
  62. #ifdef USG
  63. #include <memory.h>
  64. #include <string.h>
  65. #else
  66. #include <strings.h>
  67. #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
  68. #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
  69. #define strchr index 
  70. #define strrchr rindex
  71. #endif
  72.  
  73. /* This is '$' on systems where the assembler can deal with that.
  74.    Where the assembler can't, it's '.' (but on many systems '.' is
  75.    used for other things).  */
  76. #if !defined (CPLUS_MARKER)
  77. #define CPLUS_MARKER '$'
  78. #endif
  79.  
  80. #ifndef __STDC__
  81. #define const
  82. #endif
  83.  
  84. #ifdef __STDC__
  85. extern char *cplus_demangle (const char *type, int ansi);
  86. #else
  87. extern char *cplus_demangle ();
  88. #endif
  89.  
  90. #ifdef __STDC__
  91. extern char *xmalloc (int);
  92. extern char *xrealloc (char *, int);
  93. extern void free (char *);
  94. #else
  95. extern char *xmalloc ();
  96. extern char *xrealloc ();
  97. extern void free ();
  98. #endif
  99.  
  100. static char **typevec = 0;
  101. static int ntypes = 0;
  102. static int typevec_size = 0;
  103.  
  104. static struct {
  105.   const char *in;
  106.   const char *out;
  107. } optable[] = {
  108.   "nw", " new",            /* new (1.92, ansi) */
  109.   "dl", " delete",        /* new (1.92, ansi) */
  110.   "new", " new",        /* old (1.91) */
  111.   "delete", " delete",        /* old (1.91) */
  112.   "ne", "!=",            /* old, ansi */
  113.   "eq", "==",            /* old, ansi */
  114.   "ge", ">=",            /* old, ansi */
  115.   "gt", ">",            /* old, ansi */
  116.   "le", "<=",            /* old, ansi */
  117.   "lt", "<",            /* old, ansi */
  118.   "plus", "+",            /* old */
  119.   "pl", "+",            /* ansi */
  120.   "apl", "+=",            /* ansi */
  121.   "minus", "-",            /* old */
  122.   "mi", "-",            /* ansi */
  123.   "ami", "-=",            /* ansi */
  124.   "mult", "*",            /* old */
  125.   "ml", "*",            /* ansi */
  126.   "aml", "*=",            /* ansi */
  127.   "convert", "+",        /* old (unary +) */
  128.   "negate", "-",        /* old (unary -) */
  129.   "trunc_mod", "%",        /* old */
  130.   "md", "%",            /* ansi */
  131.   "amd", "%=",            /* ansi */
  132.   "trunc_div", "/",        /* old */
  133.   "dv", "/",            /* ansi */
  134.   "adv", "/=",            /* ansi */
  135.   "truth_andif", "&&",        /* old */
  136.   "aa", "&&",            /* ansi */
  137.   "truth_orif", "||",        /* old */
  138.   "oo", "||",            /* ansi */
  139.   "truth_not", "!",        /* old */
  140.   "nt", "!",            /* ansi */
  141.   "postincrement", "++",    /* old */
  142.   "pp", "++",            /* ansi */
  143.   "postdecrement", "--",    /* old */
  144.   "mm", "--",            /* ansi */
  145.   "bit_ior", "|",        /* old */
  146.   "or", "|",            /* ansi */
  147.   "aor", "|=",            /* ansi */
  148.   "bit_xor", "^",        /* old */
  149.   "er", "^",            /* ansi */
  150.   "aer", "^=",            /* ansi */
  151.   "bit_and", "&",        /* old */
  152.   "ad", "&",            /* ansi */
  153.   "aad", "&=",            /* ansi */
  154.   "bit_not", "~",        /* old */
  155.   "co", "~",            /* ansi */
  156.   "call", "()",            /* old */
  157.   "cl", "()",            /* ansi */
  158.   "alshift", "<<",        /* old */
  159.   "ls", "<<",            /* ansi */
  160.   "als", "<<=",            /* ansi */
  161.   "arshift", ">>",        /* old */
  162.   "rs", ">>",            /* ansi */
  163.   "ars", ">>=",            /* ansi */
  164.   "component", "->",        /* old */
  165.   "rf", "->",            /* ansi */
  166.   "indirect", "*",        /* old */
  167.   "method_call", "->()",    /* old */
  168.   "addr", "&",            /* old (unary &) */
  169.   "array", "[]",        /* old */
  170.   "vc", "[]",            /* ansi */
  171.   "compound", ",",        /* old */
  172.   "cm", ",",            /* ansi */
  173.   "nop", "",            /* old (for operator=) */
  174.   "as", "=",            /* ansi */
  175.   "cond", "?:",            /* old */
  176.   "cn", "?:",            /* psuedo-ansi */
  177.   "max", ">?",            /* old */
  178.   "mx", ">?",            /* psuedo-ansi */
  179.   "min", "<?",            /* old */
  180.   "mn", "<?",            /* psuedo-ansi */
  181.   "rm", "->*",            /* ansi */
  182. };
  183.  
  184. /* Beware: these aren't '\0' terminated. */
  185.  
  186. typedef struct {
  187.   char *b;            /* pointer to start of string */
  188.   char *p;            /* pointer after last character */
  189.   char *e;            /* pointer after end of allocated space */
  190. } string;
  191.  
  192. #ifdef __STDC__
  193. static void string_need (string *s, int n);
  194. static void string_delete (string *s);
  195. static void string_init (string *s);
  196. static void string_clear (string *s);
  197. static int string_empty (string *s);
  198. static void string_append (string *p, const char *s);
  199. static void string_appends (string *p, string *s);
  200. static void string_appendn (string *p, const char *s, int n);
  201. static void string_prepend (string *p, const char *s);
  202. static void string_prepends (string *p, string *s);
  203. static void string_prependn (string *p, const char *s, int n);
  204. static int get_count (const char **type, int *count);
  205. static int do_args (const char **type, string *decl);
  206. static int do_type (const char **type, string *result);
  207. static int do_arg (const char **type, string *result);
  208. static int do_args (const char **type, string *decl);
  209. static int do_cuv_prefix (const char **type, string *result, int *non_empty);
  210. static int do_builtin_type (const char **type, string *result, int *non_empty);
  211. static int do_template_args (const char **type, string *result);
  212. static void munge_function_name (string *name);
  213. static void remember_type (const char *type, int len);
  214. #else
  215. static void string_need ();
  216. static void string_delete ();
  217. static void string_init ();
  218. static void string_clear ();
  219. static int string_empty ();
  220. static void string_append ();
  221. static void string_appends ();
  222. static void string_appendn ();
  223. static void string_prepend ();
  224. static void string_prepends ();
  225. static void string_prependn ();
  226. static int get_count ();
  227. static int do_args ();
  228. static int do_type ();
  229. static int do_arg ();
  230. static int do_args ();
  231. static int do_cuv_prefix ();
  232. static int do_builtin_type ();
  233. static int do_template_args ();
  234. static void munge_function_name ();
  235. static void remember_type ();
  236. #endif
  237.  
  238. int
  239. get_simple_count (type, res)
  240.      char **type;
  241.      int *res;
  242. {
  243.   int n = 0, success = 1;;
  244.   
  245.   if (!isdigit (**type))
  246.     return 0;
  247.   do
  248.     {
  249.       n *= 10;
  250.       n += **type - '0';
  251.       *type += 1;
  252.     } 
  253.   while (isdigit (**type));
  254.   if (strlen (*type) < n)
  255.     {
  256.       success = 0;
  257.     }
  258.  
  259.   *res = n;
  260.   return success;
  261. }
  262.  
  263. static int print_ansi_qualifiers;
  264.  
  265. char *
  266. cplus_demangle (type, ansi)
  267.      const char *type;
  268.      int ansi;
  269. {
  270.   string decl;
  271.   int n;
  272.   int success = 0;
  273.   int constructor = 0;
  274.   int destructor = 0;
  275.   int static_type = 0;
  276.   int const_flag = 0;
  277.   int i;
  278.   const char *p;
  279. #ifndef LONGERNAMES
  280.   const char *premangle;
  281. #endif
  282.  
  283.   print_ansi_qualifiers = ansi;
  284.  
  285.   if (type == NULL || *type == '\0')
  286.     return NULL;
  287. #ifndef nounderscore
  288.   if (*type++ != '_')
  289.     return NULL;
  290. #endif
  291.   /* destructor */
  292.   if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
  293.     {
  294.       destructor = 1;
  295.       p = type;
  296.     }
  297.   /* virtual table "_vt$"  */
  298.   else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
  299.     {
  300.       type += 4;
  301.       string_init (&decl);
  302.       if (strchr (type, CPLUS_MARKER))
  303.     {
  304.       while (*type)
  305.         {
  306.           int len;
  307.           if (!get_simple_count (&type, &len)
  308.           || (type[len] && type[len] != CPLUS_MARKER))
  309.         {
  310.           string_delete (&decl);
  311.           return NULL;
  312.         }
  313.           string_appendn (&decl, type, len);
  314.           type += len;
  315.           if (*type)
  316.         {
  317.           string_append (&decl, "::");
  318.           type++;
  319.         }
  320.         }
  321.     }
  322.       else
  323.     string_append (&decl, type);
  324.       string_appendn (&decl, " virtual table", 15);
  325.       return decl.b;
  326.     }
  327.   /* static data member */
  328.   else if (type[0] == '_' && strchr ("0123456789Qt", type[1]) != NULL
  329.        && strchr (type, CPLUS_MARKER) != NULL)
  330.     {
  331.       static_type = 1;
  332.       p = type + 1;
  333.     }
  334.   else
  335.     {
  336.       p = type;
  337.       while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  338.     p++;
  339.       if (*p == '\0')
  340.     return NULL;
  341.     }
  342.  
  343.   string_init (&decl);
  344.  
  345.   if (static_type)
  346.     {
  347.       if (!isdigit (p[0]) && ('t' != p[0]) && p[0] != 'Q')
  348.     {
  349.       string_delete (&decl);
  350.       return NULL;
  351.     }
  352.     }
  353.   else if (destructor)
  354.     {
  355.       if (!isdigit (p[3])&& ('t' != p[3]) && p[3] != 'Q')
  356.     {
  357.       string_delete (&decl);
  358.       return NULL;
  359.     }
  360.       p += 3;
  361.     }
  362.   else if (p == type)
  363.     {
  364.       if (!isdigit (p[2]) && ('t' != p[2]) && p[2] != 'Q')
  365.     {
  366.       p += 1;
  367.       while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  368.         p++;
  369.       string_appendn (&decl, type, p - type);      
  370.       string_appendn (&decl, "", 1);
  371.       munge_function_name (&decl);
  372.       if (decl.b[0] == '_')
  373.         decl.p--;
  374.       p += 2;
  375.     }
  376.       else
  377.     {
  378.       constructor = 1;
  379.       p += 2;
  380.     }
  381.     }
  382.   else
  383.     {
  384.       string_appendn (&decl, type, p - type);
  385.       decl.p[0] = '\0';
  386.       munge_function_name (&decl);
  387.       p += 2;
  388.     }
  389.  
  390. #ifndef LONGERNAMES
  391.   premangle = p;
  392. #endif
  393.   switch (*p)
  394.     {
  395.     case 'C':
  396.       /* a const member function */
  397.       p += 1;
  398.       const_flag = 1;
  399.       if (*p == 't')
  400.     goto template;
  401.       if (*p == 'Q')
  402.     goto qualified;
  403.       if (!isdigit (*p))
  404.     {
  405.       string_delete (&decl);
  406.       return NULL;
  407.     }
  408.       /* fall through */
  409.     case '0':
  410.     case '1':
  411.     case '2':
  412.     case '3':
  413.     case '4':
  414.     case '5':
  415.     case '6':
  416.     case '7':
  417.     case '8':
  418.     case '9':
  419.       n = 0;
  420.       do
  421.     {
  422.       n *= 10;
  423.       n += *p - '0';
  424.       p += 1;
  425.     }
  426.       while (isdigit (*p));
  427.       if (strlen (p) < n)
  428.     {
  429.       string_delete (&decl);
  430.       return NULL;
  431.     }
  432.       if (constructor || destructor)
  433.     {
  434.       string_appendn (&decl, p, n);
  435.       string_append (&decl, "::");
  436.       if (destructor)
  437.         string_append(&decl, "~");
  438.       string_appendn (&decl, p, n);
  439.     }
  440.       else
  441.     {
  442.       string_prepend (&decl, "::");
  443.       string_prependn (&decl, p, n);
  444.     }
  445.       p += n;
  446.     do_rest:
  447. #ifndef LONGERNAMES
  448.       remember_type (premangle, p - premangle);
  449. #endif
  450.       if (static_type)
  451.     {
  452.       string_append(&decl, p+1);
  453.       p += strlen(p);
  454.       success = 1;
  455.     }
  456.       else
  457.     success = do_args (&p, &decl);
  458.       if (const_flag)
  459.     string_append (&decl, " const");
  460.       break;
  461.     case 'F':
  462.       p += 1;
  463.       success = do_args (&p, &decl);
  464.       break;
  465.     /* template additions */
  466.     case 't':
  467.     template:
  468.       p += 1;
  469.       {
  470.     int r;
  471.     string tname;
  472.     string trawname;
  473.     
  474.     string_init(&tname);
  475.     string_init(&trawname);
  476.  
  477.     /* get template name */
  478.     if (!get_simple_count (&p, &r))
  479.       {
  480.         success = 0;
  481.         break;
  482.       }
  483.     string_appendn (&tname, p, r);
  484.     string_appendn (&trawname, p, r);
  485.     p += r;
  486.     string_append (&tname, "<");
  487.     success = do_template_args (&p, &tname);
  488.     if (!success)
  489.       {
  490.         string_delete (&tname);
  491.         string_delete (&trawname);
  492.         break;
  493.       }
  494.     if (tname.p[-1] == '>')
  495.       string_append (&tname, " ");
  496.     string_append (&tname, ">::");
  497.     if (destructor)
  498.       string_append(&tname, "~");
  499.     if (constructor || destructor)
  500.       string_appends (&tname, &trawname);
  501.     string_delete(&trawname);
  502.  
  503.     if (!success) {
  504.       string_delete(&tname);
  505.       return 0;
  506.     }
  507.     string_prepends (&decl, &tname);
  508.     string_delete (&tname);
  509.       }
  510.       goto do_rest;
  511.     case 'Q':
  512.     qualified:
  513.       {
  514.     int name_length;
  515.     string temp;
  516.  
  517.     n = p[1] - '0';
  518.     if (n < 0 || n > 9)
  519.       {
  520.         success = 0;
  521.         break;
  522.       }
  523.     p += 2;
  524.     string_init (&temp);
  525.     while (n-- > 0)
  526.       {
  527.         if (!get_simple_count (&p, &name_length))
  528.           {
  529.         string_delete (&temp);
  530.         string_delete (&decl);
  531.         return NULL;
  532.           }
  533.         string_appendn (&temp, p, name_length);
  534.         if (n > 0)
  535.           string_append (&temp, "::");
  536.         p += name_length;
  537.       }
  538.     if (constructor || destructor)
  539.       {
  540.         string_appends (&decl, &temp);
  541.         string_append (&decl, "::");
  542.         if (destructor)
  543.           string_append (&decl, "~");
  544.         string_appendn (&decl, p - name_length, name_length);
  545.       }
  546.     else
  547.       {
  548.         string_prepend (&decl, "::");
  549.         string_prepends (&decl, &temp);
  550.       }
  551.     string_delete (&temp);
  552.       }
  553.       goto do_rest;
  554.     }
  555.  
  556.   for (i = 0; i < ntypes; i++)
  557.     if (typevec[i] != NULL)
  558.       free (typevec[i]);
  559.   ntypes = 0;
  560.   if (typevec != NULL)
  561.     {
  562.       free ((char *)typevec);
  563.       typevec = NULL;
  564.       typevec_size = 0;
  565.     }
  566.  
  567.   if (success)
  568.     {
  569.       string_appendn (&decl, "", 1);
  570.       return decl.b;
  571.     }
  572.   else
  573.     {
  574.       string_delete (&decl);
  575.       return NULL;
  576.     }
  577. }
  578.  
  579. static int
  580. get_count (type, count)
  581.      const char **type;
  582.      int *count;
  583. {
  584.   if (!isdigit (**type))
  585.     return 0;
  586.   *count = **type - '0';
  587.   *type += 1;
  588.   /* see flush_repeats in cp-method.c */
  589.   if (isdigit (**type))
  590.     {
  591.       const char *p = *type;
  592.       int n = *count;
  593.       do 
  594.     {
  595.       n *= 10;
  596.       n += *p - '0';
  597.       p += 1;
  598.     } 
  599.       while (isdigit (*p));
  600.       if (*p == '_')
  601.     {
  602.       *type = p + 1;
  603.       *count = n;
  604.     }
  605.     }
  606.   return 1;
  607. }
  608.  
  609. /* result will be initialised here; it will be freed on failure */
  610.  
  611. static int
  612. do_type (type, result)
  613.      const char **type;
  614.      string *result;
  615. {
  616.   int n;
  617.   int done;
  618.   int non_empty = 0;
  619.   int success;
  620.   string decl;
  621.   const char *remembered_type;
  622.  
  623.   string_init (&decl);
  624.   string_init (result);
  625.  
  626.   done = 0;
  627.   success = 1;
  628.   while (success && !done)
  629.     {
  630.       int member;
  631.       switch (**type)
  632.     {
  633.     case 'P':
  634.       *type += 1;
  635.       string_prepend (&decl, "*");
  636.       break;
  637.  
  638.     case 'R':
  639.       *type += 1;
  640.       string_prepend (&decl, "&");
  641.       break;
  642.  
  643.     case 'T':
  644.       *type += 1;
  645.       if (!get_count (type, &n) || n >= ntypes)
  646.         success = 0;
  647.       else
  648.         {
  649.           remembered_type = typevec[n];
  650.           type = &remembered_type;
  651.         }
  652.       break;
  653.  
  654.     case 'F':
  655.       *type += 1;
  656.       if (!string_empty (&decl) && decl.b[0] == '*')
  657.         {
  658.           string_prepend (&decl, "(");
  659.           string_append (&decl, ")");
  660.         }
  661.       if (!do_args (type, &decl) || **type != '_')
  662.         success = 0;
  663.       else
  664.         *type += 1;
  665.       break;
  666.  
  667.     case 'M':
  668.     case 'O':
  669.       {
  670.         int constp = 0;
  671.         int volatilep = 0;
  672.  
  673.         member = **type == 'M';
  674.         *type += 1;
  675.         if (!get_simple_count (type, &n))
  676.           {
  677.         success = 0;
  678.         break;
  679.           }
  680.         string_append (&decl, ")");
  681.         string_prepend (&decl, "::");
  682.         string_prependn (&decl, *type, n);
  683.         string_prepend (&decl, "(");
  684.         *type += n;
  685.         if (member)
  686.           {
  687.         if (**type == 'C')
  688.           {
  689.             *type += 1;
  690.             constp = 1;
  691.           }
  692.         if (**type == 'V')
  693.           {
  694.             *type += 1;
  695.             volatilep = 1;
  696.           }
  697.         if (*(*type)++ != 'F')
  698.           {
  699.             success = 0;
  700.             break;
  701.           }
  702.           }
  703.         if ((member && !do_args (type, &decl)) || **type != '_')
  704.           {
  705.         success = 0;
  706.         break;
  707.           }
  708.         *type += 1;
  709.         if (! print_ansi_qualifiers)
  710.           break;
  711.         if (constp)
  712.           {
  713.         if (non_empty)
  714.           string_append (&decl, " ");
  715.         else
  716.           non_empty = 1;
  717.         string_append (&decl, "const");
  718.           }
  719.         if (volatilep)
  720.           {
  721.         if (non_empty)
  722.           string_append (&decl, " ");
  723.         else
  724.           non_empty = 1;
  725.         string_append (&decl, "volatile");
  726.           }
  727.         break;
  728.       }
  729.  
  730.     case 'C':
  731.       if ((*type)[1] == 'P')
  732.         {
  733.           *type += 1;
  734.           if (print_ansi_qualifiers)
  735.         {
  736.           if (!string_empty (&decl))
  737.             string_prepend (&decl, " ");
  738.           string_prepend (&decl, "const");
  739.         }
  740.           break;
  741.         }
  742.  
  743.       /* fall through */
  744.     default:
  745.       done = 1;
  746.       break;
  747.     }
  748.     }
  749.  
  750.   non_empty = 0;
  751.   if (success)
  752.     success = do_cuv_prefix (type, result, &non_empty);
  753.  
  754.   if (success)
  755.     success = do_builtin_type(type, result, &non_empty);
  756.   
  757.   if (success)
  758.     {
  759.       if (!string_empty (&decl))
  760.     {
  761.       string_append (result, " ");
  762.       string_appends (result, &decl);
  763.     }
  764.       string_delete (&decl);
  765.       return 1;
  766.     }
  767.   else
  768.     {
  769.       string_delete (&decl);
  770.       string_delete (result);
  771.       return 0;
  772.     }
  773. }
  774.  
  775. static int
  776. do_cuv_prefix (type, result, non_empty)
  777.      const char **type;
  778.      string* result;
  779.      int* non_empty;
  780. {
  781.   int success = 1;
  782.   int done = 0;
  783.   
  784.   while (success && !done)
  785.     {
  786.       switch (**type)
  787.     {
  788.     case 'C':
  789.       *type += 1;
  790.       if (print_ansi_qualifiers)
  791.         {
  792.           if (*non_empty)
  793.         string_append (result, " ");
  794.           else
  795.         *non_empty = 1;
  796.           string_append (result, "const");
  797.         }
  798.       break;
  799.     case 'U':
  800.       *type += 1;
  801.       if (*non_empty)
  802.         string_append (result, " ");
  803.       else
  804.         *non_empty = 1;
  805.       string_append (result, "unsigned");
  806.       break;
  807.     case 'S':
  808.       *type += 1;
  809.       if (*non_empty)
  810.         string_append (result, " ");
  811.       else
  812.         *non_empty = 1;
  813.       string_append (result, "signed");
  814.       break;
  815.     case 'V':
  816.       *type += 1;
  817.       if (print_ansi_qualifiers)
  818.         {
  819.           if (*non_empty)
  820.         string_append (result, " ");
  821.           else
  822.         *non_empty = 1;
  823.           string_append (result, "volatile");
  824.         }
  825.       break;
  826.     default:
  827.       done = 1;
  828.       break;
  829.     }
  830.     }
  831.   return success;
  832. }
  833.  
  834. static int
  835. do_builtin_type (type, result, non_empty)
  836.      const char **type;
  837.      string* result;
  838.      int *non_empty;
  839. {
  840.   int success = 1;
  841.   int n;
  842.   
  843.   switch (**type)
  844.     {
  845.     case '\0':
  846.     case '_':
  847.       break;
  848.     case 'v':
  849.       *type += 1;
  850.       if (*non_empty)
  851.     string_append (result, " ");
  852.       string_append (result, "void");
  853.       break;
  854.     case 'x':
  855.       *type += 1;
  856.       if (*non_empty)
  857.     string_append (result, " ");
  858.       string_append (result, "long long");
  859.       break;
  860.     case 'l':
  861.       *type += 1;
  862.       if (*non_empty)
  863.     string_append (result, " ");
  864.       string_append (result, "long");
  865.       break;
  866.     case 'i':
  867.       *type += 1;
  868.       if (*non_empty)
  869.     string_append (result, " ");
  870.       string_append (result, "int");
  871.       break;
  872.     case 's':
  873.       *type += 1;
  874.       if (*non_empty)
  875.     string_append (result, " ");
  876.       string_append (result, "short");
  877.       break;
  878.     case 'c':
  879.       *type += 1;
  880.       if (*non_empty)
  881.     string_append (result, " ");
  882.       string_append (result, "char");
  883.       break;
  884.     case 'w':
  885.       *type += 1;
  886.       if (*non_empty)
  887.     string_append (result, " ");
  888.       string_append (result, "wchar_t");
  889.       break;
  890.     case 'r':
  891.       *type += 1;
  892.       if (*non_empty)
  893.     string_append (result, " ");
  894.       string_append (result, "long double");
  895.       break;
  896.     case 'd':
  897.       *type += 1;
  898.       if (*non_empty)
  899.     string_append (result, " ");
  900.       string_append (result, "double");
  901.       break;
  902.     case 'f':
  903.       *type += 1;
  904.       if (*non_empty)
  905.     string_append (result, " ");
  906.       string_append (result, "float");
  907.       break;
  908.     case 'G':
  909.       *type += 1;
  910.       if (!isdigit (**type))
  911.     {
  912.       success = 0;
  913.       break;
  914.     }
  915.       /* fall through */
  916.     case '0':
  917.     case '1':
  918.     case '2':
  919.     case '3':
  920.     case '4':
  921.     case '5':
  922.     case '6':
  923.     case '7':
  924.     case '8':
  925.     case '9':
  926.       n = 0;
  927.       do
  928.     {
  929.       n *= 10;
  930.       n += **type - '0';
  931.       *type += 1;
  932.     }
  933.       while (isdigit (**type));
  934.       if (strlen (*type) < n)
  935.     {
  936.       success = 0;
  937.       break;
  938.     }
  939.       if (*non_empty)
  940.     string_append (result, " ");
  941.       string_appendn (result, *type, n);
  942.       *type += n;
  943.       break;
  944.     case 't':
  945.       *type += 1;
  946.       /* get template name */
  947.       if (!get_simple_count (type, &n))
  948.     {
  949.       success = 0;
  950.       break;
  951.     }
  952.       if (*non_empty)
  953.     string_append (result, " ");
  954.       string_appendn (result, *type, n);
  955.       *type += n;
  956.       string_append (result, "<");
  957.       if (!do_template_args (type, result))
  958.     success = 0;
  959.       else
  960.     {
  961.       if (result->p[-1] == '>')
  962.         string_append (result, " ");
  963.       string_append (result, ">");
  964.     }
  965.       break;
  966.     case 'Q':
  967.       n = (*type)[1] - '0';
  968.       if (n < 1 || n > 9)
  969.     {
  970.       success = 0;
  971.       break;
  972.     }
  973.       *type += 2;
  974.       if (*non_empty)
  975.     string_append (result, " ");
  976.       while (n-- > 0)
  977.     {
  978.       int len;
  979.       if (!get_simple_count (type, &len))
  980.         {
  981.           success = 0;
  982.           break;
  983.         }
  984.       string_appendn (result, *type, len);
  985.       if (n > 0)
  986.         string_append (result, "::");
  987.       (*type) += len;
  988.     }
  989.       break;
  990.       
  991.     default:
  992.       success = 0;
  993.       break;
  994.     }
  995.   return success;
  996. }
  997.  
  998. static int
  999. do_template_args (type, result)
  1000.      const char **type;
  1001.      string *result;
  1002. {
  1003.   int r, i;
  1004.  
  1005.   string temp;
  1006.   int need_comma = 0;
  1007.   int success;
  1008.  
  1009.   /* get size of template parameter list */
  1010.   if (!get_count (type, &r))
  1011.     return 0;
  1012.   success = 1;
  1013.   for (i = 0; i < r; i++)
  1014.     {
  1015.       if (need_comma)
  1016.     string_append (result, ", ");
  1017.       /* Z for type parameters */
  1018.       if (**type == 'Z')
  1019.     {
  1020.       *type += 1;
  1021.  
  1022.       success = do_arg (type, &temp);
  1023.       if (success)
  1024.         string_appends (result, &temp);
  1025.       string_delete(&temp);
  1026.       if (!success)
  1027.         break;
  1028.     }
  1029.       /* otherwise, value parameter */
  1030.       else
  1031.     {
  1032.       const char *old_p  = *type;
  1033.       int is_pointer = 0;
  1034.       int is_real = 0;
  1035.       int is_integral = 0;
  1036.       int done = 0;
  1037.  
  1038.       success = do_arg (type, &temp);
  1039.       if (success)
  1040.         string_appends (result, &temp);
  1041.       string_delete(&temp);
  1042.       if (!success)
  1043.         break;
  1044.       string_append (result, "=");
  1045.       while (*old_p && !done)
  1046.         {    
  1047.           switch (*old_p)
  1048.         {
  1049.         case 'P':
  1050.         case 'R':
  1051.           done = is_pointer = 1;
  1052.           break;
  1053.         case 'C':    /* const */
  1054.         case 'S':    /* explicitly signed [char] */
  1055.         case 'U':    /* unsigned */
  1056.         case 'V':    /* volatile */
  1057.         case 'F':    /* function */
  1058.         case 'M':    /* member function */
  1059.         case 'O':    /* ??? */
  1060.           old_p++;
  1061.           continue;
  1062.         case 'Q':    /* repetition of following */
  1063.         case 'T':    /* remembered type */
  1064.         case 'v':    /* void */
  1065.           return 0;
  1066.         case 'x':    /* long long */
  1067.         case 'l':    /* long */
  1068.         case 'i':    /* int */
  1069.         case 's':    /* short */
  1070.         case 'c':    /* char */
  1071.         case 'w':    /* wchar_t */
  1072.           done = is_integral = 1;
  1073.           break;
  1074.         case 'r':    /* long double */
  1075.         case 'd':    /* double */
  1076.         case 'f':    /* float */
  1077.           done = is_real = 1;
  1078.           break;
  1079.         default:
  1080.           return 0;
  1081.         }
  1082.         }
  1083.       if (is_integral)
  1084.         {
  1085.           if (**type == 'm')
  1086.         {
  1087.           string_appendn (result, "-", 1);
  1088.           (*type)++;
  1089.         }
  1090.           while (isdigit (**type))    
  1091.         {
  1092.           string_appendn (result, *type, 1);
  1093.           (*type)++;
  1094.         }
  1095.         }
  1096.       else if (is_real)
  1097.         {
  1098.           if (**type == 'm')
  1099.         {
  1100.           string_appendn (result, "-", 1);
  1101.           (*type)++;
  1102.         }
  1103.           while (isdigit (**type))    
  1104.         {
  1105.           string_appendn (result, *type, 1);
  1106.           (*type)++;
  1107.         }
  1108.           if (**type == '.')    /* fraction */
  1109.         {
  1110.           string_appendn (result, ".", 1);
  1111.           (*type)++;
  1112.           while (isdigit (**type))    
  1113.             {
  1114.               string_appendn (result, *type, 1);
  1115.               (*type)++;
  1116.             }
  1117.         }
  1118.           if (**type == 'e')    /* exponent */
  1119.         {
  1120.           string_appendn (result, "e", 1);
  1121.           (*type)++;
  1122.           while (isdigit (**type))    
  1123.             {
  1124.               string_appendn (result, *type, 1);
  1125.               (*type)++;
  1126.             }
  1127.         }
  1128.         }
  1129.       else if (is_pointer)
  1130.         {
  1131.           int symbol_len;
  1132.  
  1133.           if (!get_count (type, &symbol_len))
  1134.         {
  1135.           success = 0;
  1136.           break;
  1137.         }
  1138.           string_appendn (result, *type, symbol_len);
  1139.           *type += symbol_len;
  1140.         }
  1141.     }
  1142.       need_comma = 1;
  1143.     }
  1144.   return success;
  1145. }
  1146.  
  1147. /* `result' will be initialised in do_type; it will be freed on failure */
  1148.  
  1149. static int
  1150. do_arg (type, result)
  1151.      const char **type;
  1152.      string *result;
  1153. {
  1154.   const char *start = *type;
  1155.  
  1156.   if (!do_type (type, result))
  1157.     return 0;
  1158.   remember_type (start, *type - start);
  1159.   return 1;
  1160. }
  1161.  
  1162. static void
  1163. remember_type (start, len)
  1164.      const char *start;
  1165.      int len;
  1166. {
  1167.   char *tem;
  1168.  
  1169.   if (ntypes >= typevec_size)
  1170.     {
  1171.       if (typevec_size == 0)
  1172.     {
  1173.       typevec_size = 3;
  1174.       typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
  1175.     }
  1176.       else
  1177.     {
  1178.       typevec_size *= 2;
  1179.       typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
  1180.     }
  1181.     }
  1182.   tem = (char *) xmalloc (len + 1);
  1183.   memcpy (tem, start, len);
  1184.   tem[len] = '\0';
  1185.   typevec[ntypes++] = tem;
  1186. }
  1187.  
  1188. /* `decl' must be already initialised, usually non-empty;
  1189.    it won't be freed on failure */
  1190.  
  1191. static int
  1192. do_args (type, decl)
  1193.      const char **type;
  1194.      string *decl;
  1195. {
  1196.   string arg;
  1197.   int need_comma = 0;
  1198.  
  1199.   string_append (decl, "(");
  1200.  
  1201.   while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
  1202.     {
  1203.       if (**type == 'N')
  1204.     {
  1205.       int r;
  1206.       int t;
  1207.       *type += 1;
  1208.       if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
  1209.         return 0;
  1210.       while (--r >= 0)
  1211.         {
  1212.           const char *tem = typevec[t];
  1213.           if (need_comma)
  1214.         string_append (decl, ", ");
  1215.           if (!do_arg (&tem, &arg))
  1216.         return 0;
  1217.           string_appends (decl, &arg);
  1218.           string_delete (&arg);
  1219.           need_comma = 1;
  1220.         }
  1221.     }
  1222.       else
  1223.     {
  1224.       if (need_comma)
  1225.         string_append (decl, ", ");
  1226.       if (!do_arg (type, &arg))
  1227.         return 0;
  1228.       string_appends (decl, &arg);
  1229.       string_delete (&arg);
  1230.       need_comma = 1;
  1231.     }
  1232.     }
  1233.  
  1234.   if (**type == 'v')
  1235.     *type += 1;
  1236.   else if (**type == 'e')
  1237.     {
  1238.       *type += 1;
  1239.       if (need_comma)
  1240.     string_append (decl, ",");
  1241.       string_append (decl, "...");
  1242.     }
  1243.  
  1244.   string_append (decl, ")");
  1245.   return 1;
  1246. }
  1247.  
  1248. static void
  1249. munge_function_name (name)
  1250.      string *name;
  1251. {
  1252.   if (string_empty (name))
  1253.     return;
  1254.  
  1255.   if (name->p - name->b >= 3 
  1256.       && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
  1257.     {
  1258.       int i;
  1259.       /* see if it's an assignment expression */
  1260.       if (name->p - name->b >= 10 /* op$assign_ */
  1261.       && memcmp (name->b + 3, "assign_", 7) == 0)
  1262.     {
  1263.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1264.         {
  1265.           int len = name->p - name->b - 10;
  1266.           if (strlen (optable[i].in) == len
  1267.           && memcmp (optable[i].in, name->b + 10, len) == 0)
  1268.         {
  1269.           string_clear (name);
  1270.           string_append (name, "operator");
  1271.           string_append (name, optable[i].out);
  1272.           string_append (name, "=");
  1273.           return;
  1274.         }
  1275.         }
  1276.     }
  1277.       else
  1278.     {
  1279.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1280.         {
  1281.           int len = name->p - name->b - 3;
  1282.           if (strlen (optable[i].in) == len 
  1283.           && memcmp (optable[i].in, name->b + 3, len) == 0)
  1284.         {
  1285.           string_clear (name);
  1286.           string_append (name, "operator");
  1287.           string_append (name, optable[i].out);
  1288.           return;
  1289.         }
  1290.         }
  1291.     }
  1292.       return;
  1293.     }
  1294.   else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
  1295.     {
  1296.       /* type conversion operator */
  1297.       string type;
  1298.       const char *tem = name->b + 5;
  1299.       if (do_type (&tem, &type))
  1300.     {
  1301.       string_clear (name);
  1302.       string_append (name, "operator ");
  1303.       string_appends (name, &type);
  1304.       string_delete (&type);
  1305.       return;
  1306.     }
  1307.     }
  1308.   /* ANSI.  */
  1309.   else if (name->b[2] == 'o' && name->b[3] == 'p')
  1310.     {
  1311.       /* type conversion operator.  */
  1312.       string type;
  1313.       const char *tem = name->b + 4;
  1314.       if (do_type (&tem, &type))
  1315.     {
  1316.       string_clear (name);
  1317.       string_append (name, "operator ");
  1318.       string_appends (name, &type);
  1319.       string_delete (&type);
  1320.       return;
  1321.     }
  1322.     }
  1323.   else if (name->b[2] >= 'a' && name->b[2] <= 'z'
  1324.        && name->b[3] >= 'a' && name->b[3] <= 'z')
  1325.     {
  1326.       int i;
  1327.  
  1328.       if (name->b[4] == '\0')
  1329.     {
  1330.       /* Operator.  */
  1331.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1332.         {
  1333.           if (strlen (optable[i].in) == 2
  1334.           && memcmp (optable[i].in, name->b + 2, 2) == 0)
  1335.         {
  1336.           string_clear (name);
  1337.           string_append (name, "operator");
  1338.           string_append (name, optable[i].out);
  1339.           return;
  1340.         }
  1341.         }
  1342.     }
  1343.       else
  1344.     {
  1345.       if (name->b[2] != 'a' || name->b[5] != '\0')
  1346.         return;
  1347.       /* Assignment.  */
  1348.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1349.         {
  1350.           if (strlen (optable[i].in) == 3
  1351.           && memcmp (optable[i].in, name->b + 2, 3) == 0)
  1352.         {
  1353.           string_clear (name);
  1354.           string_append (name, "operator");
  1355.           string_append (name, optable[i].out);
  1356.           return;
  1357.         }
  1358.         }
  1359.     }
  1360.     }
  1361. }
  1362.  
  1363. /* a mini string-handling package */
  1364.  
  1365. static void
  1366. string_need (s, n)
  1367.      string *s;
  1368.      int n;
  1369. {
  1370.   if (s->b == NULL)
  1371.     {
  1372.       if (n < 32)
  1373.     n = 32;
  1374.       s->p = s->b = (char *) xmalloc (n);
  1375.       s->e = s->b + n;
  1376.     }
  1377.   else if (s->e - s->p < n)
  1378.     {
  1379.       int tem = s->p - s->b;
  1380.       n += tem;
  1381.       n *= 2;
  1382.       s->b = (char *) xrealloc (s->b, n);
  1383.       s->p = s->b + tem;
  1384.       s->e = s->b + n;
  1385.     }
  1386. }
  1387.  
  1388. static void
  1389. string_delete (s)
  1390.      string *s;
  1391. {
  1392.   if (s->b != NULL)
  1393.     {
  1394.       free (s->b);
  1395.       s->b = s->e = s->p = NULL;
  1396.     }
  1397. }
  1398.  
  1399. static void
  1400. string_init (s)
  1401.      string *s;
  1402. {
  1403.   s->b = s->p = s->e = NULL;
  1404. }
  1405.  
  1406. static void 
  1407. string_clear (s)
  1408.      string *s;
  1409. {
  1410.   s->p = s->b;
  1411. }
  1412.  
  1413. static int
  1414. string_empty (s)
  1415.      string *s;
  1416. {
  1417.   return s->b == s->p;
  1418. }
  1419.  
  1420. static void
  1421. string_append (p, s)
  1422.      string *p;
  1423.      const char *s;
  1424. {
  1425.   int n;
  1426.   if (s == NULL || *s == '\0')
  1427.     return;
  1428.   n = strlen (s);
  1429.   string_need (p, n);
  1430.   memcpy (p->p, s, n);
  1431.   p->p += n;
  1432. }
  1433.  
  1434. static void
  1435. string_appends (p, s)
  1436.      string *p, *s;
  1437. {
  1438.   int n;
  1439.   if (s->b == s->p)
  1440.     return;
  1441.   n = s->p - s->b;
  1442.   string_need (p, n);
  1443.   memcpy (p->p, s->b, n);
  1444.   p->p += n;
  1445. }
  1446.  
  1447. static void
  1448. string_appendn (p, s, n)
  1449.      string *p;
  1450.      const char *s;
  1451.      int n;
  1452. {
  1453.   if (n == 0)
  1454.     return;
  1455.   string_need (p, n);
  1456.   memcpy (p->p, s, n);
  1457.   p->p += n;
  1458. }
  1459.  
  1460. static void
  1461. string_prepend (p, s)
  1462.      string *p;
  1463.      const char *s;
  1464. {
  1465.   if (s == NULL || *s == '\0')
  1466.     return;
  1467.   string_prependn (p, s, strlen (s));
  1468. }
  1469.  
  1470. static void
  1471. string_prepends (p, s)
  1472.      string *p, *s;
  1473. {
  1474.   if (s->b == s->p)
  1475.     return;
  1476.   string_prependn (p, s->b, s->p - s->b);
  1477. }
  1478.  
  1479. static void
  1480. string_prependn (p, s, n)
  1481.      string *p;
  1482.      const char *s;
  1483.      int n;
  1484. {
  1485.   char *q;
  1486.  
  1487.   if (n == 0)
  1488.     return;
  1489.   string_need (p, n);
  1490.   for (q = p->p - 1; q >= p->b; q--)
  1491.     q[n] = q[0];
  1492.   memcpy (p->b, s, n);
  1493.   p->p += n;
  1494. }
  1495.