Home | History | Annotate | Line # | Download | only in libiberty
      1       1.1  mrg /* Demangler for GNU C++
      2  1.1.1.12  mrg    Copyright (C) 1989-2024 Free Software Foundation, Inc.
      3       1.1  mrg    Written by James Clark (jjc (at) jclark.uucp)
      4       1.1  mrg    Rewritten by Fred Fish (fnf (at) cygnus.com) for ARM and Lucid demangling
      5       1.1  mrg    Modified by Satish Pai (pai (at) apollo.hp.com) for HP demangling
      6       1.1  mrg 
      7       1.1  mrg This file is part of the libiberty library.
      8       1.1  mrg Libiberty is free software; you can redistribute it and/or
      9       1.1  mrg modify it under the terms of the GNU Library General Public
     10       1.1  mrg License as published by the Free Software Foundation; either
     11       1.1  mrg version 2 of the License, or (at your option) any later version.
     12       1.1  mrg 
     13       1.1  mrg In addition to the permissions in the GNU Library General Public
     14       1.1  mrg License, the Free Software Foundation gives you unlimited permission
     15       1.1  mrg to link the compiled version of this file into combinations with other
     16       1.1  mrg programs, and to distribute those combinations without any restriction
     17       1.1  mrg coming from the use of this file.  (The Library Public License
     18       1.1  mrg restrictions do apply in other respects; for example, they cover
     19       1.1  mrg modification of the file, and distribution when not linked into a
     20       1.1  mrg combined executable.)
     21       1.1  mrg 
     22       1.1  mrg Libiberty is distributed in the hope that it will be useful,
     23       1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     24       1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     25       1.1  mrg Library General Public License for more details.
     26       1.1  mrg 
     27       1.1  mrg You should have received a copy of the GNU Library General Public
     28       1.1  mrg License along with libiberty; see the file COPYING.LIB.  If
     29       1.1  mrg not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     30       1.1  mrg Boston, MA 02110-1301, USA.  */
     31       1.1  mrg 
     32       1.1  mrg /* This file lives in both GCC and libiberty.  When making changes, please
     33       1.1  mrg    try not to break either.  */
     34       1.1  mrg 
     35       1.1  mrg #ifdef HAVE_CONFIG_H
     36       1.1  mrg #include "config.h"
     37       1.1  mrg #endif
     38       1.1  mrg 
     39       1.1  mrg #include "safe-ctype.h"
     40       1.1  mrg 
     41       1.1  mrg #include <string.h>
     42       1.1  mrg 
     43       1.1  mrg #ifdef HAVE_STDLIB_H
     44       1.1  mrg #include <stdlib.h>
     45       1.1  mrg #else
     46       1.1  mrg void * malloc ();
     47       1.1  mrg void * realloc ();
     48       1.1  mrg #endif
     49       1.1  mrg 
     50       1.1  mrg #include <demangle.h>
     51       1.1  mrg #undef CURRENT_DEMANGLING_STYLE
     52   1.1.1.9  mrg #define CURRENT_DEMANGLING_STYLE options
     53       1.1  mrg 
     54       1.1  mrg #include "libiberty.h"
     55       1.1  mrg 
     56       1.1  mrg enum demangling_styles current_demangling_style = auto_demangling;
     57       1.1  mrg 
     58       1.1  mrg const struct demangler_engine libiberty_demanglers[] =
     59       1.1  mrg {
     60       1.1  mrg   {
     61       1.1  mrg     NO_DEMANGLING_STYLE_STRING,
     62       1.1  mrg     no_demangling,
     63       1.1  mrg     "Demangling disabled"
     64       1.1  mrg   }
     65       1.1  mrg   ,
     66       1.1  mrg   {
     67       1.1  mrg     AUTO_DEMANGLING_STYLE_STRING,
     68       1.1  mrg       auto_demangling,
     69       1.1  mrg       "Automatic selection based on executable"
     70       1.1  mrg   }
     71       1.1  mrg   ,
     72       1.1  mrg   {
     73       1.1  mrg     GNU_V3_DEMANGLING_STYLE_STRING,
     74       1.1  mrg     gnu_v3_demangling,
     75   1.1.1.9  mrg     "GNU (g++) V3 (Itanium C++ ABI) style demangling"
     76       1.1  mrg   }
     77       1.1  mrg   ,
     78       1.1  mrg   {
     79       1.1  mrg     JAVA_DEMANGLING_STYLE_STRING,
     80       1.1  mrg     java_demangling,
     81       1.1  mrg     "Java style demangling"
     82       1.1  mrg   }
     83       1.1  mrg   ,
     84       1.1  mrg   {
     85       1.1  mrg     GNAT_DEMANGLING_STYLE_STRING,
     86       1.1  mrg     gnat_demangling,
     87       1.1  mrg     "GNAT style demangling"
     88       1.1  mrg   }
     89       1.1  mrg   ,
     90       1.1  mrg   {
     91   1.1.1.3  mrg     DLANG_DEMANGLING_STYLE_STRING,
     92   1.1.1.3  mrg     dlang_demangling,
     93   1.1.1.3  mrg     "DLANG style demangling"
     94   1.1.1.3  mrg   }
     95   1.1.1.3  mrg   ,
     96   1.1.1.3  mrg   {
     97   1.1.1.5  mrg     RUST_DEMANGLING_STYLE_STRING,
     98   1.1.1.5  mrg     rust_demangling,
     99   1.1.1.5  mrg     "Rust style demangling"
    100   1.1.1.5  mrg   }
    101   1.1.1.5  mrg   ,
    102   1.1.1.5  mrg   {
    103       1.1  mrg     NULL, unknown_demangling, NULL
    104       1.1  mrg   }
    105       1.1  mrg };
    106       1.1  mrg 
    107       1.1  mrg /* Add a routine to set the demangling style to be sure it is valid and
    108       1.1  mrg    allow for any demangler initialization that maybe necessary. */
    109       1.1  mrg 
    110       1.1  mrg enum demangling_styles
    111       1.1  mrg cplus_demangle_set_style (enum demangling_styles style)
    112       1.1  mrg {
    113       1.1  mrg   const struct demangler_engine *demangler = libiberty_demanglers;
    114       1.1  mrg 
    115       1.1  mrg   for (; demangler->demangling_style != unknown_demangling; ++demangler)
    116       1.1  mrg     if (style == demangler->demangling_style)
    117       1.1  mrg       {
    118       1.1  mrg 	current_demangling_style = style;
    119       1.1  mrg 	return current_demangling_style;
    120       1.1  mrg       }
    121       1.1  mrg 
    122       1.1  mrg   return unknown_demangling;
    123       1.1  mrg }
    124       1.1  mrg 
    125       1.1  mrg /* Do string name to style translation */
    126       1.1  mrg 
    127       1.1  mrg enum demangling_styles
    128       1.1  mrg cplus_demangle_name_to_style (const char *name)
    129       1.1  mrg {
    130       1.1  mrg   const struct demangler_engine *demangler = libiberty_demanglers;
    131       1.1  mrg 
    132       1.1  mrg   for (; demangler->demangling_style != unknown_demangling; ++demangler)
    133       1.1  mrg     if (strcmp (name, demangler->demangling_style_name) == 0)
    134       1.1  mrg       return demangler->demangling_style;
    135       1.1  mrg 
    136       1.1  mrg   return unknown_demangling;
    137       1.1  mrg }
    138       1.1  mrg 
    139       1.1  mrg /* char *cplus_demangle (const char *mangled, int options)
    140       1.1  mrg 
    141       1.1  mrg    If MANGLED is a mangled function name produced by GNU C++, then
    142       1.1  mrg    a pointer to a @code{malloc}ed string giving a C++ representation
    143       1.1  mrg    of the name will be returned; otherwise NULL will be returned.
    144       1.1  mrg    It is the caller's responsibility to free the string which
    145       1.1  mrg    is returned.
    146       1.1  mrg 
    147       1.1  mrg    Note that any leading underscores, or other such characters prepended by
    148       1.1  mrg    the compilation system, are presumed to have already been stripped from
    149       1.1  mrg    MANGLED.  */
    150       1.1  mrg 
    151       1.1  mrg char *
    152       1.1  mrg cplus_demangle (const char *mangled, int options)
    153       1.1  mrg {
    154       1.1  mrg   char *ret;
    155       1.1  mrg 
    156       1.1  mrg   if (current_demangling_style == no_demangling)
    157       1.1  mrg     return xstrdup (mangled);
    158       1.1  mrg 
    159   1.1.1.9  mrg   if ((options & DMGL_STYLE_MASK) == 0)
    160   1.1.1.9  mrg     options |= (int) current_demangling_style & DMGL_STYLE_MASK;
    161       1.1  mrg 
    162  1.1.1.10  mrg   /* The Rust demangling is implemented elsewhere.
    163  1.1.1.10  mrg      Legacy Rust symbols overlap with GNU_V3, so try Rust first.  */
    164  1.1.1.10  mrg   if (RUST_DEMANGLING || AUTO_DEMANGLING)
    165  1.1.1.10  mrg     {
    166  1.1.1.10  mrg       ret = rust_demangle (mangled, options);
    167  1.1.1.10  mrg       if (ret || RUST_DEMANGLING)
    168  1.1.1.10  mrg         return ret;
    169  1.1.1.10  mrg     }
    170  1.1.1.10  mrg 
    171       1.1  mrg   /* The V3 ABI demangling is implemented elsewhere.  */
    172  1.1.1.10  mrg   if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
    173       1.1  mrg     {
    174   1.1.1.9  mrg       ret = cplus_demangle_v3 (mangled, options);
    175  1.1.1.10  mrg       if (ret || GNU_V3_DEMANGLING)
    176       1.1  mrg 	return ret;
    177       1.1  mrg     }
    178       1.1  mrg 
    179       1.1  mrg   if (JAVA_DEMANGLING)
    180       1.1  mrg     {
    181       1.1  mrg       ret = java_demangle_v3 (mangled);
    182       1.1  mrg       if (ret)
    183       1.1  mrg         return ret;
    184       1.1  mrg     }
    185       1.1  mrg 
    186       1.1  mrg   if (GNAT_DEMANGLING)
    187       1.1  mrg     return ada_demangle (mangled, options);
    188       1.1  mrg 
    189  1.1.1.12  mrg   if (DLANG_DEMANGLING || AUTO_DEMANGLING)
    190   1.1.1.3  mrg     {
    191   1.1.1.3  mrg       ret = dlang_demangle (mangled, options);
    192   1.1.1.3  mrg       if (ret)
    193   1.1.1.3  mrg 	return ret;
    194   1.1.1.3  mrg     }
    195   1.1.1.3  mrg 
    196       1.1  mrg   return (ret);
    197       1.1  mrg }
    198       1.1  mrg 
    199       1.1  mrg /* Demangle ada names.  The encoding is documented in gcc/ada/exp_dbug.ads.  */
    200       1.1  mrg 
    201       1.1  mrg char *
    202       1.1  mrg ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
    203       1.1  mrg {
    204       1.1  mrg   int len0;
    205       1.1  mrg   const char* p;
    206       1.1  mrg   char *d;
    207   1.1.1.5  mrg   char *demangled = NULL;
    208       1.1  mrg 
    209       1.1  mrg   /* Discard leading _ada_, which is used for library level subprograms.  */
    210       1.1  mrg   if (strncmp (mangled, "_ada_", 5) == 0)
    211       1.1  mrg     mangled += 5;
    212       1.1  mrg 
    213       1.1  mrg   /* All ada unit names are lower-case.  */
    214       1.1  mrg   if (!ISLOWER (mangled[0]))
    215       1.1  mrg     goto unknown;
    216       1.1  mrg 
    217       1.1  mrg   /* Most of the demangling will trivially remove chars.  Operator names
    218       1.1  mrg      may add one char but because they are always preceeded by '__' which is
    219   1.1.1.2  mrg      replaced by '.', they eventually never expand the size.
    220   1.1.1.2  mrg      A few special names such as '___elabs' add a few chars (at most 7), but
    221   1.1.1.2  mrg      they occur only once.  */
    222   1.1.1.2  mrg   len0 = strlen (mangled) + 7 + 1;
    223       1.1  mrg   demangled = XNEWVEC (char, len0);
    224       1.1  mrg 
    225       1.1  mrg   d = demangled;
    226       1.1  mrg   p = mangled;
    227       1.1  mrg   while (1)
    228       1.1  mrg     {
    229   1.1.1.2  mrg       /* An entity names is expected.  */
    230       1.1  mrg       if (ISLOWER (*p))
    231       1.1  mrg         {
    232   1.1.1.2  mrg           /* An identifier, which is always lower case.  */
    233       1.1  mrg           do
    234       1.1  mrg             *d++ = *p++;
    235       1.1  mrg           while (ISLOWER(*p) || ISDIGIT (*p)
    236       1.1  mrg                  || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
    237       1.1  mrg         }
    238       1.1  mrg       else if (p[0] == 'O')
    239       1.1  mrg         {
    240   1.1.1.2  mrg           /* An operator name.  */
    241       1.1  mrg           static const char * const operators[][2] =
    242       1.1  mrg             {{"Oabs", "abs"},  {"Oand", "and"},    {"Omod", "mod"},
    243       1.1  mrg              {"Onot", "not"},  {"Oor", "or"},      {"Orem", "rem"},
    244       1.1  mrg              {"Oxor", "xor"},  {"Oeq", "="},       {"One", "/="},
    245       1.1  mrg              {"Olt", "<"},     {"Ole", "<="},      {"Ogt", ">"},
    246       1.1  mrg              {"Oge", ">="},    {"Oadd", "+"},      {"Osubtract", "-"},
    247       1.1  mrg              {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
    248       1.1  mrg              {"Oexpon", "**"}, {NULL, NULL}};
    249       1.1  mrg           int k;
    250       1.1  mrg 
    251   1.1.1.2  mrg           for (k = 0; operators[k][0] != NULL; k++)
    252       1.1  mrg             {
    253   1.1.1.2  mrg               size_t slen = strlen (operators[k][0]);
    254   1.1.1.2  mrg               if (strncmp (p, operators[k][0], slen) == 0)
    255       1.1  mrg                 {
    256   1.1.1.2  mrg                   p += slen;
    257   1.1.1.2  mrg                   slen = strlen (operators[k][1]);
    258       1.1  mrg                   *d++ = '"';
    259   1.1.1.2  mrg                   memcpy (d, operators[k][1], slen);
    260   1.1.1.2  mrg                   d += slen;
    261       1.1  mrg                   *d++ = '"';
    262       1.1  mrg                   break;
    263       1.1  mrg                 }
    264       1.1  mrg             }
    265       1.1  mrg           /* Operator not found.  */
    266   1.1.1.2  mrg           if (operators[k][0] == NULL)
    267       1.1  mrg             goto unknown;
    268       1.1  mrg         }
    269       1.1  mrg       else
    270       1.1  mrg         {
    271       1.1  mrg           /* Not a GNAT encoding.  */
    272       1.1  mrg           goto unknown;
    273       1.1  mrg         }
    274       1.1  mrg 
    275   1.1.1.2  mrg       /* The name can be directly followed by some uppercase letters.  */
    276   1.1.1.2  mrg       if (p[0] == 'T' && p[1] == 'K')
    277   1.1.1.2  mrg         {
    278   1.1.1.2  mrg           /* Task stuff.  */
    279   1.1.1.2  mrg           if (p[2] == 'B' && p[3] == 0)
    280   1.1.1.2  mrg             {
    281   1.1.1.2  mrg               /* Subprogram for task body.  */
    282   1.1.1.2  mrg               break;
    283   1.1.1.2  mrg             }
    284   1.1.1.2  mrg           else if (p[2] == '_' && p[3] == '_')
    285   1.1.1.2  mrg             {
    286   1.1.1.2  mrg               /* Inner declarations in a task.  */
    287   1.1.1.2  mrg               p += 4;
    288   1.1.1.2  mrg               *d++ = '.';
    289   1.1.1.2  mrg               continue;
    290   1.1.1.2  mrg             }
    291   1.1.1.2  mrg           else
    292   1.1.1.2  mrg             goto unknown;
    293   1.1.1.2  mrg         }
    294   1.1.1.2  mrg       if (p[0] == 'E' && p[1] == 0)
    295   1.1.1.2  mrg         {
    296   1.1.1.2  mrg           /* Exception name.  */
    297   1.1.1.2  mrg           goto unknown;
    298   1.1.1.2  mrg         }
    299   1.1.1.2  mrg       if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
    300   1.1.1.2  mrg         {
    301   1.1.1.2  mrg           /* Protected type subprogram.  */
    302   1.1.1.2  mrg           break;
    303   1.1.1.2  mrg         }
    304   1.1.1.2  mrg       if ((*p == 'N' || *p == 'S') && p[1] == 0)
    305   1.1.1.2  mrg         {
    306   1.1.1.2  mrg           /* Enumerated type name table.  */
    307   1.1.1.2  mrg           goto unknown;
    308   1.1.1.2  mrg         }
    309   1.1.1.2  mrg       if (p[0] == 'X')
    310   1.1.1.2  mrg         {
    311   1.1.1.2  mrg           /* Body nested.  */
    312   1.1.1.2  mrg           p++;
    313   1.1.1.2  mrg           while (p[0] == 'n' || p[0] == 'b')
    314   1.1.1.2  mrg             p++;
    315   1.1.1.2  mrg         }
    316   1.1.1.2  mrg       if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
    317   1.1.1.2  mrg         {
    318   1.1.1.2  mrg           /* Stream operations.  */
    319   1.1.1.2  mrg           const char *name;
    320   1.1.1.2  mrg           switch (p[1])
    321   1.1.1.2  mrg             {
    322   1.1.1.2  mrg             case 'R':
    323   1.1.1.2  mrg               name = "'Read";
    324   1.1.1.2  mrg               break;
    325   1.1.1.2  mrg             case 'W':
    326   1.1.1.2  mrg               name = "'Write";
    327   1.1.1.2  mrg               break;
    328   1.1.1.2  mrg             case 'I':
    329   1.1.1.2  mrg               name = "'Input";
    330   1.1.1.2  mrg               break;
    331   1.1.1.2  mrg             case 'O':
    332   1.1.1.2  mrg               name = "'Output";
    333   1.1.1.2  mrg               break;
    334   1.1.1.2  mrg             default:
    335   1.1.1.2  mrg               goto unknown;
    336   1.1.1.2  mrg             }
    337   1.1.1.2  mrg           p += 2;
    338   1.1.1.2  mrg           strcpy (d, name);
    339   1.1.1.2  mrg           d += strlen (name);
    340   1.1.1.2  mrg         }
    341   1.1.1.2  mrg       else if (p[0] == 'D')
    342   1.1.1.2  mrg         {
    343   1.1.1.2  mrg           /* Controlled type operation.  */
    344   1.1.1.2  mrg           const char *name;
    345   1.1.1.2  mrg           switch (p[1])
    346   1.1.1.2  mrg             {
    347   1.1.1.2  mrg             case 'F':
    348   1.1.1.2  mrg               name = ".Finalize";
    349   1.1.1.2  mrg               break;
    350   1.1.1.2  mrg             case 'A':
    351   1.1.1.2  mrg               name = ".Adjust";
    352   1.1.1.2  mrg               break;
    353   1.1.1.2  mrg             default:
    354   1.1.1.2  mrg               goto unknown;
    355   1.1.1.2  mrg             }
    356   1.1.1.2  mrg           strcpy (d, name);
    357   1.1.1.2  mrg           d += strlen (name);
    358   1.1.1.2  mrg           break;
    359   1.1.1.2  mrg         }
    360   1.1.1.2  mrg 
    361       1.1  mrg       if (p[0] == '_')
    362       1.1  mrg         {
    363       1.1  mrg           /* Separator.  */
    364       1.1  mrg           if (p[1] == '_')
    365       1.1  mrg             {
    366       1.1  mrg               /* Standard separator.  Handled first.  */
    367       1.1  mrg               p += 2;
    368   1.1.1.2  mrg 
    369       1.1  mrg               if (ISDIGIT (*p))
    370       1.1  mrg                 {
    371   1.1.1.2  mrg                   /* Overloading number.  */
    372       1.1  mrg                   do
    373       1.1  mrg                     p++;
    374       1.1  mrg                   while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
    375   1.1.1.2  mrg                   if (*p == 'X')
    376   1.1.1.2  mrg                     {
    377   1.1.1.2  mrg                       p++;
    378   1.1.1.2  mrg                       while (p[0] == 'n' || p[0] == 'b')
    379   1.1.1.2  mrg                         p++;
    380   1.1.1.2  mrg                     }
    381       1.1  mrg                 }
    382   1.1.1.2  mrg               else if (p[0] == '_' && p[1] != '_')
    383       1.1  mrg                 {
    384   1.1.1.2  mrg                   /* Special names.  */
    385   1.1.1.2  mrg                   static const char * const special[][2] = {
    386   1.1.1.2  mrg                     { "_elabb", "'Elab_Body" },
    387   1.1.1.2  mrg                     { "_elabs", "'Elab_Spec" },
    388   1.1.1.2  mrg                     { "_size", "'Size" },
    389   1.1.1.2  mrg                     { "_alignment", "'Alignment" },
    390   1.1.1.2  mrg                     { "_assign", ".\":=\"" },
    391   1.1.1.2  mrg                     { NULL, NULL }
    392   1.1.1.2  mrg                   };
    393   1.1.1.2  mrg                   int k;
    394   1.1.1.2  mrg 
    395   1.1.1.2  mrg                   for (k = 0; special[k][0] != NULL; k++)
    396   1.1.1.2  mrg                     {
    397   1.1.1.2  mrg                       size_t slen = strlen (special[k][0]);
    398   1.1.1.2  mrg                       if (strncmp (p, special[k][0], slen) == 0)
    399   1.1.1.2  mrg                         {
    400   1.1.1.2  mrg                           p += slen;
    401   1.1.1.2  mrg                           slen = strlen (special[k][1]);
    402   1.1.1.2  mrg                           memcpy (d, special[k][1], slen);
    403   1.1.1.2  mrg                           d += slen;
    404   1.1.1.2  mrg                           break;
    405   1.1.1.2  mrg                         }
    406   1.1.1.2  mrg                     }
    407   1.1.1.2  mrg                   if (special[k][0] != NULL)
    408   1.1.1.2  mrg                     break;
    409   1.1.1.2  mrg                   else
    410   1.1.1.2  mrg                     goto unknown;
    411       1.1  mrg                 }
    412       1.1  mrg               else
    413       1.1  mrg                 {
    414       1.1  mrg                   *d++ = '.';
    415       1.1  mrg                   continue;
    416       1.1  mrg                 }
    417       1.1  mrg             }
    418       1.1  mrg           else if (p[1] == 'B' || p[1] == 'E')
    419       1.1  mrg             {
    420       1.1  mrg               /* Entry Body or barrier Evaluation.  */
    421       1.1  mrg               p += 2;
    422       1.1  mrg               while (ISDIGIT (*p))
    423       1.1  mrg                 p++;
    424       1.1  mrg               if (p[0] == 's' && p[1] == 0)
    425       1.1  mrg                 break;
    426       1.1  mrg               else
    427       1.1  mrg                 goto unknown;
    428       1.1  mrg             }
    429       1.1  mrg           else
    430       1.1  mrg             goto unknown;
    431       1.1  mrg         }
    432       1.1  mrg 
    433       1.1  mrg       if (p[0] == '.' && ISDIGIT (p[1]))
    434       1.1  mrg         {
    435       1.1  mrg           /* Nested subprogram.  */
    436       1.1  mrg           p += 2;
    437       1.1  mrg           while (ISDIGIT (*p))
    438       1.1  mrg             p++;
    439       1.1  mrg         }
    440       1.1  mrg       if (*p == 0)
    441       1.1  mrg         {
    442       1.1  mrg           /* End of mangled name.  */
    443       1.1  mrg           break;
    444       1.1  mrg         }
    445       1.1  mrg       else
    446       1.1  mrg         goto unknown;
    447       1.1  mrg     }
    448       1.1  mrg   *d = 0;
    449       1.1  mrg   return demangled;
    450       1.1  mrg 
    451       1.1  mrg  unknown:
    452   1.1.1.5  mrg   XDELETEVEC (demangled);
    453       1.1  mrg   len0 = strlen (mangled);
    454       1.1  mrg   demangled = XNEWVEC (char, len0 + 3);
    455       1.1  mrg 
    456       1.1  mrg   if (mangled[0] == '<')
    457       1.1  mrg      strcpy (demangled, mangled);
    458       1.1  mrg   else
    459       1.1  mrg     sprintf (demangled, "<%s>", mangled);
    460       1.1  mrg 
    461       1.1  mrg   return demangled;
    462       1.1  mrg }
    463