home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / cp-dem.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  27KB  |  1,353 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)
  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.    For example,
  39.    
  40.    cplus_demangle ("_foo__1Ai")
  41.    
  42.    returns
  43.  
  44.    "A::foo(int)"
  45.  
  46.    This file imports xmalloc and xrealloc, which are like malloc and
  47.    realloc except that they generate a fatal error if there is no
  48.    available memory. */
  49.  
  50. /* #define nounderscore 1 /* define this is names don't start with _ */
  51.  
  52. #include <stdio.h>
  53. #include <ctype.h>
  54.  
  55. #ifdef USG
  56. #include <memory.h>
  57. #else
  58. #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
  59. #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
  60. #endif
  61.  
  62. /* This is '$' on systems where the assembler can deal with that.
  63.    Where the assembler can't, it's '.' (but on many systems '.' is
  64.    used for other things).  */
  65. #if !defined (CPLUS_MARKER)
  66. #define CPLUS_MARKER '$'
  67. #endif
  68.  
  69. #ifndef __STDC__
  70. #define const
  71. #endif
  72.  
  73. #ifdef __STDC__
  74. extern char *cplus_demangle (const char *type);
  75. #else
  76. extern char *cplus_demangle ();
  77. #endif
  78.  
  79. #ifdef __STDC__
  80. extern char *xmalloc (int);
  81. extern char *xrealloc (char *, int);
  82. extern void free (char *);
  83. #else
  84. extern char *xmalloc ();
  85. extern char *xrealloc ();
  86. extern void free ();
  87. #endif
  88.  
  89. static char **typevec = 0;
  90. static int ntypes = 0;
  91. static int typevec_size = 0;
  92.  
  93. static struct {
  94.   const char *in;
  95.   const char *out;
  96. } optable[] = {
  97.   "nw", " new",            /* new (1.92, ansi) */
  98.   "dl", " delete",        /* new (1.92, ansi) */
  99.   "new", " new",        /* old (1.91) */
  100.   "delete", " delete",        /* old (1.91) */
  101.   "ne", "!=",            /* old, ansi */
  102.   "eq", "==",            /* old, ansi */
  103.   "ge", ">=",            /* old, ansi */
  104.   "gt", ">",            /* old, ansi */
  105.   "le", "<=",            /* old, ansi */
  106.   "lt", "<",            /* old, ansi */
  107.   "plus", "+",            /* old */
  108.   "pl", "+",            /* ansi */
  109.   "apl", "+=",            /* ansi */
  110.   "minus", "-",            /* old */
  111.   "mi", "-",            /* ansi */
  112.   "ami", "-=",            /* ansi */
  113.   "mult", "*",            /* old */
  114.   "ml", "*",            /* ansi */
  115.   "aml", "*=",            /* ansi */
  116.   "convert", "+",        /* old (unary +) */
  117.   "negate", "-",        /* old (unary -) */
  118.   "trunc_mod", "%",        /* old */
  119.   "md", "%",            /* ansi */
  120.   "amd", "%=",            /* ansi */
  121.   "trunc_div", "/",        /* old */
  122.   "dv", "/",            /* ansi */
  123.   "adv", "/=",            /* ansi */
  124.   "truth_andif", "&&",        /* old */
  125.   "aa", "&&",            /* ansi */
  126.   "truth_orif", "||",        /* old */
  127.   "oo", "||",            /* ansi */
  128.   "truth_not", "!",        /* old */
  129.   "nt", "!",            /* ansi */
  130.   "postincrement", "++",    /* old */
  131.   "pp", "++",            /* ansi */
  132.   "postdecrement", "--",    /* old */
  133.   "mm", "--",            /* ansi */
  134.   "bit_ior", "|",        /* old */
  135.   "or", "|",            /* ansi */
  136.   "aor", "|=",            /* ansi */
  137.   "bit_xor", "^",        /* old */
  138.   "er", "^",            /* ansi */
  139.   "aer", "^=",            /* ansi */
  140.   "bit_and", "&",        /* old */
  141.   "ad", "&",            /* ansi */
  142.   "aad", "&=",            /* ansi */
  143.   "bit_not", "~",        /* old */
  144.   "co", "~",            /* ansi */
  145.   "call", "()",            /* old */
  146.   "cl", "()",            /* ansi */
  147.   "cond", "?:",            /* old */
  148.   "alshift", "<<",        /* old */
  149.   "ls", "<<",            /* ansi */
  150.   "als", "<<=",            /* ansi */
  151.   "arshift", ">>",        /* old */
  152.   "rs", ">>",            /* ansi */
  153.   "ars", ">>=",            /* ansi */
  154.   "component", "->",        /* old */
  155.   "rf", "->",            /* ansi */
  156.   "indirect", "*",        /* old */
  157.   "method_call", "->()",    /* old */
  158.   "addr", "&",            /* old (unary &) */
  159.   "array", "[]",        /* old */
  160.   "vc", "[]",            /* ansi */
  161.   "compound", ",",        /* old */
  162.   "cm", ",",            /* ansi */
  163.   "nop", "",            /* old (for operator=) */
  164.   "as", "=",            /* ansi */
  165. };
  166.  
  167. /* Beware: these aren't '\0' terminated. */
  168.  
  169. typedef struct {
  170.   char *b;            /* pointer to start of string */
  171.   char *p;            /* pointer after last character */
  172.   char *e;            /* pointer after end of allocated space */
  173. } string;
  174.  
  175. #ifdef __STDC__
  176. static void string_need (string *s, int n);
  177. static void string_delete (string *s);
  178. static void string_init (string *s);
  179. static void string_clear (string *s);
  180. static int string_empty (string *s);
  181. static void string_append (string *p, const char *s);
  182. static void string_appends (string *p, string *s);
  183. static void string_appendn (string *p, const char *s, int n);
  184. static void string_prepend (string *p, const char *s);
  185. #if 0
  186. static void string_prepends (string *p, string *s);
  187. #endif
  188. static void string_prependn (string *p, const char *s, int n);
  189. static int get_count (const char **type, int *count);
  190. static int do_args (const char **type, string *decl);
  191. static int do_type (const char **type, string *result);
  192. static int do_arg (const char **type, string *result);
  193. static int do_args (const char **type, string *decl);
  194. static void munge_function_name (string *name);
  195. static void remember_type (const char *type, int len);
  196. #else
  197. static void string_need ();
  198. static void string_delete ();
  199. static void string_init ();
  200. static void string_clear ();
  201. static int string_empty ();
  202. static void string_append ();
  203. static void string_appends ();
  204. static void string_appendn ();
  205. static void string_prepend ();
  206. static void string_prepends ();
  207. static void string_prependn ();
  208. static int get_count ();
  209. static int do_args ();
  210. static int do_type ();
  211. static int do_arg ();
  212. static int do_args ();
  213. static void munge_function_name ();
  214. static void remember_type ();
  215. #endif
  216.  
  217. int
  218. get_simple_count (type, res)
  219.      char **type;
  220.      int *res;
  221. {
  222.   int n = 0, success = 1;;
  223.   
  224.   do
  225.     {
  226.       n *= 10;
  227.       n += **type - '0';
  228.       *type += 1;
  229.     } 
  230.   while (isdigit (**type));
  231.   if (strlen (*type) < n)
  232.     {
  233.       success = 0;
  234.     }
  235.  
  236.   *res = n;
  237.   return success;
  238. }
  239.  
  240. char *
  241. cplus_demangle (type)
  242.      const char *type;
  243. {
  244.   string decl;
  245.   int n;
  246.   int success = 0;
  247.   int constructor = 0;
  248.   int destructor = 0;
  249.   int static_type = 0;
  250.   int const_flag = 0;
  251.   int i;
  252.   const char *p;
  253. #ifndef LONGERNAMES
  254.   const char *premangle;
  255. #endif
  256.  
  257.   if (type == NULL || *type == '\0')
  258.     return NULL;
  259. #ifndef nounderscore
  260.   if (*type++ != '_')
  261.     return NULL;
  262. #endif
  263.   p = type;
  264.   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  265.     p++;
  266.   if (*p == '\0')
  267.     {
  268.       /* destructor */
  269.       if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
  270.     {
  271.       destructor = 1;
  272.       p = type;
  273.     }
  274.       /* static data member */
  275.       else if (*type != '_' && (index (type, CPLUS_MARKER) != NULL))
  276.     {
  277.       static_type = 1;
  278.       p = type;
  279.     }
  280.       /* virtual table "_vt$"  */
  281.       else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
  282.     {
  283.       int n = strlen (type + 4) + 14 + 1;
  284.       char *tem = (char *) xmalloc (n);
  285.       strcpy (tem, type + 4);
  286.       strcat (tem, " virtual table");
  287.       return tem;
  288.     }
  289.       else return NULL;
  290.     }
  291.  
  292.   string_init (&decl);
  293.  
  294.   if (static_type)
  295.     {
  296.       if (!isdigit (p[0]) && ('t' != p[0]))
  297.     {
  298.       string_delete (&decl);
  299.       return NULL;
  300.     }
  301.     }
  302.   else if (destructor)
  303.     {
  304.       if (!isdigit (p[3])&& ('t' != p[3]))
  305.     {
  306.       string_delete (&decl);
  307.       return NULL;
  308.     }
  309.       p += 3;
  310.     }
  311.   else if (p == type)
  312.     {
  313.       if (!isdigit (p[2]) && ('t' != p[2]))
  314.     {
  315.       p += 1;
  316.       while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  317.         p++;
  318.       stri