Home | History | Annotate | Download | only in libiberty
      1 /* Demangler for GNU C++
      2    Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
      3    2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
      4    Written by James Clark (jjc (at) jclark.uucp)
      5    Rewritten by Fred Fish (fnf (at) cygnus.com) for ARM and Lucid demangling
      6    Modified by Satish Pai (pai (at) apollo.hp.com) for HP demangling
      7 
      8 This file is part of the libiberty library.
      9 Libiberty is free software; you can redistribute it and/or
     10 modify it under the terms of the GNU Library General Public
     11 License as published by the Free Software Foundation; either
     12 version 2 of the License, or (at your option) any later version.
     13 
     14 In addition to the permissions in the GNU Library General Public
     15 License, the Free Software Foundation gives you unlimited permission
     16 to link the compiled version of this file into combinations with other
     17 programs, and to distribute those combinations without any restriction
     18 coming from the use of this file.  (The Library Public License
     19 restrictions do apply in other respects; for example, they cover
     20 modification of the file, and distribution when not linked into a
     21 combined executable.)
     22 
     23 Libiberty is distributed in the hope that it will be useful,
     24 but WITHOUT ANY WARRANTY; without even the implied warranty of
     25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     26 Library General Public License for more details.
     27 
     28 You should have received a copy of the GNU Library General Public
     29 License along with libiberty; see the file COPYING.LIB.  If
     30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     31 Boston, MA 02110-1301, USA.  */
     32 
     33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
     34 
     35    This file imports xmalloc and xrealloc, which are like malloc and
     36    realloc except that they generate a fatal error if there is no
     37    available memory.  */
     38 
     39 /* This file lives in both GCC and libiberty.  When making changes, please
     40    try not to break either.  */
     41 
     42 #ifdef HAVE_CONFIG_H
     43 #include "config.h"
     44 #endif
     45 
     46 #include "safe-ctype.h"
     47 
     48 #include <sys/types.h>
     49 #include <string.h>
     50 #include <stdio.h>
     51 
     52 #ifdef HAVE_STDLIB_H
     53 #include <stdlib.h>
     54 #else
     55 void * malloc ();
     56 void * realloc ();
     57 #endif
     58 
     59 #include <demangle.h>
     60 #undef CURRENT_DEMANGLING_STYLE
     61 #define CURRENT_DEMANGLING_STYLE work->options
     62 
     63 #include "libiberty.h"
     64 
     65 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
     66 
     67 /* A value at least one greater than the maximum number of characters
     68    that will be output when using the `%d' format with `printf'.  */
     69 #define INTBUF_SIZE 32
     70 
     71 extern void fancy_abort (void) ATTRIBUTE_NORETURN;
     72 
     73 /* In order to allow a single demangler executable to demangle strings
     74    using various common values of CPLUS_MARKER, as well as any specific
     75    one set at compile time, we maintain a string containing all the
     76    commonly used ones, and check to see if the marker we are looking for
     77    is in that string.  CPLUS_MARKER is usually '$' on systems where the
     78    assembler can deal with that.  Where the assembler can't, it's usually
     79    '.' (but on many systems '.' is used for other things).  We put the
     80    current defined CPLUS_MARKER first (which defaults to '$'), followed
     81    by the next most common value, followed by an explicit '$' in case
     82    the value of CPLUS_MARKER is not '$'.
     83 
     84    We could avoid this if we could just get g++ to tell us what the actual
     85    cplus marker character is as part of the debug information, perhaps by
     86    ensuring that it is the character that terminates the gcc<n>_compiled
     87    marker symbol (FIXME).  */
     88 
     89 #if !defined (CPLUS_MARKER)
     90 #define CPLUS_MARKER '$'
     91 #endif
     92 
     93 enum demangling_styles current_demangling_style = auto_demangling;
     94 
     95 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
     96 
     97 static char char_str[2] = { '\000', '\000' };
     98 
     99 void
    100 set_cplus_marker_for_demangling (int ch)
    101 {
    102   cplus_markers[0] = ch;
    103 }
    104 
    105 typedef struct string		/* Beware: these aren't required to be */
    106 {				/*  '\0' terminated.  */
    107   char *b;			/* pointer to start of string */
    108   char *p;			/* pointer after last character */
    109   char *e;			/* pointer after end of allocated space */
    110 } string;
    111 
    112 /* Stuff that is shared between sub-routines.
    113    Using a shared structure allows cplus_demangle to be reentrant.  */
    114 
    115 struct work_stuff
    116 {
    117   int options;
    118   char **typevec;
    119   char **ktypevec;
    120   char **btypevec;
    121   int numk;
    122   int numb;
    123   int ksize;
    124   int bsize;
    125   int ntypes;
    126   int typevec_size;
    127   int constructor;
    128   int destructor;
    129   int static_type;	/* A static member function */
    130   int temp_start;       /* index in demangled to start of template args */
    131   int type_quals;       /* The type qualifiers.  */
    132   int dllimported;	/* Symbol imported from a PE DLL */
    133   char **tmpl_argvec;   /* Template function arguments. */
    134   int ntmpl_args;       /* The number of template function arguments. */
    135   int forgetting_types; /* Nonzero if we are not remembering the types
    136 			   we see.  */
    137   string* previous_argument; /* The last function argument demangled.  */
    138   int nrepeats;         /* The number of times to repeat the previous
    139 			   argument.  */
    140 };
    141 
    142 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
    143 #define PRINT_ARG_TYPES       (work -> options & DMGL_PARAMS)
    144 
    145 static const struct optable
    146 {
    147   const char *const in;
    148   const char *const out;
    149   const int flags;
    150 } optable[] = {
    151   {"nw",	  " new",	DMGL_ANSI},	/* new (1.92,	 ansi) */
    152   {"dl",	  " delete",	DMGL_ANSI},	/* new (1.92,	 ansi) */
    153   {"new",	  " new",	0},		/* old (1.91,	 and 1.x) */
    154   {"delete",	  " delete",	0},		/* old (1.91,	 and 1.x) */
    155   {"vn",	  " new []",	DMGL_ANSI},	/* GNU, pending ansi */
    156   {"vd",	  " delete []",	DMGL_ANSI},	/* GNU, pending ansi */
    157   {"as",	  "=",		DMGL_ANSI},	/* ansi */
    158   {"ne",	  "!=",		DMGL_ANSI},	/* old, ansi */
    159   {"eq",	  "==",		DMGL_ANSI},	/* old,	ansi */
    160   {"ge",	  ">=",		DMGL_ANSI},	/* old,	ansi */
    161   {"gt",	  ">",		DMGL_ANSI},	/* old,	ansi */
    162   {"le",	  "<=",		DMGL_ANSI},	/* old,	ansi */
    163   {"lt",	  "<",		DMGL_ANSI},	/* old,	ansi */
    164   {"plus",	  "+",		0},		/* old */
    165   {"pl",	  "+",		DMGL_ANSI},	/* ansi */
    166   {"apl",	  "+=",		DMGL_ANSI},	/* ansi */
    167   {"minus",	  "-",		0},		/* old */
    168   {"mi",	  "-",		DMGL_ANSI},	/* ansi */
    169   {"ami",	  "-=",		DMGL_ANSI},	/* ansi */
    170   {"mult",	  "*",		0},		/* old */
    171   {"ml",	  "*",		DMGL_ANSI},	/* ansi */
    172   {"amu",	  "*=",		DMGL_ANSI},	/* ansi (ARM/Lucid) */
    173   {"aml",	  "*=",		DMGL_ANSI},	/* ansi (GNU/g++) */
    174   {"convert",	  "+",		0},		/* old (unary +) */
    175   {"negate",	  "-",		0},		/* old (unary -) */
    176   {"trunc_mod",	  "%",		0},		/* old */
    177   {"md",	  "%",		DMGL_ANSI},	/* ansi */
    178   {"amd",	  "%=",		DMGL_ANSI},	/* ansi */
    179   {"trunc_div",	  "/",		0},		/* old */
    180   {"dv",	  "/",		DMGL_ANSI},	/* ansi */
    181   {"adv",	  "/=",		DMGL_ANSI},	/* ansi */
    182   {"truth_andif", "&&",		0},		/* old */
    183   {"aa",	  "&&",		DMGL_ANSI},	/* ansi */
    184   {"truth_orif",  "||",		0},		/* old */
    185   {"oo",	  "||",		DMGL_ANSI},	/* ansi */
    186   {"truth_not",	  "!",		0},		/* old */
    187   {"nt",	  "!",		DMGL_ANSI},	/* ansi */
    188   {"postincrement","++",	0},		/* old */
    189   {"pp",	  "++",		DMGL_ANSI},	/* ansi */
    190   {"postdecrement","--",	0},		/* old */
    191   {"mm",	  "--",		DMGL_ANSI},	/* ansi */
    192   {"bit_ior",	  "|",		0},		/* old */
    193   {"or",	  "|",		DMGL_ANSI},	/* ansi */
    194   {"aor",	  "|=",		DMGL_ANSI},	/* ansi */
    195   {"bit_xor",	  "^",		0},		/* old */
    196   {"er",	  "^",		DMGL_ANSI},	/* ansi */
    197   {"aer",	  "^=",		DMGL_ANSI},	/* ansi */
    198   {"bit_and",	  "&",		0},		/* old */
    199   {"ad",	  "&",		DMGL_ANSI},	/* ansi */
    200   {"aad",	  "&=",		DMGL_ANSI},	/* ansi */
    201   {"bit_not",	  "~",		0},		/* old */
    202   {"co",	  "~",		DMGL_ANSI},	/* ansi */
    203   {"call",	  "()",		0},		/* old */
    204   {"cl",	  "()",		DMGL_ANSI},	/* ansi */
    205   {"alshift",	  "<<",		0},		/* old */
    206   {"ls",	  "<<",		DMGL_ANSI},	/* ansi */
    207   {"als",	  "<<=",	DMGL_ANSI},	/* ansi */
    208   {"arshift",	  ">>",		0},		/* old */
    209   {"rs",	  ">>",		DMGL_ANSI},	/* ansi */
    210   {"ars",	  ">>=",	DMGL_ANSI},	/* ansi */
    211   {"component",	  "->",		0},		/* old */
    212   {"pt",	  "->",		DMGL_ANSI},	/* ansi; Lucid C++ form */
    213   {"rf",	  "->",		DMGL_ANSI},	/* ansi; ARM/GNU form */
    214   {"indirect",	  "*",		0},		/* old */
    215   {"method_call",  "->()",	0},		/* old */
    216   {"addr",	  "&",		0},		/* old (unary &) */
    217   {"array",	  "[]",		0},		/* old */
    218   {"vc",	  "[]",		DMGL_ANSI},	/* ansi */
    219   {"compound",	  ", ",		0},		/* old */
    220   {"cm",	  ", ",		DMGL_ANSI},	/* ansi */
    221   {"cond",	  "?:",		0},		/* old */
    222   {"cn",	  "?:",		DMGL_ANSI},	/* pseudo-ansi */
    223   {"max",	  ">?",		0},		/* old */
    224   {"mx",	  ">?",		DMGL_ANSI},	/* pseudo-ansi */
    225   {"min",	  "<?",		0},		/* old */
    226   {"mn",	  "<?",		DMGL_ANSI},	/* pseudo-ansi */
    227   {"nop",	  "",		0},		/* old (for operator=) */
    228   {"rm",	  "->*",	DMGL_ANSI},	/* ansi */
    229   {"sz",          "sizeof ",    DMGL_ANSI}      /* pseudo-ansi */
    230 };
    231 
    232 /* These values are used to indicate the various type varieties.
    233    They are all non-zero so that they can be used as `success'
    234    values.  */
    235 typedef enum type_kind_t
    236 {
    237   tk_none,
    238   tk_pointer,
    239   tk_reference,
    240   tk_integral,
    241   tk_bool,
    242   tk_char,
    243   tk_real
    244 } type_kind_t;
    245 
    246 const struct demangler_engine libiberty_demanglers[] =
    247 {
    248   {
    249     NO_DEMANGLING_STYLE_STRING,
    250     no_demangling,
    251     "Demangling disabled"
    252   }
    253   ,
    254   {
    255     AUTO_DEMANGLING_STYLE_STRING,
    256       auto_demangling,
    257       "Automatic selection based on executable"
    258   }
    259   ,
    260   {
    261     GNU_DEMANGLING_STYLE_STRING,
    262       gnu_demangling,
    263       "GNU (g++) style demangling"
    264   }
    265   ,
    266   {
    267     LUCID_DEMANGLING_STYLE_STRING,
    268       lucid_demangling,
    269       "Lucid (lcc) style demangling"
    270   }
    271   ,
    272   {
    273     ARM_DEMANGLING_STYLE_STRING,
    274       arm_demangling,
    275       "ARM style demangling"
    276   }
    277   ,
    278   {
    279     HP_DEMANGLING_STYLE_STRING,
    280       hp_demangling,
    281       "HP (aCC) style demangling"
    282   }
    283   ,
    284   {
    285     EDG_DEMANGLING_STYLE_STRING,
    286       edg_demangling,
    287       "EDG style demangling"
    288   }
    289   ,
    290   {
    291     GNU_V3_DEMANGLING_STYLE_STRING,
    292     gnu_v3_demangling,
    293     "GNU (g++) V3 ABI-style demangling"
    294   }
    295   ,
    296   {
    297     JAVA_DEMANGLING_STYLE_STRING,
    298     java_demangling,
    299     "Java style demangling"
    300   }
    301   ,
    302   {
    303     GNAT_DEMANGLING_STYLE_STRING,
    304     gnat_demangling,
    305     "GNAT style demangling"
    306   }
    307   ,
    308   {
    309     DLANG_DEMANGLING_STYLE_STRING,
    310     dlang_demangling,
    311     "DLANG style demangling"
    312   }
    313   ,
    314   {
    315     NULL, unknown_demangling, NULL
    316   }
    317 };
    318 
    319 #define STRING_EMPTY(str)	((str) -> b == (str) -> p)
    320 #define APPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
    321     string_append(str, " ");}
    322 #define LEN_STRING(str)         ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
    323 
    324 /* The scope separator appropriate for the language being demangled.  */
    325 
    326 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
    327 
    328 #define ARM_VTABLE_STRING "__vtbl__"	/* Lucid/ARM virtual table prefix */
    329 #define ARM_VTABLE_STRLEN 8		/* strlen (ARM_VTABLE_STRING) */
    330 
    331 /* Prototypes for local functions */
    332 
    333 static void delete_work_stuff (struct work_stuff *);
    334 
    335 static void delete_non_B_K_work_stuff (struct work_stuff *);
    336 
    337 static char *mop_up (struct work_stuff *, string *, int);
    338 
    339 static void squangle_mop_up (struct work_stuff *);
    340 
    341 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *);
    342 
    343 #if 0
    344 static int
    345 demangle_method_args (struct work_stuff *, const char **, string *);
    346 #endif
    347 
    348 static char *
    349 internal_cplus_demangle (struct work_stuff *, const char *);
    350 
    351 static int
    352 demangle_template_template_parm (struct work_stuff *work,
    353                                  const char **, string *);
    354 
    355 static int
    356 demangle_template (struct work_stuff *work, const char **, string *,
    357                    string *, int, int);
    358 
    359 static int
    360 arm_pt (struct work_stuff *, const char *, int, const char **,
    361         const char **);
    362 
    363 static int
    364 demangle_class_name (struct work_stuff *, const char **, string *);
    365 
    366 static int
    367 demangle_qualified (struct work_stuff *, const char **, string *,
    368                     int, int);
    369 
    370 static int demangle_class (struct work_stuff *, const char **, string *);
    371 
    372 static int demangle_fund_type (struct work_stuff *, const char **, string *);
    373 
    374 static int demangle_signature (struct work_stuff *, const char **, string *);
    375 
    376 static int demangle_prefix (struct work_stuff *, const char **, string *);
    377 
    378 static int gnu_special (struct work_stuff *, const char **, string *);
    379 
    380 static int arm_special (const char **, string *);
    381 
    382 static void string_need (string *, int);
    383 
    384 static void string_delete (string *);
    385 
    386 static void
    387 string_init (string *);
    388 
    389 static void string_clear (string *);
    390 
    391 #if 0
    392 static int string_empty (string *);
    393 #endif
    394 
    395 static void string_append (string *, const char *);
    396 
    397 static void string_appends (string *, string *);
    398 
    399 static void string_appendn (string *, const char *, int);
    400 
    401 static void string_prepend (string *, const char *);
    402 
    403 static void string_prependn (string *, const char *, int);
    404 
    405 static void string_append_template_idx (string *, int);
    406 
    407 static int get_count (const char **, int *);
    408 
    409 static int consume_count (const char **);
    410 
    411 static int consume_count_with_underscores (const char**);
    412 
    413 static int demangle_args (struct work_stuff *, const char **, string *);
    414 
    415 static int demangle_nested_args (struct work_stuff*, const char**, string*);
    416 
    417 static int do_type (struct work_stuff *, const char **, string *);
    418 
    419 static int do_arg (struct work_stuff *, const char **, string *);
    420 
    421 static int
    422 demangle_function_name (struct work_stuff *, const char **, string *,
    423                         const char *);
    424 
    425 static int
    426 iterate_demangle_function (struct work_stuff *,
    427                            const char **, string *, const char *);
    428 
    429 static void remember_type (struct work_stuff *, const char *, int);
    430 
    431 static void remember_Btype (struct work_stuff *, const char *, int, int);
    432 
    433 static int register_Btype (struct work_stuff *);
    434 
    435 static void remember_Ktype (struct work_stuff *, const char *, int);
    436 
    437 static void forget_types (struct work_stuff *);
    438 
    439 static void forget_B_and_K_types (struct work_stuff *);
    440 
    441 static void string_prepends (string *, string *);
    442 
    443 static int
    444 demangle_template_value_parm (struct work_stuff*, const char**,
    445                               string*, type_kind_t);
    446 
    447 static int
    448 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
    449 
    450 static int
    451 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
    452 
    453 static int snarf_numeric_literal (const char **, string *);
    454 
    455 /* There is a TYPE_QUAL value for each type qualifier.  They can be
    456    combined by bitwise-or to form the complete set of qualifiers for a
    457    type.  */
    458 
    459 #define TYPE_UNQUALIFIED   0x0
    460 #define TYPE_QUAL_CONST    0x1
    461 #define TYPE_QUAL_VOLATILE 0x2
    462 #define TYPE_QUAL_RESTRICT 0x4
    463 
    464 static int code_for_qualifier (int);
    465 
    466 static const char* qualifier_string (int);
    467 
    468 static const char* demangle_qualifier (int);
    469 
    470 static int demangle_expression (struct work_stuff *, const char **, string *,
    471                                 type_kind_t);
    472 
    473 static int
    474 demangle_integral_value (struct work_stuff *, const char **, string *);
    475 
    476 static int
    477 demangle_real_value (struct work_stuff *, const char **, string *);
    478 
    479 static void
    480 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
    481 
    482 static void
    483 recursively_demangle (struct work_stuff *, const char **, string *, int);
    484 
    485 /* Translate count to integer, consuming tokens in the process.
    486    Conversion terminates on the first non-digit character.
    487 
    488    Trying to consume something that isn't a count results in no
    489    consumption of input and a return of -1.
    490 
    491    Overflow consumes the rest of the digits, and returns -1.  */
    492 
    493 static int
    494 consume_count (const char **type)
    495 {
    496   int count = 0;
    497 
    498   if (! ISDIGIT ((unsigned char)**type))
    499     return -1;
    500 
    501   while (ISDIGIT ((unsigned char)**type))
    502     {
    503       count *= 10;
    504 
    505       /* Check for overflow.
    506 	 We assume that count is represented using two's-complement;
    507 	 no power of two is divisible by ten, so if an overflow occurs
    508 	 when multiplying by ten, the result will not be a multiple of
    509 	 ten.  */
    510       if ((count % 10) != 0)
    511 	{
    512 	  while (ISDIGIT ((unsigned char) **type))
    513 	    (*type)++;
    514 	  return -1;
    515 	}
    516 
    517       count += **type - '0';
    518       (*type)++;
    519     }
    520 
    521   if (count < 0)
    522     count = -1;
    523 
    524   return (count);
    525 }
    526 
    527 
    528 /* Like consume_count, but for counts that are preceded and followed
    529    by '_' if they are greater than 10.  Also, -1 is returned for
    530    failure, since 0 can be a valid value.  */
    531 
    532 static int
    533 consume_count_with_underscores (const char **mangled)
    534 {
    535   int idx;
    536 
    537   if (**mangled == '_')
    538     {
    539       (*mangled)++;
    540       if (!ISDIGIT ((unsigned char)**mangled))
    541 	return -1;
    542 
    543       idx = consume_count (mangled);
    544       if (**mangled != '_')
    545 	/* The trailing underscore was missing. */
    546 	return -1;
    547 
    548       (*mangled)++;
    549     }
    550   else
    551     {
    552       if (**mangled < '0' || **mangled > '9')
    553 	return -1;
    554 
    555       idx = **mangled - '0';
    556       (*mangled)++;
    557     }
    558 
    559   return idx;
    560 }
    561 
    562 /* C is the code for a type-qualifier.  Return the TYPE_QUAL
    563    corresponding to this qualifier.  */
    564 
    565 static int
    566 code_for_qualifier (int c)
    567 {
    568   switch (c)
    569     {
    570     case 'C':
    571       return TYPE_QUAL_CONST;
    572 
    573     case 'V':
    574       return TYPE_QUAL_VOLATILE;
    575 
    576     case 'u':
    577       return TYPE_QUAL_RESTRICT;
    578 
    579     default:
    580       break;
    581     }
    582 
    583   /* C was an invalid qualifier.  */
    584   abort ();
    585 }
    586 
    587 /* Return the string corresponding to the qualifiers given by
    588    TYPE_QUALS.  */
    589 
    590 static const char*
    591 qualifier_string (int type_quals)
    592 {
    593   switch (type_quals)
    594     {
    595     case TYPE_UNQUALIFIED:
    596       return "";
    597 
    598     case TYPE_QUAL_CONST:
    599       return "const";
    600 
    601     case TYPE_QUAL_VOLATILE:
    602       return "volatile";
    603 
    604     case TYPE_QUAL_RESTRICT:
    605       return "__restrict";
    606 
    607     case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
    608       return "const volatile";
    609 
    610     case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
    611       return "const __restrict";
    612 
    613     case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
    614       return "volatile __restrict";
    615 
    616     case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
    617       return "const volatile __restrict";
    618 
    619     default:
    620       break;
    621     }
    622 
    623   /* TYPE_QUALS was an invalid qualifier set.  */
    624   abort ();
    625 }
    626 
    627 /* C is the code for a type-qualifier.  Return the string
    628    corresponding to this qualifier.  This function should only be
    629    called with a valid qualifier code.  */
    630 
    631 static const char*
    632 demangle_qualifier (int c)
    633 {
    634   return qualifier_string (code_for_qualifier (c));
    635 }
    636 
    637 int
    638 cplus_demangle_opname (const char *opname, char *result, int options)
    639 {
    640   int len, len1, ret;
    641   string type;
    642   struct work_stuff work[1];
    643   const char *tem;
    644 
    645   len = strlen(opname);
    646   result[0] = '\0';
    647   ret = 0;
    648   memset ((char *) work, 0, sizeof (work));
    649   work->options = options;
    650 
    651   if (opname[0] == '_' && opname[1] == '_'
    652       && opname[2] == 'o' && opname[3] == 'p')
    653     {
    654       /* ANSI.  */
    655       /* type conversion operator.  */
    656       tem = opname + 4;
    657       if (do_type (work, &tem, &type))
    658 	{
    659 	  strcat (result, "operator ");
    660 	  strncat (result, type.b, type.p - type.b);
    661 	  string_delete (&type);
    662 	  ret = 1;
    663 	}
    664     }
    665   else if (opname[0] == '_' && opname[1] == '_'
    666 	   && ISLOWER((unsigned char)opname[2])
    667 	   && ISLOWER((unsigned char)opname[3]))
    668     {
    669       if (opname[4] == '\0')
    670 	{
    671 	  /* Operator.  */
    672 	  size_t i;
    673 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
    674 	    {
    675 	      if (strlen (optable[i].in) == 2
    676 		  && memcmp (optable[i].in, opname + 2, 2) == 0)
    677 		{
    678 		  strcat (result, "operator");
    679 		  strcat (result, optable[i].out);
    680 		  ret = 1;
    681 		  break;
    682 		}
    683 	    }
    684 	}
    685       else
    686 	{
    687 	  if (opname[2] == 'a' && opname[5] == '\0')
    688 	    {
    689 	      /* Assignment.  */
    690 	      size_t i;
    691 	      for (i = 0; i < ARRAY_SIZE (optable); i++)
    692 		{
    693 		  if (strlen (optable[i].in) == 3
    694 		      && memcmp (optable[i].in, opname + 2, 3) == 0)
    695 		    {
    696 		      strcat (result, "operator");
    697 		      strcat (result, optable[i].out);
    698 		      ret = 1;
    699 		      break;
    700 		    }
    701 		}
    702 	    }
    703 	}
    704     }
    705   else if (len >= 3
    706 	   && opname[0] == 'o'
    707 	   && opname[1] == 'p'
    708 	   && strchr (cplus_markers, opname[2]) != NULL)
    709     {
    710       /* see if it's an assignment expression */
    711       if (len >= 10 /* op$assign_ */
    712 	  && memcmp (opname + 3, "assign_", 7) == 0)
    713 	{
    714 	  size_t i;
    715 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
    716 	    {
    717 	      len1 = len - 10;
    718 	      if ((int) strlen (optable[i].in) == len1
    719 		  && memcmp (optable[i].in, opname + 10, len1) == 0)
    720 		{
    721 		  strcat (result, "operator");
    722 		  strcat (result, optable[i].out);
    723 		  strcat (result, "=");
    724 		  ret = 1;
    725 		  break;
    726 		}
    727 	    }
    728 	}
    729       else
    730 	{
    731 	  size_t i;
    732 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
    733 	    {
    734 	      len1 = len - 3;
    735 	      if ((int) strlen (optable[i].in) == len1
    736 		  && memcmp (optable[i].in, opname + 3, len1) == 0)
    737 		{
    738 		  strcat (result, "operator");
    739 		  strcat (result, optable[i].out);
    740 		  ret = 1;
    741 		  break;
    742 		}
    743 	    }
    744 	}
    745     }
    746   else if (len >= 5 && memcmp (opname, "type", 4) == 0
    747 	   && strchr (cplus_markers, opname[4]) != NULL)
    748     {
    749       /* type conversion operator */
    750       tem = opname + 5;
    751       if (do_type (work, &tem, &type))
    752 	{
    753 	  strcat (result, "operator ");
    754 	  strncat (result, type.b, type.p - type.b);
    755 	  string_delete (&type);
    756 	  ret = 1;
    757 	}
    758     }
    759   squangle_mop_up (work);
    760   return ret;
    761 
    762 }
    763 
    764 /* Takes operator name as e.g. "++" and returns mangled
    765    operator name (e.g. "postincrement_expr"), or NULL if not found.
    766 
    767    If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
    768    if OPTIONS & DMGL_ANSI == 0, return the old GNU name.  */
    769 
    770 const char *
    771 cplus_mangle_opname (const char *opname, int options)
    772 {
    773   size_t i;
    774   int len;
    775 
    776   len = strlen (opname);
    777   for (i = 0; i < ARRAY_SIZE (optable); i++)
    778     {
    779       if ((int) strlen (optable[i].out) == len
    780 	  && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
    781 	  && memcmp (optable[i].out, opname, len) == 0)
    782 	return optable[i].in;
    783     }
    784   return (0);
    785 }
    786 
    787 /* Add a routine to set the demangling style to be sure it is valid and
    788    allow for any demangler initialization that maybe necessary. */
    789 
    790 enum demangling_styles
    791 cplus_demangle_set_style (enum demangling_styles style)
    792 {
    793   const struct demangler_engine *demangler = libiberty_demanglers;
    794 
    795   for (; demangler->demangling_style != unknown_demangling; ++demangler)
    796     if (style == demangler->demangling_style)
    797       {
    798 	current_demangling_style = style;
    799 	return current_demangling_style;
    800       }
    801 
    802   return unknown_demangling;
    803 }
    804 
    805 /* Do string name to style translation */
    806 
    807 enum demangling_styles
    808 cplus_demangle_name_to_style (const char *name)
    809 {
    810   const struct demangler_engine *demangler = libiberty_demanglers;
    811 
    812   for (; demangler->demangling_style != unknown_demangling; ++demangler)
    813     if (strcmp (name, demangler->demangling_style_name) == 0)
    814       return demangler->demangling_style;
    815 
    816   return unknown_demangling;
    817 }
    818 
    819 /* char *cplus_demangle (const char *mangled, int options)
    820 
    821    If MANGLED is a mangled function name produced by GNU C++, then
    822    a pointer to a @code{malloc}ed string giving a C++ representation
    823    of the name will be returned; otherwise NULL will be returned.
    824    It is the caller's responsibility to free the string which
    825    is returned.
    826 
    827    The OPTIONS arg may contain one or more of the following bits:
    828 
    829    	DMGL_ANSI	ANSI qualifiers such as `const' and `void' are
    830 			included.
    831 	DMGL_PARAMS	Function parameters are included.
    832 
    833    For example,
    834 
    835    cplus_demangle ("foo__1Ai", DMGL_PARAMS)		=> "A::foo(int)"
    836    cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI)	=> "A::foo(int)"
    837    cplus_demangle ("foo__1Ai", 0)			=> "A::foo"
    838 
    839    cplus_demangle ("foo__1Afe", DMGL_PARAMS)		=> "A::foo(float,...)"
    840    cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
    841    cplus_demangle ("foo__1Afe", 0)			=> "A::foo"
    842 
    843    Note that any leading underscores, or other such characters prepended by
    844    the compilation system, are presumed to have already been stripped from
    845    MANGLED.  */
    846 
    847 char *
    848 cplus_demangle (const char *mangled, int options)
    849 {
    850   char *ret;
    851   struct work_stuff work[1];
    852 
    853   if (current_demangling_style == no_demangling)
    854     return xstrdup (mangled);
    855 
    856   memset ((char *) work, 0, sizeof (work));
    857   work->options = options;
    858   if ((work->options & DMGL_STYLE_MASK) == 0)
    859     work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
    860 
    861   /* The V3 ABI demangling is implemented elsewhere.  */
    862   if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
    863     {
    864       ret = cplus_demangle_v3 (mangled, work->options);
    865       if (ret || GNU_V3_DEMANGLING)
    866 	return ret;
    867     }
    868 
    869   if (JAVA_DEMANGLING)
    870     {
    871       ret = java_demangle_v3 (mangled);
    872       if (ret)
    873         return ret;
    874     }
    875 
    876   if (GNAT_DEMANGLING)
    877     return ada_demangle (mangled, options);
    878 
    879   if (DLANG_DEMANGLING)
    880     {
    881       ret = dlang_demangle (mangled, options);
    882       if (ret)
    883 	return ret;
    884     }
    885 
    886   ret = internal_cplus_demangle (work, mangled);
    887   squangle_mop_up (work);
    888   return (ret);
    889 }
    890 
    891 /* Demangle ada names.  The encoding is documented in gcc/ada/exp_dbug.ads.  */
    892 
    893 char *
    894 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
    895 {
    896   int len0;
    897   const char* p;
    898   char *d;
    899   char *demangled;
    900 
    901   /* Discard leading _ada_, which is used for library level subprograms.  */
    902   if (strncmp (mangled, "_ada_", 5) == 0)
    903     mangled += 5;
    904 
    905   /* All ada unit names are lower-case.  */
    906   if (!ISLOWER (mangled[0]))
    907     goto unknown;
    908 
    909   /* Most of the demangling will trivially remove chars.  Operator names
    910      may add one char but because they are always preceeded by '__' which is
    911      replaced by '.', they eventually never expand the size.
    912      A few special names such as '___elabs' add a few chars (at most 7), but
    913      they occur only once.  */
    914   len0 = strlen (mangled) + 7 + 1;
    915   demangled = XNEWVEC (char, len0);
    916 
    917   d = demangled;
    918   p = mangled;
    919   while (1)
    920     {
    921       /* An entity names is expected.  */
    922       if (ISLOWER (*p))
    923         {
    924           /* An identifier, which is always lower case.  */
    925           do
    926             *d++ = *p++;
    927           while (ISLOWER(*p) || ISDIGIT (*p)
    928                  || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
    929         }
    930       else if (p[0] == 'O')
    931         {
    932           /* An operator name.  */
    933           static const char * const operators[][2] =
    934             {{"Oabs", "abs"},  {"Oand", "and"},    {"Omod", "mod"},
    935              {"Onot", "not"},  {"Oor", "or"},      {"Orem", "rem"},
    936              {"Oxor", "xor"},  {"Oeq", "="},       {"One", "/="},
    937              {"Olt", "<"},     {"Ole", "<="},      {"Ogt", ">"},
    938              {"Oge", ">="},    {"Oadd", "+"},      {"Osubtract", "-"},
    939              {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
    940              {"Oexpon", "**"}, {NULL, NULL}};
    941           int k;
    942 
    943           for (k = 0; operators[k][0] != NULL; k++)
    944             {
    945               size_t slen = strlen (operators[k][0]);
    946               if (strncmp (p, operators[k][0], slen) == 0)
    947                 {
    948                   p += slen;
    949                   slen = strlen (operators[k][1]);
    950                   *d++ = '"';
    951                   memcpy (d, operators[k][1], slen);
    952                   d += slen;
    953                   *d++ = '"';
    954                   break;
    955                 }
    956             }
    957           /* Operator not found.  */
    958           if (operators[k][0] == NULL)
    959             goto unknown;
    960         }
    961       else
    962         {
    963           /* Not a GNAT encoding.  */
    964           goto unknown;
    965         }
    966 
    967       /* The name can be directly followed by some uppercase letters.  */
    968       if (p[0] == 'T' && p[1] == 'K')
    969         {
    970           /* Task stuff.  */
    971           if (p[2] == 'B' && p[3] == 0)
    972             {
    973               /* Subprogram for task body.  */
    974               break;
    975             }
    976           else if (p[2] == '_' && p[3] == '_')
    977             {
    978               /* Inner declarations in a task.  */
    979               p += 4;
    980               *d++ = '.';
    981               continue;
    982             }
    983           else
    984             goto unknown;
    985         }
    986       if (p[0] == 'E' && p[1] == 0)
    987         {
    988           /* Exception name.  */
    989           goto unknown;
    990         }
    991       if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
    992         {
    993           /* Protected type subprogram.  */
    994           break;
    995         }
    996       if ((*p == 'N' || *p == 'S') && p[1] == 0)
    997         {
    998           /* Enumerated type name table.  */
    999           goto unknown;
   1000         }
   1001       if (p[0] == 'X')
   1002         {
   1003           /* Body nested.  */
   1004           p++;
   1005           while (p[0] == 'n' || p[0] == 'b')
   1006             p++;
   1007         }
   1008       if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
   1009         {
   1010           /* Stream operations.  */
   1011           const char *name;
   1012           switch (p[1])
   1013             {
   1014             case 'R':
   1015               name = "'Read";
   1016               break;
   1017             case 'W':
   1018               name = "'Write";
   1019               break;
   1020             case 'I':
   1021               name = "'Input";
   1022               break;
   1023             case 'O':
   1024               name = "'Output";
   1025               break;
   1026             default:
   1027               goto unknown;
   1028             }
   1029           p += 2;
   1030           strcpy (d, name);
   1031           d += strlen (name);
   1032         }
   1033       else if (p[0] == 'D')
   1034         {
   1035           /* Controlled type operation.  */
   1036           const char *name;
   1037           switch (p[1])
   1038             {
   1039             case 'F':
   1040               name = ".Finalize";
   1041               break;
   1042             case 'A':
   1043               name = ".Adjust";
   1044               break;
   1045             default:
   1046               goto unknown;
   1047             }
   1048           strcpy (d, name);
   1049           d += strlen (name);
   1050           break;
   1051         }
   1052 
   1053       if (p[0] == '_')
   1054         {
   1055           /* Separator.  */
   1056           if (p[1] == '_')
   1057             {
   1058               /* Standard separator.  Handled first.  */
   1059               p += 2;
   1060 
   1061               if (ISDIGIT (*p))
   1062                 {
   1063                   /* Overloading number.  */
   1064                   do
   1065                     p++;
   1066                   while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
   1067                   if (*p == 'X')
   1068                     {
   1069                       p++;
   1070                       while (p[0] == 'n' || p[0] == 'b')
   1071                         p++;
   1072                     }
   1073                 }
   1074               else if (p[0] == '_' && p[1] != '_')
   1075                 {
   1076                   /* Special names.  */
   1077                   static const char * const special[][2] = {
   1078                     { "_elabb", "'Elab_Body" },
   1079                     { "_elabs", "'Elab_Spec" },
   1080                     { "_size", "'Size" },
   1081                     { "_alignment", "'Alignment" },
   1082                     { "_assign", ".\":=\"" },
   1083                     { NULL, NULL }
   1084                   };
   1085                   int k;
   1086 
   1087                   for (k = 0; special[k][0] != NULL; k++)
   1088                     {
   1089                       size_t slen = strlen (special[k][0]);
   1090                       if (strncmp (p, special[k][0], slen) == 0)
   1091                         {
   1092                           p += slen;
   1093                           slen = strlen (special[k][1]);
   1094                           memcpy (d, special[k][1], slen);
   1095                           d += slen;
   1096                           break;
   1097                         }
   1098                     }
   1099                   if (special[k][0] != NULL)
   1100                     break;
   1101                   else
   1102                     goto unknown;
   1103                 }
   1104               else
   1105                 {
   1106                   *d++ = '.';
   1107                   continue;
   1108                 }
   1109             }
   1110           else if (p[1] == 'B' || p[1] == 'E')
   1111             {
   1112               /* Entry Body or barrier Evaluation.  */
   1113               p += 2;
   1114               while (ISDIGIT (*p))
   1115                 p++;
   1116               if (p[0] == 's' && p[1] == 0)
   1117                 break;
   1118               else
   1119                 goto unknown;
   1120             }
   1121           else
   1122             goto unknown;
   1123         }
   1124 
   1125       if (p[0] == '.' && ISDIGIT (p[1]))
   1126         {
   1127           /* Nested subprogram.  */
   1128           p += 2;
   1129           while (ISDIGIT (*p))
   1130             p++;
   1131         }
   1132       if (*p == 0)
   1133         {
   1134           /* End of mangled name.  */
   1135           break;
   1136         }
   1137       else
   1138         goto unknown;
   1139     }
   1140   *d = 0;
   1141   return demangled;
   1142 
   1143  unknown:
   1144   len0 = strlen (mangled);
   1145   demangled = XNEWVEC (char, len0 + 3);
   1146 
   1147   if (mangled[0] == '<')
   1148      strcpy (demangled, mangled);
   1149   else
   1150     sprintf (demangled, "<%s>", mangled);
   1151 
   1152   return demangled;
   1153 }
   1154 
   1155 /* This function performs most of what cplus_demangle use to do, but
   1156    to be able to demangle a name with a B, K or n code, we need to
   1157    have a longer term memory of what types have been seen. The original
   1158    now initializes and cleans up the squangle code info, while internal
   1159    calls go directly to this routine to avoid resetting that info. */
   1160 
   1161 static char *
   1162 internal_cplus_demangle (struct work_stuff *work, const char *mangled)
   1163 {
   1164 
   1165   string decl;
   1166   int success = 0;
   1167   char *demangled = NULL;
   1168   int s1, s2, s3, s4;
   1169   s1 = work->constructor;
   1170   s2 = work->destructor;
   1171   s3 = work->static_type;
   1172   s4 = work->type_quals;
   1173   work->constructor = work->destructor = 0;
   1174   work->type_quals = TYPE_UNQUALIFIED;
   1175   work->dllimported = 0;
   1176 
   1177   if ((mangled != NULL) && (*mangled != '\0'))
   1178     {
   1179       string_init (&decl);
   1180 
   1181       /* First check to see if gnu style demangling is active and if the
   1182 	 string to be demangled contains a CPLUS_MARKER.  If so, attempt to
   1183 	 recognize one of the gnu special forms rather than looking for a
   1184 	 standard prefix.  In particular, don't worry about whether there
   1185 	 is a "__" string in the mangled string.  Consider "_$_5__foo" for
   1186 	 example.  */
   1187 
   1188       if ((AUTO_DEMANGLING || GNU_DEMANGLING))
   1189 	{
   1190 	  success = gnu_special (work, &mangled, &decl);
   1191 	  if (!success)
   1192 	    {
   1193 	      delete_work_stuff (work);
   1194 	      string_delete (&decl);
   1195 	    }
   1196 	}
   1197       if (!success)
   1198 	{
   1199 	  success = demangle_prefix (work, &mangled, &decl);
   1200 	}
   1201       if (success && (*mangled != '\0'))
   1202 	{
   1203 	  success = demangle_signature (work, &mangled, &decl);
   1204 	}
   1205       if (work->constructor == 2)
   1206         {
   1207           string_prepend (&decl, "global constructors keyed to ");
   1208           work->constructor = 0;
   1209         }
   1210       else if (work->destructor == 2)
   1211         {
   1212           string_prepend (&decl, "global destructors keyed to ");
   1213           work->destructor = 0;
   1214         }
   1215       else if (work->dllimported == 1)
   1216         {
   1217           string_prepend (&decl, "import stub for ");
   1218           work->dllimported = 0;
   1219         }
   1220       demangled = mop_up (work, &decl, success);
   1221     }
   1222   work->constructor = s1;
   1223   work->destructor = s2;
   1224   work->static_type = s3;
   1225   work->type_quals = s4;
   1226   return demangled;
   1227 }
   1228 
   1229 
   1230 /* Clear out and squangling related storage */
   1231 static void
   1232 squangle_mop_up (struct work_stuff *work)
   1233 {
   1234   /* clean up the B and K type mangling types. */
   1235   forget_B_and_K_types (work);
   1236   if (work -> btypevec != NULL)
   1237     {
   1238       free ((char *) work -> btypevec);
   1239       work->btypevec = NULL;
   1240     }
   1241   if (work -> ktypevec != NULL)
   1242     {
   1243       free ((char *) work -> ktypevec);
   1244       work->ktypevec = NULL;
   1245     }
   1246 }
   1247 
   1248 
   1249 /* Copy the work state and storage.  */
   1250 
   1251 static void
   1252 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
   1253 {
   1254   int i;
   1255 
   1256   delete_work_stuff (to);
   1257 
   1258   /* Shallow-copy scalars.  */
   1259   memcpy (to, from, sizeof (*to));
   1260 
   1261   /* Deep-copy dynamic storage.  */
   1262   if (from->typevec_size)
   1263     to->typevec = XNEWVEC (char *, from->typevec_size);
   1264 
   1265   for (i = 0; i < from->ntypes; i++)
   1266     {
   1267       int len = strlen (from->typevec[i]) + 1;
   1268 
   1269       to->typevec[i] = XNEWVEC (char, len);
   1270       memcpy (to->typevec[i], from->typevec[i], len);
   1271     }
   1272 
   1273   if (from->ksize)
   1274     to->ktypevec = XNEWVEC (char *, from->ksize);
   1275 
   1276   for (i = 0; i < from->numk; i++)
   1277     {
   1278       int len = strlen (from->ktypevec[i]) + 1;
   1279 
   1280       to->ktypevec[i] = XNEWVEC (char, len);
   1281       memcpy (to->ktypevec[i], from->ktypevec[i], len);
   1282     }
   1283 
   1284   if (from->bsize)
   1285     to->btypevec = XNEWVEC (char *, from->bsize);
   1286 
   1287   for (i = 0; i < from->numb; i++)
   1288     {
   1289       int len = strlen (from->btypevec[i]) + 1;
   1290 
   1291       to->btypevec[i] = XNEWVEC (char , len);
   1292       memcpy (to->btypevec[i], from->btypevec[i], len);
   1293     }
   1294 
   1295   if (from->ntmpl_args)
   1296     to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
   1297 
   1298   for (i = 0; i < from->ntmpl_args; i++)
   1299     {
   1300       int len = strlen (from->tmpl_argvec[i]) + 1;
   1301 
   1302       to->tmpl_argvec[i] = XNEWVEC (char, len);
   1303       memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
   1304     }
   1305 
   1306   if (from->previous_argument)
   1307     {
   1308       to->previous_argument = XNEW (string);
   1309       string_init (to->previous_argument);
   1310       string_appends (to->previous_argument, from->previous_argument);
   1311     }
   1312 }
   1313 
   1314 
   1315 /* Delete dynamic stuff in work_stuff that is not to be re-used.  */
   1316 
   1317 static void
   1318 delete_non_B_K_work_stuff (struct work_stuff *work)
   1319 {
   1320   /* Discard the remembered types, if any.  */
   1321 
   1322   forget_types (work);
   1323   if (work -> typevec != NULL)
   1324     {
   1325       free ((char *) work -> typevec);
   1326       work -> typevec = NULL;
   1327       work -> typevec_size = 0;
   1328     }
   1329   if (work->tmpl_argvec)
   1330     {
   1331       int i;
   1332 
   1333       for (i = 0; i < work->ntmpl_args; i++)
   1334 	free ((char*) work->tmpl_argvec[i]);
   1335 
   1336       free ((char*) work->tmpl_argvec);
   1337       work->tmpl_argvec = NULL;
   1338     }
   1339   if (work->previous_argument)
   1340     {
   1341       string_delete (work->previous_argument);
   1342       free ((char*) work->previous_argument);
   1343       work->previous_argument = NULL;
   1344     }
   1345 }
   1346 
   1347 
   1348 /* Delete all dynamic storage in work_stuff.  */
   1349 static void
   1350 delete_work_stuff (struct work_stuff *work)
   1351 {
   1352   delete_non_B_K_work_stuff (work);
   1353   squangle_mop_up (work);
   1354 }
   1355 
   1356 
   1357 /* Clear out any mangled storage */
   1358 
   1359 static char *
   1360 mop_up (struct work_stuff *work, string *declp, int success)
   1361 {
   1362   char *demangled = NULL;
   1363 
   1364   delete_non_B_K_work_stuff (work);
   1365 
   1366   /* If demangling was successful, ensure that the demangled string is null
   1367      terminated and return it.  Otherwise, free the demangling decl.  */
   1368 
   1369   if (!success)
   1370     {
   1371       string_delete (declp);
   1372     }
   1373   else
   1374     {
   1375       string_appendn (declp, "", 1);
   1376       demangled = declp->b;
   1377     }
   1378   return (demangled);
   1379 }
   1380 
   1381 /*
   1382 
   1383 LOCAL FUNCTION
   1384 
   1385 	demangle_signature -- demangle the signature part of a mangled name
   1386 
   1387 SYNOPSIS
   1388 
   1389 	static int
   1390 	demangle_signature (struct work_stuff *work, const char **mangled,
   1391 			    string *declp);
   1392 
   1393 DESCRIPTION
   1394 
   1395 	Consume and demangle the signature portion of the mangled name.
   1396 
   1397 	DECLP is the string where demangled output is being built.  At
   1398 	entry it contains the demangled root name from the mangled name
   1399 	prefix.  I.E. either a demangled operator name or the root function
   1400 	name.  In some special cases, it may contain nothing.
   1401 
   1402 	*MANGLED points to the current unconsumed location in the mangled
   1403 	name.  As tokens are consumed and demangling is performed, the
   1404 	pointer is updated to continuously point at the next token to
   1405 	be consumed.
   1406 
   1407 	Demangling GNU style mangled names is nasty because there is no
   1408 	explicit token that marks the start of the outermost function
   1409 	argument list.  */
   1410 
   1411 static int
   1412 demangle_signature (struct work_stuff *work,
   1413                     const char **mangled, string *declp)
   1414 {
   1415   int success = 1;
   1416   int func_done = 0;
   1417   int expect_func = 0;
   1418   int expect_return_type = 0;
   1419   const char *oldmangled = NULL;
   1420   string trawname;
   1421   string tname;
   1422 
   1423   while (success && (**mangled != '\0'))
   1424     {
   1425       switch (**mangled)
   1426 	{
   1427 	case 'Q':
   1428 	  oldmangled = *mangled;
   1429 	  success = demangle_qualified (work, mangled, declp, 1, 0);
   1430 	  if (success)
   1431 	    remember_type (work, oldmangled, *mangled - oldmangled);
   1432 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1433 	    expect_func = 1;
   1434 	  oldmangled = NULL;
   1435 	  break;
   1436 
   1437         case 'K':
   1438 	  oldmangled = *mangled;
   1439 	  success = demangle_qualified (work, mangled, declp, 1, 0);
   1440 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1441 	    {
   1442 	      expect_func = 1;
   1443 	    }
   1444 	  oldmangled = NULL;
   1445 	  break;
   1446 
   1447 	case 'S':
   1448 	  /* Static member function */
   1449 	  if (oldmangled == NULL)
   1450 	    {
   1451 	      oldmangled = *mangled;
   1452 	    }
   1453 	  (*mangled)++;
   1454 	  work -> static_type = 1;
   1455 	  break;
   1456 
   1457 	case 'C':
   1458 	case 'V':
   1459 	case 'u':
   1460 	  work->type_quals |= code_for_qualifier (**mangled);
   1461 
   1462 	  /* a qualified member function */
   1463 	  if (oldmangled == NULL)
   1464 	    oldmangled = *mangled;
   1465 	  (*mangled)++;
   1466 	  break;
   1467 
   1468 	case 'L':
   1469 	  /* Local class name follows after "Lnnn_" */
   1470 	  if (HP_DEMANGLING)
   1471 	    {
   1472 	      while (**mangled && (**mangled != '_'))
   1473 		(*mangled)++;
   1474 	      if (!**mangled)
   1475 		success = 0;
   1476 	      else
   1477 		(*mangled)++;
   1478 	    }
   1479 	  else
   1480 	    success = 0;
   1481 	  break;
   1482 
   1483 	case '0': case '1': case '2': case '3': case '4':
   1484 	case '5': case '6': case '7': case '8': case '9':
   1485 	  if (oldmangled == NULL)
   1486 	    {
   1487 	      oldmangled = *mangled;
   1488 	    }
   1489           work->temp_start = -1; /* uppermost call to demangle_class */
   1490 	  success = demangle_class (work, mangled, declp);
   1491 	  if (success)
   1492 	    {
   1493 	      remember_type (work, oldmangled, *mangled - oldmangled);
   1494 	    }
   1495 	  if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
   1496 	    {
   1497               /* EDG and others will have the "F", so we let the loop cycle
   1498                  if we are looking at one. */
   1499               if (**mangled != 'F')
   1500                  expect_func = 1;
   1501 	    }
   1502 	  oldmangled = NULL;
   1503 	  break;
   1504 
   1505 	case 'B':
   1506 	  {
   1507 	    string s;
   1508 	    success = do_type (work, mangled, &s);
   1509 	    if (success)
   1510 	      {
   1511 		string_append (&s, SCOPE_STRING (work));
   1512 		string_prepends (declp, &s);
   1513 		string_delete (&s);
   1514 	      }
   1515 	    oldmangled = NULL;
   1516 	    expect_func = 1;
   1517 	  }
   1518 	  break;
   1519 
   1520 	case 'F':
   1521 	  /* Function */
   1522 	  /* ARM/HP style demangling includes a specific 'F' character after
   1523 	     the class name.  For GNU style, it is just implied.  So we can
   1524 	     safely just consume any 'F' at this point and be compatible
   1525 	     with either style.  */
   1526 
   1527 	  oldmangled = NULL;
   1528 	  func_done = 1;
   1529 	  (*mangled)++;
   1530 
   1531 	  /* For lucid/ARM/HP style we have to forget any types we might
   1532 	     have remembered up to this point, since they were not argument
   1533 	     types.  GNU style considers all types seen as available for
   1534 	     back references.  See comment in demangle_args() */
   1535 
   1536 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
   1537 	    {
   1538 	      forget_types (work);
   1539 	    }
   1540 	  success = demangle_args (work, mangled, declp);
   1541 	  /* After picking off the function args, we expect to either
   1542 	     find the function return type (preceded by an '_') or the
   1543 	     end of the string. */
   1544 	  if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
   1545 	    {
   1546 	      ++(*mangled);
   1547               /* At this level, we do not care about the return type. */
   1548               success = do_type (work, mangled, &tname);
   1549               string_delete (&tname);
   1550             }
   1551 
   1552 	  break;
   1553 
   1554 	case 't':
   1555 	  /* G++ Template */
   1556 	  string_init(&trawname);
   1557 	  string_init(&tname);
   1558 	  if (oldmangled == NULL)
   1559 	    {
   1560 	      oldmangled = *mangled;
   1561 	    }
   1562 	  success = demangle_template (work, mangled, &tname,
   1563 				       &trawname, 1, 1);
   1564 	  if (success)
   1565 	    {
   1566 	      remember_type (work, oldmangled, *mangled - oldmangled);
   1567 	    }
   1568 	  string_append (&tname, SCOPE_STRING (work));
   1569 
   1570 	  string_prepends(declp, &tname);
   1571 	  if (work -> destructor & 1)
   1572 	    {
   1573 	      string_prepend (&trawname, "~");
   1574 	      string_appends (declp, &trawname);
   1575 	      work->destructor -= 1;
   1576 	    }
   1577 	  if ((work->constructor & 1) || (work->destructor & 1))
   1578 	    {
   1579 	      string_appends (declp, &trawname);
   1580 	      work->constructor -= 1;
   1581 	    }
   1582 	  string_delete(&trawname);
   1583 	  string_delete(&tname);
   1584 	  oldmangled = NULL;
   1585 	  expect_func = 1;
   1586 	  break;
   1587 
   1588 	case '_':
   1589 	  if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
   1590 	    {
   1591 	      /* Read the return type. */
   1592 	      string return_type;
   1593 
   1594 	      (*mangled)++;
   1595 	      success = do_type (work, mangled, &return_type);
   1596 	      APPEND_BLANK (&return_type);
   1597 
   1598 	      string_prepends (declp, &return_type);
   1599 	      string_delete (&return_type);
   1600 	      break;
   1601 	    }
   1602 	  else
   1603 	    /* At the outermost level, we cannot have a return type specified,
   1604 	       so if we run into another '_' at this point we are dealing with
   1605 	       a mangled name that is either bogus, or has been mangled by
   1606 	       some algorithm we don't know how to deal with.  So just
   1607 	       reject the entire demangling.  */
   1608             /* However, "_nnn" is an expected suffix for alternate entry point
   1609                numbered nnn for a function, with HP aCC, so skip over that
   1610                without reporting failure. pai/1997-09-04 */
   1611             if (HP_DEMANGLING)
   1612               {
   1613                 (*mangled)++;
   1614                 while (**mangled && ISDIGIT ((unsigned char)**mangled))
   1615                   (*mangled)++;
   1616               }
   1617             else
   1618 	      success = 0;
   1619 	  break;
   1620 
   1621 	case 'H':
   1622 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1623 	    {
   1624 	      /* A G++ template function.  Read the template arguments. */
   1625 	      success = demangle_template (work, mangled, declp, 0, 0,
   1626 					   0);
   1627 	      if (!(work->constructor & 1))
   1628 		expect_return_type = 1;
   1629 	      (*mangled)++;
   1630 	      break;
   1631 	    }
   1632 	  else
   1633 	    /* fall through */
   1634 	    {;}
   1635 
   1636 	default:
   1637 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1638 	    {
   1639 	      /* Assume we have stumbled onto the first outermost function
   1640 		 argument token, and start processing args.  */
   1641 	      func_done = 1;
   1642 	      success = demangle_args (work, mangled, declp);
   1643 	    }
   1644 	  else
   1645 	    {
   1646 	      /* Non-GNU demanglers use a specific token to mark the start
   1647 		 of the outermost function argument tokens.  Typically 'F',
   1648 		 for ARM/HP-demangling, for example.  So if we find something
   1649 		 we are not prepared for, it must be an error.  */
   1650 	      success = 0;
   1651 	    }
   1652 	  break;
   1653 	}
   1654       /*
   1655 	if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1656 	*/
   1657       {
   1658 	if (success && expect_func)
   1659 	  {
   1660 	    func_done = 1;
   1661               if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
   1662                 {
   1663                   forget_types (work);
   1664                 }
   1665 	    success = demangle_args (work, mangled, declp);
   1666 	    /* Since template include the mangling of their return types,
   1667 	       we must set expect_func to 0 so that we don't try do
   1668 	       demangle more arguments the next time we get here.  */
   1669 	    expect_func = 0;
   1670 	  }
   1671       }
   1672     }
   1673   if (success && !func_done)
   1674     {
   1675       if (AUTO_DEMANGLING || GNU_DEMANGLING)
   1676 	{
   1677 	  /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
   1678 	     bar__3fooi is 'foo::bar(int)'.  We get here when we find the
   1679 	     first case, and need to ensure that the '(void)' gets added to
   1680 	     the current declp.  Note that with ARM/HP, the first case
   1681 	     represents the name of a static data member 'foo::bar',
   1682 	     which is in the current declp, so we leave it alone.  */
   1683 	  success = demangle_args (work, mangled, declp);
   1684 	}
   1685     }
   1686   if (success && PRINT_ARG_TYPES)
   1687     {
   1688       if (work->static_type)
   1689 	string_append (declp, " static");
   1690       if (work->type_quals != TYPE_UNQUALIFIED)
   1691 	{
   1692 	  APPEND_BLANK (declp);
   1693 	  string_append (declp, qualifier_string (work->type_quals));
   1694 	}
   1695     }
   1696 
   1697   return (success);
   1698 }
   1699 
   1700 #if 0
   1701 
   1702 static int
   1703 demangle_method_args (struct work_stuff *work, const char **mangled,
   1704                       string *declp)
   1705 {
   1706   int success = 0;
   1707 
   1708   if (work -> static_type)
   1709     {
   1710       string_append (declp, *mangled + 1);
   1711       *mangled += strlen (*mangled);
   1712       success = 1;
   1713     }
   1714   else
   1715     {
   1716       success = demangle_args (work, mangled, declp);
   1717     }
   1718   return (success);
   1719 }
   1720 
   1721 #endif
   1722 
   1723 static int
   1724 demangle_template_template_parm (struct work_stuff *work,
   1725                                  const char **mangled, string *tname)
   1726 {
   1727   int i;
   1728   int r;
   1729   int need_comma = 0;
   1730   int success = 1;
   1731   string temp;
   1732 
   1733   string_append (tname, "template <");
   1734   /* get size of template parameter list */
   1735   if (get_count (mangled, &r))
   1736     {
   1737       for (i = 0; i < r; i++)
   1738 	{
   1739 	  if (need_comma)
   1740 	    {
   1741 	      string_append (tname, ", ");
   1742 	    }
   1743 
   1744 	    /* Z for type parameters */
   1745 	    if (**mangled == 'Z')
   1746 	      {
   1747 		(*mangled)++;
   1748 		string_append (tname, "class");
   1749 	      }
   1750 	      /* z for template parameters */
   1751 	    else if (**mangled == 'z')
   1752 	      {
   1753 		(*mangled)++;
   1754 		success =
   1755 		  demangle_template_template_parm (work, mangled, tname);
   1756 		if (!success)
   1757 		  {
   1758 		    break;
   1759 		  }
   1760 	      }
   1761 	    else
   1762 	      {
   1763 		/* temp is initialized in do_type */
   1764 		success = do_type (work, mangled, &temp);
   1765 		if (success)
   1766 		  {
   1767 		    string_appends (tname, &temp);
   1768 		  }
   1769 		string_delete(&temp);
   1770 		if (!success)
   1771 		  {
   1772 		    break;
   1773 		  }
   1774 	      }
   1775 	  need_comma = 1;
   1776 	}
   1777 
   1778     }
   1779   if (tname->p[-1] == '>')
   1780     string_append (tname, " ");
   1781   string_append (tname, "> class");
   1782   return (success);
   1783 }
   1784 
   1785 static int
   1786 demangle_expression (struct work_stuff *work, const char **mangled,
   1787                      string *s, type_kind_t tk)
   1788 {
   1789   int need_operator = 0;
   1790   int success;
   1791 
   1792   success = 1;
   1793   string_appendn (s, "(", 1);
   1794   (*mangled)++;
   1795   while (success && **mangled != 'W' && **mangled != '\0')
   1796     {
   1797       if (need_operator)
   1798 	{
   1799 	  size_t i;
   1800 	  size_t len;
   1801 
   1802 	  success = 0;
   1803 
   1804 	  len = strlen (*mangled);
   1805 
   1806 	  for (i = 0; i < ARRAY_SIZE (optable); ++i)
   1807 	    {
   1808 	      size_t l = strlen (optable[i].in);
   1809 
   1810 	      if (l <= len
   1811 		  && memcmp (optable[i].in, *mangled, l) == 0)
   1812 		{
   1813 		  string_appendn (s, " ", 1);
   1814 		  string_append (s, optable[i].out);
   1815 		  string_appendn (s, " ", 1);
   1816 		  success = 1;
   1817 		  (*mangled) += l;
   1818 		  break;
   1819 		}
   1820 	    }
   1821 
   1822 	  if (!success)
   1823 	    break;
   1824 	}
   1825       else
   1826 	need_operator = 1;
   1827 
   1828       success = demangle_template_value_parm (work, mangled, s, tk);
   1829     }
   1830 
   1831   if (**mangled != 'W')
   1832     success = 0;
   1833   else
   1834     {
   1835       string_appendn (s, ")", 1);
   1836       (*mangled)++;
   1837     }
   1838 
   1839   return success;
   1840 }
   1841 
   1842 static int
   1843 demangle_integral_value (struct work_stuff *work,
   1844                          const char **mangled, string *s)
   1845 {
   1846   int success;
   1847 
   1848   if (**mangled == 'E')
   1849     success = demangle_expression (work, mangled, s, tk_integral);
   1850   else if (**mangled == 'Q' || **mangled == 'K')
   1851     success = demangle_qualified (work, mangled, s, 0, 1);
   1852   else
   1853     {
   1854       int value;
   1855 
   1856       /* By default, we let the number decide whether we shall consume an
   1857 	 underscore.  */
   1858       int multidigit_without_leading_underscore = 0;
   1859       int leave_following_underscore = 0;
   1860 
   1861       success = 0;
   1862 
   1863       if (**mangled == '_')
   1864         {
   1865 	  if (mangled[0][1] == 'm')
   1866 	    {
   1867 	      /* Since consume_count_with_underscores does not handle the
   1868 		 `m'-prefix we must do it here, using consume_count and
   1869 		 adjusting underscores: we have to consume the underscore
   1870 		 matching the prepended one.  */
   1871 	      multidigit_without_leading_underscore = 1;
   1872 	      string_appendn (s, "-", 1);
   1873 	      (*mangled) += 2;
   1874 	    }
   1875 	  else
   1876 	    {
   1877 	      /* Do not consume a following underscore;
   1878 	         consume_count_with_underscores will consume what
   1879 	         should be consumed.  */
   1880 	      leave_following_underscore = 1;
   1881 	    }
   1882 	}
   1883       else
   1884 	{
   1885 	  /* Negative numbers are indicated with a leading `m'.  */
   1886 	  if (**mangled == 'm')
   1887 	  {
   1888 	    string_appendn (s, "-", 1);
   1889 	    (*mangled)++;
   1890 	  }
   1891 	  /* Since consume_count_with_underscores does not handle
   1892 	     multi-digit numbers that do not start with an underscore,
   1893 	     and this number can be an integer template parameter,
   1894 	     we have to call consume_count. */
   1895 	  multidigit_without_leading_underscore = 1;
   1896 	  /* These multi-digit numbers never end on an underscore,
   1897 	     so if there is one then don't eat it. */
   1898 	  leave_following_underscore = 1;
   1899 	}
   1900 
   1901       /* We must call consume_count if we expect to remove a trailing
   1902 	 underscore, since consume_count_with_underscores expects
   1903 	 the leading underscore (that we consumed) if it is to handle
   1904 	 multi-digit numbers.  */
   1905       if (multidigit_without_leading_underscore)
   1906 	value = consume_count (mangled);
   1907       else
   1908 	value = consume_count_with_underscores (mangled);
   1909 
   1910       if (value != -1)
   1911 	{
   1912 	  char buf[INTBUF_SIZE];
   1913 	  sprintf (buf, "%d", value);
   1914 	  string_append (s, buf);
   1915 
   1916 	  /* Numbers not otherwise delimited, might have an underscore
   1917 	     appended as a delimeter, which we should skip.
   1918 
   1919 	     ??? This used to always remove a following underscore, which
   1920 	     is wrong.  If other (arbitrary) cases are followed by an
   1921 	     underscore, we need to do something more radical.  */
   1922 
   1923 	  if ((value > 9 || multidigit_without_leading_underscore)
   1924 	      && ! leave_following_underscore
   1925 	      && **mangled == '_')
   1926 	    (*mangled)++;
   1927 
   1928 	  /* All is well.  */
   1929 	  success = 1;
   1930 	}
   1931       }
   1932 
   1933   return success;
   1934 }
   1935 
   1936 /* Demangle the real value in MANGLED.  */
   1937 
   1938 static int
   1939 demangle_real_value (struct work_stuff *work,
   1940                      const char **mangled, string *s)
   1941 {
   1942   if (**mangled == 'E')
   1943     return demangle_expression (work, mangled, s, tk_real);
   1944 
   1945   if (**mangled == 'm')
   1946     {
   1947       string_appendn (s, "-", 1);
   1948       (*mangled)++;
   1949     }
   1950   while (ISDIGIT ((unsigned char)**mangled))
   1951     {
   1952       string_appendn (s, *mangled, 1);
   1953       (*mangled)++;
   1954     }
   1955   if (**mangled == '.') /* fraction */
   1956     {
   1957       string_appendn (s, ".", 1);
   1958       (*mangled)++;
   1959       while (ISDIGIT ((unsigned char)**mangled))
   1960 	{
   1961 	  string_appendn (s, *mangled, 1);
   1962 	  (*mangled)++;
   1963 	}
   1964     }
   1965   if (**mangled == 'e') /* exponent */
   1966     {
   1967       string_appendn (s, "e", 1);
   1968       (*mangled)++;
   1969       while (ISDIGIT ((unsigned char)**mangled))
   1970 	{
   1971 	  string_appendn (s, *mangled, 1);
   1972 	  (*mangled)++;
   1973 	}
   1974     }
   1975 
   1976   return 1;
   1977 }
   1978 
   1979 static int
   1980 demangle_template_value_parm (struct work_stuff *work, const char **mangled,
   1981                               string *s, type_kind_t tk)
   1982 {
   1983   int success = 1;
   1984 
   1985   if (**mangled == 'Y')
   1986     {
   1987       /* The next argument is a template parameter. */
   1988       int idx;
   1989 
   1990       (*mangled)++;
   1991       idx = consume_count_with_underscores (mangled);
   1992       if (idx == -1
   1993 	  || (work->tmpl_argvec && idx >= work->ntmpl_args)
   1994 	  || consume_count_with_underscores (mangled) == -1)
   1995 	return -1;
   1996       if (work->tmpl_argvec)
   1997 	string_append (s, work->tmpl_argvec[idx]);
   1998       else
   1999 	string_append_template_idx (s, idx);
   2000     }
   2001   else if (tk == tk_integral)
   2002     success = demangle_integral_value (work, mangled, s);
   2003   else if (tk == tk_char)
   2004     {
   2005       char tmp[2];
   2006       int val;
   2007       if (**mangled == 'm')
   2008 	{
   2009 	  string_appendn (s, "-", 1);
   2010 	  (*mangled)++;
   2011 	}
   2012       string_appendn (s, "'", 1);
   2013       val = consume_count(mangled);
   2014       if (val <= 0)
   2015 	success = 0;
   2016       else
   2017 	{
   2018 	  tmp[0] = (char)val;
   2019 	  tmp[1] = '\0';
   2020 	  string_appendn (s, &tmp[0], 1);
   2021 	  string_appendn (s, "'", 1);
   2022 	}
   2023     }
   2024   else if (tk == tk_bool)
   2025     {
   2026       int val = consume_count (mangled);
   2027       if (val == 0)
   2028 	string_appendn (s, "false", 5);
   2029       else if (val == 1)
   2030 	string_appendn (s, "true", 4);
   2031       else
   2032 	success = 0;
   2033     }
   2034   else if (tk == tk_real)
   2035     success = demangle_real_value (work, mangled, s);
   2036   else if (tk == tk_pointer || tk == tk_reference)
   2037     {
   2038       if (**mangled == 'Q')
   2039 	success = demangle_qualified (work, mangled, s,
   2040 				      /*isfuncname=*/0,
   2041 				      /*append=*/1);
   2042       else
   2043 	{
   2044 	  int symbol_len  = consume_count (mangled);
   2045 	  if (symbol_len == -1)
   2046 	    return -1;
   2047 	  if (symbol_len == 0)
   2048 	    string_appendn (s, "0", 1);
   2049 	  else
   2050 	    {
   2051 	      char *p = XNEWVEC (char, symbol_len + 1), *q;
   2052 	      strncpy (p, *mangled, symbol_len);
   2053 	      p [symbol_len] = '\0';
   2054 	      /* We use cplus_demangle here, rather than
   2055 		 internal_cplus_demangle, because the name of the entity
   2056 		 mangled here does not make use of any of the squangling
   2057 		 or type-code information we have built up thus far; it is
   2058 		 mangled independently.  */
   2059 	      q = cplus_demangle (p, work->options);
   2060 	      if (tk == tk_pointer)
   2061 		string_appendn (s, "&", 1);
   2062 	      /* FIXME: Pointer-to-member constants should get a
   2063 		 qualifying class name here.  */
   2064 	      if (q)
   2065 		{
   2066 		  string_append (s, q);
   2067 		  free (q);
   2068 		}
   2069 	      else
   2070 		string_append (s, p);
   2071 	      free (p);
   2072 	    }
   2073 	  *mangled += symbol_len;
   2074 	}
   2075     }
   2076 
   2077   return success;
   2078 }
   2079 
   2080 /* Demangle the template name in MANGLED.  The full name of the
   2081    template (e.g., S<int>) is placed in TNAME.  The name without the
   2082    template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
   2083    non-NULL.  If IS_TYPE is nonzero, this template is a type template,
   2084    not a function template.  If both IS_TYPE and REMEMBER are nonzero,
   2085    the template is remembered in the list of back-referenceable
   2086    types.  */
   2087 
   2088 static int
   2089 demangle_template (struct work_stuff *work, const char **mangled,
   2090                    string *tname, string *trawname,
   2091                    int is_type, int remember)
   2092 {
   2093   int i;
   2094   int r;
   2095   int need_comma = 0;
   2096   int success = 0;
   2097   int is_java_array = 0;
   2098   string temp;
   2099 
   2100   (*mangled)++;
   2101   if (is_type)
   2102     {
   2103       /* get template name */
   2104       if (**mangled == 'z')
   2105 	{
   2106 	  int idx;
   2107 	  (*mangled)++;
   2108 	  (*mangled)++;
   2109 
   2110 	  idx = consume_count_with_underscores (mangled);
   2111 	  if (idx == -1
   2112 	      || (work->tmpl_argvec && idx >= work->ntmpl_args)
   2113 	      || consume_count_with_underscores (mangled) == -1)
   2114 	    return (0);
   2115 
   2116 	  if (work->tmpl_argvec)
   2117 	    {
   2118 	      string_append (tname, work->tmpl_argvec[idx]);
   2119 	      if (trawname)
   2120 		string_append (trawname, work->tmpl_argvec[idx]);
   2121 	    }
   2122 	  else
   2123 	    {
   2124 	      string_append_template_idx (tname, idx);
   2125 	      if (trawname)
   2126 		string_append_template_idx (trawname, idx);
   2127 	    }
   2128 	}
   2129       else
   2130 	{
   2131 	  if ((r = consume_count (mangled)) <= 0
   2132 	      || (int) strlen (*mangled) < r)
   2133 	    {
   2134 	      return (0);
   2135 	    }
   2136 	  is_java_array = (work -> options & DMGL_JAVA)
   2137 	    && strncmp (*mangled, "JArray1Z", 8) == 0;
   2138 	  if (! is_java_array)
   2139 	    {
   2140 	      string_appendn (tname, *mangled, r);
   2141 	    }
   2142 	  if (trawname)
   2143 	    string_appendn (trawname, *mangled, r);
   2144 	  *mangled += r;
   2145 	}
   2146     }
   2147   if (!is_java_array)
   2148     string_append (tname, "<");
   2149   /* get size of template parameter list */
   2150   if (!get_count (mangled, &r))
   2151     {
   2152       return (0);
   2153     }
   2154   if (!is_type)
   2155     {
   2156       /* Create an array for saving the template argument values. */
   2157       work->tmpl_argvec = XNEWVEC (char *, r);
   2158       work->ntmpl_args = r;
   2159       for (i = 0; i < r; i++)
   2160 	work->tmpl_argvec[i] = 0;
   2161     }
   2162   for (i = 0; i < r; i++)
   2163     {
   2164       if (need_comma)
   2165 	{
   2166 	  string_append (tname, ", ");
   2167 	}
   2168       /* Z for type parameters */
   2169       if (**mangled == 'Z')
   2170 	{
   2171 	  (*mangled)++;
   2172 	  /* temp is initialized in do_type */
   2173 	  success = do_type (work, mangled, &temp);
   2174 	  if (success)
   2175 	    {
   2176 	      string_appends (tname, &temp);
   2177 
   2178 	      if (!is_type)
   2179 		{
   2180 		  /* Save the template argument. */
   2181 		  int len = temp.p - temp.b;
   2182 		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
   2183 		  memcpy (work->tmpl_argvec[i], temp.b, len);
   2184 		  work->tmpl_argvec[i][len] = '\0';
   2185 		}
   2186 	    }
   2187 	  string_delete(&temp);
   2188 	  if (!success)
   2189 	    {
   2190 	      break;
   2191 	    }
   2192 	}
   2193       /* z for template parameters */
   2194       else if (**mangled == 'z')
   2195 	{
   2196 	  int r2;
   2197 	  (*mangled)++;
   2198 	  success = demangle_template_template_parm (work, mangled, tname);
   2199 
   2200 	  if (success
   2201 	      && (r2 = consume_count (mangled)) > 0
   2202 	      && (int) strlen (*mangled) >= r2)
   2203 	    {
   2204 	      string_append (tname, " ");
   2205 	      string_appendn (tname, *mangled, r2);
   2206 	      if (!is_type)
   2207 		{
   2208 		  /* Save the template argument. */
   2209 		  int len = r2;
   2210 		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
   2211 		  memcpy (work->tmpl_argvec[i], *mangled, len);
   2212 		  work->tmpl_argvec[i][len] = '\0';
   2213 		}
   2214 	      *mangled += r2;
   2215 	    }
   2216 	  if (!success)
   2217 	    {
   2218 	      break;
   2219 	    }
   2220 	}
   2221       else
   2222 	{
   2223 	  string  param;
   2224 	  string* s;
   2225 
   2226 	  /* otherwise, value parameter */
   2227 
   2228 	  /* temp is initialized in do_type */
   2229 	  success = do_type (work, mangled, &temp);
   2230 	  string_delete(&temp);
   2231 	  if (!success)
   2232 	    break;
   2233 
   2234 	  if (!is_type)
   2235 	    {
   2236 	      s = &param;
   2237 	      string_init (s);
   2238 	    }
   2239 	  else
   2240 	    s = tname;
   2241 
   2242 	  success = demangle_template_value_parm (work, mangled, s,
   2243 						  (type_kind_t) success);
   2244 
   2245 	  if (!success)
   2246 	    {
   2247 	      if (!is_type)
   2248 		string_delete (s);
   2249 	      success = 0;
   2250 	      break;
   2251 	    }
   2252 
   2253 	  if (!is_type)
   2254 	    {
   2255 	      int len = s->p - s->b;
   2256 	      work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
   2257 	      memcpy (work->tmpl_argvec[i], s->b, len);
   2258 	      work->tmpl_argvec[i][len] = '\0';
   2259 
   2260 	      string_appends (tname, s);
   2261 	      string_delete (s);
   2262 	    }
   2263 	}
   2264       need_comma = 1;
   2265     }
   2266   if (is_java_array)
   2267     {
   2268       string_append (tname, "[]");
   2269     }
   2270   else
   2271     {
   2272       if (tname->p[-1] == '>')
   2273 	string_append (tname, " ");
   2274       string_append (tname, ">");
   2275     }
   2276 
   2277   if (is_type && remember)
   2278     {
   2279       const int bindex = register_Btype (work);
   2280       remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
   2281     }
   2282 
   2283   /*
   2284     if (work -> static_type)
   2285     {
   2286     string_append (declp, *mangled + 1);
   2287     *mangled += strlen (*mangled);
   2288     success = 1;
   2289     }
   2290     else
   2291     {
   2292     success = demangle_args (work, mangled, declp);
   2293     }
   2294     }
   2295     */
   2296   return (success);
   2297 }
   2298 
   2299 static int
   2300 arm_pt (struct work_stuff *work, const char *mangled,
   2301         int n, const char **anchor, const char **args)
   2302 {
   2303   /* Check if ARM template with "__pt__" in it ("parameterized type") */
   2304   /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
   2305   if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
   2306     {
   2307       int len;
   2308       *args = *anchor + 6;
   2309       len = consume_count (args);
   2310       if (len == -1)
   2311 	return 0;
   2312       if (*args + len == mangled + n && **args == '_')
   2313 	{
   2314 	  ++*args;
   2315 	  return 1;
   2316 	}
   2317     }
   2318   if (AUTO_DEMANGLING || EDG_DEMANGLING)
   2319     {
   2320       if ((*anchor = strstr (mangled, "__tm__"))
   2321           || (*anchor = strstr (mangled, "__ps__"))
   2322           || (*anchor = strstr (mangled, "__pt__")))
   2323         {
   2324           int len;
   2325           *args = *anchor + 6;
   2326           len = consume_count (args);
   2327 	  if (len == -1)
   2328 	    return 0;
   2329           if (*args + len == mangled + n && **args == '_')
   2330             {
   2331               ++*args;
   2332               return 1;
   2333             }
   2334         }
   2335       else if ((*anchor = strstr (mangled, "__S")))
   2336         {
   2337  	  int len;
   2338  	  *args = *anchor + 3;
   2339  	  len = consume_count (args);
   2340 	  if (len == -1)
   2341 	    return 0;
   2342  	  if (*args + len == mangled + n && **args == '_')
   2343             {
   2344               ++*args;
   2345  	      return 1;
   2346             }
   2347         }
   2348     }
   2349 
   2350   return 0;
   2351 }
   2352 
   2353 static void
   2354 demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
   2355                           int n, string *declp)
   2356 {
   2357   const char *p;
   2358   const char *args;
   2359   const char *e = *mangled + n;
   2360   string arg;
   2361 
   2362   /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
   2363      template args */
   2364   if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
   2365     {
   2366       char *start_spec_args = NULL;
   2367       int hold_options;
   2368 
   2369       /* First check for and omit template specialization pseudo-arguments,
   2370          such as in "Spec<#1,#1.*>" */
   2371       start_spec_args = strchr (*mangled, '<');
   2372       if (start_spec_args && (start_spec_args - *mangled < n))
   2373         string_appendn (declp, *mangled, start_spec_args - *mangled);
   2374       else
   2375         string_appendn (declp, *mangled, n);
   2376       (*mangled) += n + 1;
   2377       string_init (&arg);
   2378       if (work->temp_start == -1) /* non-recursive call */
   2379         work->temp_start = declp->p - declp->b;
   2380 
   2381       /* We want to unconditionally demangle parameter types in
   2382 	 template parameters.  */
   2383       hold_options = work->options;
   2384       work->options |= DMGL_PARAMS;
   2385 
   2386       string_append (declp, "<");
   2387       while (1)
   2388         {
   2389           string_delete (&arg);
   2390           switch (**mangled)
   2391             {
   2392               case 'T':
   2393                 /* 'T' signals a type parameter */
   2394                 (*mangled)++;
   2395                 if (!do_type (work, mangled, &arg))
   2396                   goto hpacc_template_args_done;
   2397                 break;
   2398 
   2399               case 'U':
   2400               case 'S':
   2401                 /* 'U' or 'S' signals an integral value */
   2402                 if (!do_hpacc_template_const_value (work, mangled, &arg))
   2403                   goto hpacc_template_args_done;
   2404                 break;
   2405 
   2406               case 'A':
   2407                 /* 'A' signals a named constant expression (literal) */
   2408                 if (!do_hpacc_template_literal (work, mangled, &arg))
   2409                   goto hpacc_template_args_done;
   2410                 break;
   2411 
   2412               default:
   2413                 /* Today, 1997-09-03, we have only the above types
   2414                    of template parameters */
   2415                 /* FIXME: maybe this should fail and return null */
   2416                 goto hpacc_template_args_done;
   2417             }
   2418           string_appends (declp, &arg);
   2419          /* Check if we're at the end of template args.
   2420              0 if at end of static member of template class,
   2421              _ if done with template args for a function */
   2422           if ((**mangled == '\000') || (**mangled == '_'))
   2423             break;
   2424           else
   2425             string_append (declp, ",");
   2426         }
   2427     hpacc_template_args_done:
   2428       string_append (declp, ">");
   2429       string_delete (&arg);
   2430       if (**mangled == '_')
   2431         (*mangled)++;
   2432       work->options = hold_options;
   2433       return;
   2434     }
   2435   /* ARM template? (Also handles HP cfront extensions) */
   2436   else if (arm_pt (work, *mangled, n, &p, &args))
   2437     {
   2438       int hold_options;
   2439       string type_str;
   2440 
   2441       string_init (&arg);
   2442       string_appendn (declp, *mangled, p - *mangled);
   2443       if (work->temp_start == -1)  /* non-recursive call */
   2444 	work->temp_start = declp->p - declp->b;
   2445 
   2446       /* We want to unconditionally demangle parameter types in
   2447 	 template parameters.  */
   2448       hold_options = work->options;
   2449       work->options |= DMGL_PARAMS;
   2450 
   2451       string_append (declp, "<");
   2452       /* should do error checking here */
   2453       while (args < e) {
   2454 	string_delete (&arg);
   2455 
   2456 	/* Check for type or literal here */
   2457 	switch (*args)
   2458 	  {
   2459 	    /* HP cfront extensions to ARM for template args */
   2460 	    /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
   2461 	    /* FIXME: We handle only numeric literals for HP cfront */
   2462           case 'X':
   2463             /* A typed constant value follows */
   2464             args++;
   2465             if (!do_type (work, &args, &type_str))
   2466 	      goto cfront_template_args_done;
   2467             string_append (&arg, "(");
   2468             string_appends (&arg, &type_str);
   2469             string_delete (&type_str);
   2470             string_append (&arg, ")");
   2471             if (*args != 'L')
   2472               goto cfront_template_args_done;
   2473             args++;
   2474             /* Now snarf a literal value following 'L' */
   2475             if (!snarf_numeric_literal (&args, &arg))
   2476 	      goto cfront_template_args_done;
   2477             break;
   2478 
   2479           case 'L':
   2480             /* Snarf a literal following 'L' */
   2481             args++;
   2482             if (!snarf_numeric_literal (&args, &arg))
   2483 	      goto cfront_template_args_done;
   2484             break;
   2485           default:
   2486             /* Not handling other HP cfront stuff */
   2487             {
   2488               const char* old_args = args;
   2489               if (!do_type (work, &args, &arg))
   2490                 goto cfront_template_args_done;
   2491 
   2492               /* Fail if we didn't make any progress: prevent infinite loop. */
   2493               if (args == old_args)
   2494 		{
   2495 		  work->options = hold_options;
   2496 		  return;
   2497 		}
   2498             }
   2499 	  }
   2500 	string_appends (declp, &arg);
   2501 	string_append (declp, ",");
   2502       }
   2503     cfront_template_args_done:
   2504       string_delete (&arg);
   2505       if (args >= e)
   2506 	--declp->p; /* remove extra comma */
   2507       string_append (declp, ">");
   2508       work->options = hold_options;
   2509     }
   2510   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
   2511 	   && (*mangled)[9] == 'N'
   2512 	   && (*mangled)[8] == (*mangled)[10]
   2513 	   && strchr (cplus_markers, (*mangled)[8]))
   2514     {
   2515       /* A member of the anonymous namespace.  */
   2516       string_append (declp, "{anonymous}");
   2517     }
   2518   else
   2519     {
   2520       if (work->temp_start == -1) /* non-recursive call only */
   2521 	work->temp_start = 0;     /* disable in recursive calls */
   2522       string_appendn (declp, *mangled, n);
   2523     }
   2524   *mangled += n;
   2525 }
   2526 
   2527 /* Extract a class name, possibly a template with arguments, from the
   2528    mangled string; qualifiers, local class indicators, etc. have
   2529    already been dealt with */
   2530 
   2531 static int
   2532 demangle_class_name (struct work_stuff *work, const char **mangled,
   2533                      string *declp)
   2534 {
   2535   int n;
   2536   int success = 0;
   2537 
   2538   n = consume_count (mangled);
   2539   if (n == -1)
   2540     return 0;
   2541   if ((int) strlen (*mangled) >= n)
   2542     {
   2543       demangle_arm_hp_template (work, mangled, n, declp);
   2544       success = 1;
   2545     }
   2546 
   2547   return (success);
   2548 }
   2549 
   2550 /*
   2551 
   2552 LOCAL FUNCTION
   2553 
   2554 	demangle_class -- demangle a mangled class sequence
   2555 
   2556 SYNOPSIS
   2557 
   2558 	static int
   2559 	demangle_class (struct work_stuff *work, const char **mangled,
   2560 			strint *declp)
   2561 
   2562 DESCRIPTION
   2563 
   2564 	DECLP points to the buffer into which demangling is being done.
   2565 
   2566 	*MANGLED points to the current token to be demangled.  On input,
   2567 	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
   2568 	On exit, it points to the next token after the mangled class on
   2569 	success, or the first unconsumed token on failure.
   2570 
   2571 	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
   2572 	we are demangling a constructor or destructor.  In this case
   2573 	we prepend "class::class" or "class::~class" to DECLP.
   2574 
   2575 	Otherwise, we prepend "class::" to the current DECLP.
   2576 
   2577 	Reset the constructor/destructor flags once they have been
   2578 	"consumed".  This allows demangle_class to be called later during
   2579 	the same demangling, to do normal class demangling.
   2580 
   2581 	Returns 1 if demangling is successful, 0 otherwise.
   2582 
   2583 */
   2584 
   2585 static int
   2586 demangle_class (struct work_stuff *work, const char **mangled, string *declp)
   2587 {
   2588   int success = 0;
   2589   int btype;
   2590   string class_name;
   2591   char *save_class_name_end = 0;
   2592 
   2593   string_init (&class_name);
   2594   btype = register_Btype (work);
   2595   if (demangle_class_name (work, mangled, &class_name))
   2596     {
   2597       save_class_name_end = class_name.p;
   2598       if ((work->constructor & 1) || (work->destructor & 1))
   2599 	{
   2600           /* adjust so we don't include template args */
   2601           if (work->temp_start && (work->temp_start != -1))
   2602             {
   2603               class_name.p = class_name.b + work->temp_start;
   2604             }
   2605 	  string_prepends (declp, &class_name);
   2606 	  if (work -> destructor & 1)
   2607 	    {
   2608 	      string_prepend (declp, "~");
   2609               work -> destructor -= 1;
   2610 	    }
   2611 	  else
   2612 	    {
   2613 	      work -> constructor -= 1;
   2614 	    }
   2615 	}
   2616       class_name.p = save_class_name_end;
   2617       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
   2618       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
   2619       string_prepend (declp, SCOPE_STRING (work));
   2620       string_prepends (declp, &class_name);
   2621       success = 1;
   2622     }
   2623   string_delete (&class_name);
   2624   return (success);
   2625 }
   2626 
   2627 
   2628 /* Called when there's a "__" in the mangled name, with `scan' pointing to
   2629    the rightmost guess.
   2630 
   2631    Find the correct "__"-sequence where the function name ends and the
   2632    signature starts, which is ambiguous with GNU mangling.
   2633    Call demangle_signature here, so we can make sure we found the right
   2634    one; *mangled will be consumed so caller will not make further calls to
   2635    demangle_signature.  */
   2636 
   2637 static int
   2638 iterate_demangle_function (struct work_stuff *work, const char **mangled,
   2639                            string *declp, const char *scan)
   2640 {
   2641   const char *mangle_init = *mangled;
   2642   int success = 0;
   2643   string decl_init;
   2644   struct work_stuff work_init;
   2645 
   2646   if (*(scan + 2) == '\0')
   2647     return 0;
   2648 
   2649   /* Do not iterate for some demangling modes, or if there's only one
   2650      "__"-sequence.  This is the normal case.  */
   2651   if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
   2652       || strstr (scan + 2, "__") == NULL)
   2653     return demangle_function_name (work, mangled, declp, scan);
   2654 
   2655   /* Save state so we can restart if the guess at the correct "__" was
   2656      wrong.  */
   2657   string_init (&decl_init);
   2658   string_appends (&decl_init, declp);
   2659   memset (&work_init, 0, sizeof work_init);
   2660   work_stuff_copy_to_from (&work_init, work);
   2661 
   2662   /* Iterate over occurrences of __, allowing names and types to have a
   2663      "__" sequence in them.  We must start with the first (not the last)
   2664      occurrence, since "__" most often occur between independent mangled
   2665      parts, hence starting at the last occurence inside a signature
   2666      might get us a "successful" demangling of the signature.  */
   2667 
   2668   while (scan[2])
   2669     {
   2670       if (demangle_function_name (work, mangled, declp, scan))
   2671 	{
   2672 	  success = demangle_signature (work, mangled, declp);
   2673 	  if (success)
   2674 	    break;
   2675 	}
   2676 
   2677       /* Reset demangle state for the next round.  */
   2678       *mangled = mangle_init;
   2679       string_clear (declp);
   2680       string_appends (declp, &decl_init);
   2681       work_stuff_copy_to_from (work, &work_init);
   2682 
   2683       /* Leave this underscore-sequence.  */
   2684       scan += 2;
   2685 
   2686       /* Scan for the next "__" sequence.  */
   2687       while (*scan && (scan[0] != '_' || scan[1] != '_'))
   2688 	scan++;
   2689 
   2690       /* Move to last "__" in this sequence.  */
   2691       while (*scan && *scan == '_')
   2692 	scan++;
   2693       scan -= 2;
   2694     }
   2695 
   2696   /* Delete saved state.  */
   2697   delete_work_stuff (&work_init);
   2698   string_delete (&decl_init);
   2699 
   2700   return success;
   2701 }
   2702 
   2703 /*
   2704 
   2705 LOCAL FUNCTION
   2706 
   2707 	demangle_prefix -- consume the mangled name prefix and find signature
   2708 
   2709 SYNOPSIS
   2710 
   2711 	static int
   2712 	demangle_prefix (struct work_stuff *work, const char **mangled,
   2713 			 string *declp);
   2714 
   2715 DESCRIPTION
   2716 
   2717 	Consume and demangle the prefix of the mangled name.
   2718 	While processing the function name root, arrange to call
   2719 	demangle_signature if the root is ambiguous.
   2720 
   2721 	DECLP points to the string buffer into which demangled output is
   2722 	placed.  On entry, the buffer is empty.  On exit it contains
   2723 	the root function name, the demangled operator name, or in some
   2724 	special cases either nothing or the completely demangled result.
   2725 
   2726 	MANGLED points to the current pointer into the mangled name.  As each
   2727 	token of the mangled name is consumed, it is updated.  Upon entry
   2728 	the current mangled name pointer points to the first character of
   2729 	the mangled name.  Upon exit, it should point to the first character
   2730 	of the signature if demangling was successful, or to the first
   2731 	unconsumed character if demangling of the prefix was unsuccessful.
   2732 
   2733 	Returns 1 on success, 0 otherwise.
   2734  */
   2735 
   2736 static int
   2737 demangle_prefix (struct work_stuff *work, const char **mangled,
   2738                  string *declp)
   2739 {
   2740   int success = 1;
   2741   const char *scan;
   2742   int i;
   2743 
   2744   if (strlen(*mangled) > 6
   2745       && (strncmp(*mangled, "_imp__", 6) == 0
   2746           || strncmp(*mangled, "__imp_", 6) == 0))
   2747     {
   2748       /* it's a symbol imported from a PE dynamic library. Check for both
   2749          new style prefix _imp__ and legacy __imp_ used by older versions
   2750 	 of dlltool. */
   2751       (*mangled) += 6;
   2752       work->dllimported = 1;
   2753     }
   2754   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
   2755     {
   2756       char *marker = strchr (cplus_markers, (*mangled)[8]);
   2757       if (marker != NULL && *marker == (*mangled)[10])
   2758 	{
   2759 	  if ((*mangled)[9] == 'D')
   2760 	    {
   2761 	      /* it's a GNU global destructor to be executed at program exit */
   2762 	      (*mangled) += 11;
   2763 	      work->destructor = 2;
   2764 	      if (gnu_special (work, mangled, declp))
   2765 		return success;
   2766 	    }
   2767 	  else if ((*mangled)[9] == 'I')
   2768 	    {
   2769 	      /* it's a GNU global constructor to be executed at program init */
   2770 	      (*mangled) += 11;
   2771 	      work->constructor = 2;
   2772 	      if (gnu_special (work, mangled, declp))
   2773 		return success;
   2774 	    }
   2775 	}
   2776     }
   2777   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
   2778     {
   2779       /* it's a ARM global destructor to be executed at program exit */
   2780       (*mangled) += 7;
   2781       work->destructor = 2;
   2782     }
   2783   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
   2784     {
   2785       /* it's a ARM global constructor to be executed at program initial */
   2786       (*mangled) += 7;
   2787       work->constructor = 2;
   2788     }
   2789 
   2790   /*  This block of code is a reduction in strength time optimization
   2791       of:
   2792       scan = strstr (*mangled, "__"); */
   2793 
   2794   {
   2795     scan = *mangled;
   2796 
   2797     do {
   2798       scan = strchr (scan, '_');
   2799     } while (scan != NULL && *++scan != '_');
   2800 
   2801     if (scan != NULL) --scan;
   2802   }
   2803 
   2804   if (scan != NULL)
   2805     {
   2806       /* We found a sequence of two or more '_', ensure that we start at
   2807 	 the last pair in the sequence.  */
   2808       i = strspn (scan, "_");
   2809       if (i > 2)
   2810 	{
   2811 	  scan += (i - 2);
   2812 	}
   2813     }
   2814 
   2815   if (scan == NULL)
   2816     {
   2817       success = 0;
   2818     }
   2819   else if (work -> static_type)
   2820     {
   2821       if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
   2822 	{
   2823 	  success = 0;
   2824 	}
   2825     }
   2826   else if ((scan == *mangled)
   2827 	   && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
   2828 	       || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
   2829     {
   2830       /* The ARM says nothing about the mangling of local variables.
   2831 	 But cfront mangles local variables by prepending __<nesting_level>
   2832 	 to them. As an extension to ARM demangling we handle this case.  */
   2833       if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
   2834 	  && ISDIGIT ((unsigned char)scan[2]))
   2835 	{
   2836 	  *mangled = scan + 2;
   2837 	  consume_count (mangled);
   2838 	  string_append (declp, *mangled);
   2839 	  *mangled += strlen (*mangled);
   2840 	  success = 1;
   2841 	}
   2842       else
   2843 	{
   2844 	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
   2845 	     names like __Q2_3foo3bar for nested type names.  So don't accept
   2846 	     this style of constructor for cfront demangling.  A GNU
   2847 	     style member-template constructor starts with 'H'. */
   2848 	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
   2849 	    work -> constructor += 1;
   2850 	  *mangled = scan + 2;
   2851 	}
   2852     }
   2853   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
   2854     {
   2855       /* Cfront-style parameterized type.  Handled later as a signature. */
   2856       success = 1;
   2857 
   2858       /* ARM template? */
   2859       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
   2860     }
   2861   else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
   2862                               || (scan[2] == 'p' && scan[3] == 's')
   2863                               || (scan[2] == 'p' && scan[3] == 't')))
   2864     {
   2865       /* EDG-style parameterized type.  Handled later as a signature. */
   2866       success = 1;
   2867 
   2868       /* EDG template? */
   2869       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
   2870     }
   2871   else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
   2872 	   && (scan[2] != 't'))
   2873     {
   2874       /* Mangled name starts with "__".  Skip over any leading '_' characters,
   2875 	 then find the next "__" that separates the prefix from the signature.
   2876 	 */
   2877       if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
   2878 	  || (arm_special (mangled, declp) == 0))
   2879 	{
   2880 	  while (*scan == '_')
   2881 	    {
   2882 	      scan++;
   2883 	    }
   2884 	  if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
   2885 	    {
   2886 	      /* No separator (I.E. "__not_mangled"), or empty signature
   2887 		 (I.E. "__not_mangled_either__") */
   2888 	      success = 0;
   2889 	    }
   2890 	  else
   2891 	    return iterate_demangle_function (work, mangled, declp, scan);
   2892 	}
   2893     }
   2894   else if (*(scan + 2) != '\0')
   2895     {
   2896       /* Mangled name does not start with "__" but does have one somewhere
   2897 	 in there with non empty stuff after it.  Looks like a global
   2898 	 function name.  Iterate over all "__":s until the right
   2899 	 one is found.  */
   2900       return iterate_demangle_function (work, mangled, declp, scan);
   2901     }
   2902   else
   2903     {
   2904       /* Doesn't look like a mangled name */
   2905       success = 0;
   2906     }
   2907 
   2908   if (!success && (work->constructor == 2 || work->destructor == 2))
   2909     {
   2910       string_append (declp, *mangled);
   2911       *mangled += strlen (*mangled);
   2912       success = 1;
   2913     }
   2914   return (success);
   2915 }
   2916 
   2917 /*
   2918 
   2919 LOCAL FUNCTION
   2920 
   2921 	gnu_special -- special handling of gnu mangled strings
   2922 
   2923 SYNOPSIS
   2924 
   2925 	static int
   2926 	gnu_special (struct work_stuff *work, const char **mangled,
   2927 		     string *declp);
   2928 
   2929 
   2930 DESCRIPTION
   2931 
   2932 	Process some special GNU style mangling forms that don't fit
   2933 	the normal pattern.  For example:
   2934 
   2935 		_$_3foo		(destructor for class foo)
   2936 		_vt$foo		(foo virtual table)
   2937 		_vt$foo$bar	(foo::bar virtual table)
   2938 		__vt_foo	(foo virtual table, new style with thunks)
   2939 		_3foo$varname	(static data member)
   2940 		_Q22rs2tu$vw	(static data member)
   2941 		__t6vector1Zii	(constructor with template)
   2942 		__thunk_4__$_7ostream (virtual function thunk)
   2943  */
   2944 
   2945 static int
   2946 gnu_special (struct work_stuff *work, const char **mangled, string *declp)
   2947 {
   2948   int n;
   2949   int success = 1;
   2950   const char *p;
   2951 
   2952   if ((*mangled)[0] == '_'
   2953       && strchr (cplus_markers, (*mangled)[1]) != NULL
   2954       && (*mangled)[2] == '_')
   2955     {
   2956       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
   2957       (*mangled) += 3;
   2958       work -> destructor += 1;
   2959     }
   2960   else if ((*mangled)[0] == '_'
   2961 	   && (((*mangled)[1] == '_'
   2962 		&& (*mangled)[2] == 'v'
   2963 		&& (*mangled)[3] == 't'
   2964 		&& (*mangled)[4] == '_')
   2965 	       || ((*mangled)[1] == 'v'
   2966 		   && (*mangled)[2] == 't'
   2967 		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
   2968     {
   2969       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
   2970          and create the decl.  Note that we consume the entire mangled
   2971 	 input string, which means that demangle_signature has no work
   2972 	 to do.  */
   2973       if ((*mangled)[2] == 'v')
   2974 	(*mangled) += 5; /* New style, with thunks: "__vt_" */
   2975       else
   2976 	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
   2977       while (**mangled != '\0')
   2978 	{
   2979 	  switch (**mangled)
   2980 	    {
   2981 	    case 'Q':
   2982 	    case 'K':
   2983 	      success = demangle_qualified (work, mangled, declp, 0, 1);
   2984 	      break;
   2985 	    case 't':
   2986 	      success = demangle_template (work, mangled, declp, 0, 1,
   2987 					   1);
   2988 	      break;
   2989 	    default:
   2990 	      if (ISDIGIT((unsigned char)*mangled[0]))
   2991 		{
   2992 		  n = consume_count(mangled);
   2993 		  /* We may be seeing a too-large size, or else a
   2994 		     ".<digits>" indicating a static local symbol.  In
   2995 		     any case, declare victory and move on; *don't* try
   2996 		     to use n to allocate.  */
   2997 		  if (n > (int) strlen (*mangled))
   2998 		    {
   2999 		      success = 1;
   3000 		      break;
   3001 		    }
   3002 		}
   3003 	      else
   3004 		{
   3005 		  n = strcspn (*mangled, cplus_markers);
   3006 		}
   3007 	      string_appendn (declp, *mangled, n);
   3008 	      (*mangled) += n;
   3009 	    }
   3010 
   3011 	  p = strpbrk (*mangled, cplus_markers);
   3012 	  if (success && ((p == NULL) || (p == *mangled)))
   3013 	    {
   3014 	      if (p != NULL)
   3015 		{
   3016 		  string_append (declp, SCOPE_STRING (work));
   3017 		  (*mangled)++;
   3018 		}
   3019 	    }
   3020 	  else
   3021 	    {
   3022 	      success = 0;
   3023 	      break;
   3024 	    }
   3025 	}
   3026       if (success)
   3027 	string_append (declp, " virtual table");
   3028     }
   3029   else if ((*mangled)[0] == '_'
   3030 	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
   3031 	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
   3032     {
   3033       /* static data member, "_3foo$varname" for example */
   3034       (*mangled)++;
   3035       switch (**mangled)
   3036 	{
   3037 	case 'Q':
   3038 	case 'K':
   3039 	  success = demangle_qualified (work, mangled, declp, 0, 1);
   3040 	  break;
   3041 	case 't':
   3042 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
   3043 	  break;
   3044 	default:
   3045 	  n = consume_count (mangled);
   3046 	  if (n < 0 || n > (long) strlen (*mangled))
   3047 	    {
   3048 	      success = 0;
   3049 	      break;
   3050 	    }
   3051 
   3052 	  if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
   3053 	      && (*mangled)[9] == 'N'
   3054 	      && (*mangled)[8] == (*mangled)[10]
   3055 	      && strchr (cplus_markers, (*mangled)[8]))
   3056 	    {
   3057 	      /* A member of the anonymous namespace.  There's information
   3058 		 about what identifier or filename it was keyed to, but
   3059 		 it's just there to make the mangled name unique; we just
   3060 		 step over it.  */
   3061 	      string_append (declp, "{anonymous}");
   3062 	      (*mangled) += n;
   3063 
   3064 	      /* Now p points to the marker before the N, so we need to
   3065 		 update it to the first marker after what we consumed.  */
   3066 	      p = strpbrk (*mangled, cplus_markers);
   3067 	      break;
   3068 	    }
   3069 
   3070 	  string_appendn (declp, *mangled, n);
   3071 	  (*mangled) += n;
   3072 	}
   3073       if (success && (p == *mangled))
   3074 	{
   3075 	  /* Consumed everything up to the cplus_marker, append the
   3076 	     variable name.  */
   3077 	  (*mangled)++;
   3078 	  string_append (declp, SCOPE_STRING (work));
   3079 	  n = strlen (*mangled);
   3080 	  string_appendn (declp, *mangled, n);
   3081 	  (*mangled) += n;
   3082 	}
   3083       else
   3084 	{
   3085 	  success = 0;
   3086 	}
   3087     }
   3088   else if (strncmp (*mangled, "__thunk_", 8) == 0)
   3089     {
   3090       int delta;
   3091 
   3092       (*mangled) += 8;
   3093       delta = consume_count (mangled);
   3094       if (delta == -1)
   3095 	success = 0;
   3096       else
   3097 	{
   3098 	  char *method = internal_cplus_demangle (work, ++*mangled);
   3099 
   3100 	  if (method)
   3101 	    {
   3102 	      char buf[50];
   3103 	      sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
   3104 	      string_append (declp, buf);
   3105 	      string_append (declp, method);
   3106 	      free (method);
   3107 	      n = strlen (*mangled);
   3108 	      (*mangled) += n;
   3109 	    }
   3110 	  else
   3111 	    {
   3112 	      success = 0;
   3113 	    }
   3114 	}
   3115     }
   3116   else if (strncmp (*mangled, "__t", 3) == 0
   3117 	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
   3118     {
   3119       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
   3120       (*mangled) += 4;
   3121       switch (**mangled)
   3122 	{
   3123 	case 'Q':
   3124 	case 'K':
   3125 	  success = demangle_qualified (work, mangled, declp, 0, 1);
   3126 	  break;
   3127 	case 't':
   3128 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
   3129 	  break;
   3130 	default:
   3131 	  success = do_type (work, mangled, declp);
   3132 	  break;
   3133 	}
   3134       if (success && **mangled != '\0')
   3135 	success = 0;
   3136       if (success)
   3137 	string_append (declp, p);
   3138     }
   3139   else
   3140     {
   3141       success = 0;
   3142     }
   3143   return (success);
   3144 }
   3145 
   3146 static void
   3147 recursively_demangle(struct work_stuff *work, const char **mangled,
   3148                      string *result, int namelength)
   3149 {
   3150   char * recurse = (char *)NULL;
   3151   char * recurse_dem = (char *)NULL;
   3152 
   3153   recurse = XNEWVEC (char, namelength + 1);
   3154   memcpy (recurse, *mangled, namelength);
   3155   recurse[namelength] = '\000';
   3156 
   3157   recurse_dem = cplus_demangle (recurse, work->options);
   3158 
   3159   if (recurse_dem)
   3160     {
   3161       string_append (result, recurse_dem);
   3162       free (recurse_dem);
   3163     }
   3164   else
   3165     {
   3166       string_appendn (result, *mangled, namelength);
   3167     }
   3168   free (recurse);
   3169   *mangled += namelength;
   3170 }
   3171 
   3172 /*
   3173 
   3174 LOCAL FUNCTION
   3175 
   3176 	arm_special -- special handling of ARM/lucid mangled strings
   3177 
   3178 SYNOPSIS
   3179 
   3180 	static int
   3181 	arm_special (const char **mangled,
   3182 		     string *declp);
   3183 
   3184 
   3185 DESCRIPTION
   3186 
   3187 	Process some special ARM style mangling forms that don't fit
   3188 	the normal pattern.  For example:
   3189 
   3190 		__vtbl__3foo		(foo virtual table)
   3191 		__vtbl__3foo__3bar	(bar::foo virtual table)
   3192 
   3193  */
   3194 
   3195 static int
   3196 arm_special (const char **mangled, string *declp)
   3197 {
   3198   int n;
   3199   int success = 1;
   3200   const char *scan;
   3201 
   3202   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
   3203     {
   3204       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
   3205          and create the decl.  Note that we consume the entire mangled
   3206 	 input string, which means that demangle_signature has no work
   3207 	 to do.  */
   3208       scan = *mangled + ARM_VTABLE_STRLEN;
   3209       while (*scan != '\0')        /* first check it can be demangled */
   3210         {
   3211           n = consume_count (&scan);
   3212           if (n == -1)
   3213 	    {
   3214 	      return (0);           /* no good */
   3215 	    }
   3216           scan += n;
   3217           if (scan[0] == '_' && scan[1] == '_')
   3218 	    {
   3219 	      scan += 2;
   3220 	    }
   3221         }
   3222       (*mangled) += ARM_VTABLE_STRLEN;
   3223       while (**mangled != '\0')
   3224 	{
   3225 	  n = consume_count (mangled);
   3226           if (n == -1
   3227 	      || n > (long) strlen (*mangled))
   3228 	    return 0;
   3229 	  string_prependn (declp, *mangled, n);
   3230 	  (*mangled) += n;
   3231 	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
   3232 	    {
   3233 	      string_prepend (declp, "::");
   3234 	      (*mangled) += 2;
   3235 	    }
   3236 	}
   3237       string_append (declp, " virtual table");
   3238     }
   3239   else
   3240     {
   3241       success = 0;
   3242     }
   3243   return (success);
   3244 }
   3245 
   3246 /*
   3247 
   3248 LOCAL FUNCTION
   3249 
   3250 	demangle_qualified -- demangle 'Q' qualified name strings
   3251 
   3252 SYNOPSIS
   3253 
   3254 	static int
   3255 	demangle_qualified (struct work_stuff *, const char *mangled,
   3256 			    string *result, int isfuncname, int append);
   3257 
   3258 DESCRIPTION
   3259 
   3260 	Demangle a qualified name, such as "Q25Outer5Inner" which is
   3261 	the mangled form of "Outer::Inner".  The demangled output is
   3262 	prepended or appended to the result string according to the
   3263 	state of the append flag.
   3264 
   3265 	If isfuncname is nonzero, then the qualified name we are building
   3266 	is going to be used as a member function name, so if it is a
   3267 	constructor or destructor function, append an appropriate
   3268 	constructor or destructor name.  I.E. for the above example,
   3269 	the result for use as a constructor is "Outer::Inner::Inner"
   3270 	and the result for use as a destructor is "Outer::Inner::~Inner".
   3271 
   3272 BUGS
   3273 
   3274 	Numeric conversion is ASCII dependent (FIXME).
   3275 
   3276  */
   3277 
   3278 static int
   3279 demangle_qualified (struct work_stuff *work, const char **mangled,
   3280                     string *result, int isfuncname, int append)
   3281 {
   3282   int qualifiers = 0;
   3283   int success = 1;
   3284   char num[2];
   3285   string temp;
   3286   string last_name;
   3287   int bindex = register_Btype (work);
   3288 
   3289   /* We only make use of ISFUNCNAME if the entity is a constructor or
   3290      destructor.  */
   3291   isfuncname = (isfuncname
   3292 		&& ((work->constructor & 1) || (work->destructor & 1)));
   3293 
   3294   string_init (&temp);
   3295   string_init (&last_name);
   3296 
   3297   if ((*mangled)[0] == 'K')
   3298     {
   3299     /* Squangling qualified name reuse */
   3300       int idx;
   3301       (*mangled)++;
   3302       idx = consume_count_with_underscores (mangled);
   3303       if (idx == -1 || idx >= work -> numk)
   3304         success = 0;
   3305       else
   3306         string_append (&temp, work -> ktypevec[idx]);
   3307     }
   3308   else
   3309     switch ((*mangled)[1])
   3310     {
   3311     case '_':
   3312       /* GNU mangled name with more than 9 classes.  The count is preceded
   3313 	 by an underscore (to distinguish it from the <= 9 case) and followed
   3314 	 by an underscore.  */
   3315       (*mangled)++;
   3316       qualifiers = consume_count_with_underscores (mangled);
   3317       if (qualifiers == -1)
   3318 	success = 0;
   3319       break;
   3320 
   3321     case '1':
   3322     case '2':
   3323     case '3':
   3324     case '4':
   3325     case '5':
   3326     case '6':
   3327     case '7':
   3328     case '8':
   3329     case '9':
   3330       /* The count is in a single digit.  */
   3331       num[0] = (*mangled)[1];
   3332       num[1] = '\0';
   3333       qualifiers = atoi (num);
   3334 
   3335       /* If there is an underscore after the digit, skip it.  This is
   3336 	 said to be for ARM-qualified names, but the ARM makes no
   3337 	 mention of such an underscore.  Perhaps cfront uses one.  */
   3338       if ((*mangled)[2] == '_')
   3339 	{
   3340 	  (*mangled)++;
   3341 	}
   3342       (*mangled) += 2;
   3343       break;
   3344 
   3345     case '0':
   3346     default:
   3347       success = 0;
   3348     }
   3349 
   3350   if (!success)
   3351     return success;
   3352 
   3353   /* Pick off the names and collect them in the temp buffer in the order
   3354      in which they are found, separated by '::'.  */
   3355 
   3356   while (qualifiers-- > 0)
   3357     {
   3358       int remember_K = 1;
   3359       string_clear (&last_name);
   3360 
   3361       if (*mangled[0] == '_')
   3362 	(*mangled)++;
   3363 
   3364       if (*mangled[0] == 't')
   3365 	{
   3366 	  /* Here we always append to TEMP since we will want to use
   3367 	     the template name without the template parameters as a
   3368 	     constructor or destructor name.  The appropriate
   3369 	     (parameter-less) value is returned by demangle_template
   3370 	     in LAST_NAME.  We do not remember the template type here,
   3371 	     in order to match the G++ mangling algorithm.  */
   3372 	  success = demangle_template(work, mangled, &temp,
   3373 				      &last_name, 1, 0);
   3374 	  if (!success)
   3375 	    break;
   3376 	}
   3377       else if (*mangled[0] == 'K')
   3378 	{
   3379           int idx;
   3380           (*mangled)++;
   3381           idx = consume_count_with_underscores (mangled);
   3382           if (idx == -1 || idx >= work->numk)
   3383             success = 0;
   3384           else
   3385             string_append (&temp, work->ktypevec[idx]);
   3386           remember_K = 0;
   3387 
   3388 	  if (!success) break;
   3389 	}
   3390       else
   3391 	{
   3392 	  if (EDG_DEMANGLING)
   3393             {
   3394 	      int namelength;
   3395  	      /* Now recursively demangle the qualifier
   3396  	       * This is necessary to deal with templates in
   3397  	       * mangling styles like EDG */
   3398 	      namelength = consume_count (mangled);
   3399 	      if (namelength == -1)
   3400 		{
   3401 		  success = 0;
   3402 		  break;
   3403 		}
   3404  	      recursively_demangle(work, mangled, &temp, namelength);
   3405             }
   3406           else
   3407             {
   3408               string_delete (&last_name);
   3409               success = do_type (work, mangled, &last_name);
   3410               if (!success)
   3411                 break;
   3412               string_appends (&temp, &last_name);
   3413             }
   3414 	}
   3415 
   3416       if (remember_K)
   3417 	remember_Ktype (work, temp.b, LEN_STRING (&temp));
   3418 
   3419       if (qualifiers > 0)
   3420 	string_append (&temp, SCOPE_STRING (work));
   3421     }
   3422 
   3423   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
   3424 
   3425   /* If we are using the result as a function name, we need to append
   3426      the appropriate '::' separated constructor or destructor name.
   3427      We do this here because this is the most convenient place, where
   3428      we already have a pointer to the name and the length of the name.  */
   3429 
   3430   if (isfuncname)
   3431     {
   3432       string_append (&temp, SCOPE_STRING (work));
   3433       if (work -> destructor & 1)
   3434 	string_append (&temp, "~");
   3435       string_appends (&temp, &last_name);
   3436     }
   3437 
   3438   /* Now either prepend the temp buffer to the result, or append it,
   3439      depending upon the state of the append flag.  */
   3440 
   3441   if (append)
   3442     string_appends (result, &temp);
   3443   else
   3444     {
   3445       if (!STRING_EMPTY (result))
   3446 	string_append (&temp, SCOPE_STRING (work));
   3447       string_prepends (result, &temp);
   3448     }
   3449 
   3450   string_delete (&last_name);
   3451   string_delete (&temp);
   3452   return (success);
   3453 }
   3454 
   3455 /*
   3456 
   3457 LOCAL FUNCTION
   3458 
   3459 	get_count -- convert an ascii count to integer, consuming tokens
   3460 
   3461 SYNOPSIS
   3462 
   3463 	static int
   3464 	get_count (const char **type, int *count)
   3465 
   3466 DESCRIPTION
   3467 
   3468 	Assume that *type points at a count in a mangled name; set
   3469 	*count to its value, and set *type to the next character after
   3470 	the count.  There are some weird rules in effect here.
   3471 
   3472 	If *type does not point at a string of digits, return zero.
   3473 
   3474 	If *type points at a string of digits followed by an
   3475 	underscore, set *count to their value as an integer, advance
   3476 	*type to point *after the underscore, and return 1.
   3477 
   3478 	If *type points at a string of digits not followed by an
   3479 	underscore, consume only the first digit.  Set *count to its
   3480 	value as an integer, leave *type pointing after that digit,
   3481 	and return 1.
   3482 
   3483         The excuse for this odd behavior: in the ARM and HP demangling
   3484         styles, a type can be followed by a repeat count of the form
   3485         `Nxy', where:
   3486 
   3487         `x' is a single digit specifying how many additional copies
   3488             of the type to append to the argument list, and
   3489 
   3490         `y' is one or more digits, specifying the zero-based index of
   3491             the first repeated argument in the list.  Yes, as you're
   3492             unmangling the name you can figure this out yourself, but
   3493             it's there anyway.
   3494 
   3495         So, for example, in `bar__3fooFPiN51', the first argument is a
   3496         pointer to an integer (`Pi'), and then the next five arguments
   3497         are the same (`N5'), and the first repeat is the function's
   3498         second argument (`1').
   3499 */
   3500 
   3501 static int
   3502 get_count (const char **type, int *count)
   3503 {
   3504   const char *p;
   3505   int n;
   3506 
   3507   if (!ISDIGIT ((unsigned char)**type))
   3508     return (0);
   3509   else
   3510     {
   3511       *count = **type - '0';
   3512       (*type)++;
   3513       if (ISDIGIT ((unsigned char)**type))
   3514 	{
   3515 	  p = *type;
   3516 	  n = *count;
   3517 	  do
   3518 	    {
   3519 	      n *= 10;
   3520 	      n += *p - '0';
   3521 	      p++;
   3522 	    }
   3523 	  while (ISDIGIT ((unsigned char)*p));
   3524 	  if (*p == '_')
   3525 	    {
   3526 	      *type = p + 1;
   3527 	      *count = n;
   3528 	    }
   3529 	}
   3530     }
   3531   return (1);
   3532 }
   3533 
   3534 /* RESULT will be initialised here; it will be freed on failure.  The
   3535    value returned is really a type_kind_t.  */
   3536 
   3537 static int
   3538 do_type (struct work_stuff *work, const char **mangled, string *result)
   3539 {
   3540   int n;
   3541   int done;
   3542   int success;
   3543   string decl;
   3544   const char *remembered_type;
   3545   int type_quals;
   3546   type_kind_t tk = tk_none;
   3547 
   3548   string_init (&decl);
   3549   string_init (result);
   3550 
   3551   done = 0;
   3552   success = 1;
   3553   while (success && !done)
   3554     {
   3555       int member;
   3556       switch (**mangled)
   3557 	{
   3558 
   3559 	  /* A pointer type */
   3560 	case 'P':
   3561 	case 'p':
   3562 	  (*mangled)++;
   3563 	  if (! (work -> options & DMGL_JAVA))
   3564 	    string_prepend (&decl, "*");
   3565 	  if (tk == tk_none)
   3566 	    tk = tk_pointer;
   3567 	  break;
   3568 
   3569 	  /* A reference type */
   3570 	case 'R':
   3571 	  (*mangled)++;
   3572 	  string_prepend (&decl, "&");
   3573 	  if (tk == tk_none)
   3574 	    tk = tk_reference;
   3575 	  break;
   3576 
   3577 	  /* An array */
   3578 	case 'A':
   3579 	  {
   3580 	    ++(*mangled);
   3581 	    if (!STRING_EMPTY (&decl)
   3582 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
   3583 	      {
   3584 		string_prepend (&decl, "(");
   3585 		string_append (&decl, ")");
   3586 	      }
   3587 	    string_append (&decl, "[");
   3588 	    if (**mangled != '_')
   3589 	      success = demangle_template_value_parm (work, mangled, &decl,
   3590 						      tk_integral);
   3591 	    if (**mangled == '_')
   3592 	      ++(*mangled);
   3593 	    string_append (&decl, "]");
   3594 	    break;
   3595 	  }
   3596 
   3597 	/* A back reference to a previously seen type */
   3598 	case 'T':
   3599 	  (*mangled)++;
   3600 	  if (!get_count (mangled, &n) || n >= work -> ntypes)
   3601 	    {
   3602 	      success = 0;
   3603 	    }
   3604 	  else
   3605 	    {
   3606 	      remembered_type = work -> typevec[n];
   3607 	      mangled = &remembered_type;
   3608 	    }
   3609 	  break;
   3610 
   3611 	  /* A function */
   3612 	case 'F':
   3613 	  (*mangled)++;
   3614 	    if (!STRING_EMPTY (&decl)
   3615 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
   3616 	    {
   3617 	      string_prepend (&decl, "(");
   3618 	      string_append (&decl, ")");
   3619 	    }
   3620 	  /* After picking off the function args, we expect to either find the
   3621 	     function return type (preceded by an '_') or the end of the
   3622 	     string.  */
   3623 	  if (!demangle_nested_args (work, mangled, &decl)
   3624 	      || (**mangled != '_' && **mangled != '\0'))
   3625 	    {
   3626 	      success = 0;
   3627 	      break;
   3628 	    }
   3629 	  if (success && (**mangled == '_'))
   3630 	    (*mangled)++;
   3631 	  break;
   3632 
   3633 	case 'M':
   3634 	case 'O':
   3635 	  {
   3636 	    type_quals = TYPE_UNQUALIFIED;
   3637 
   3638 	    member = **mangled == 'M';
   3639 	    (*mangled)++;
   3640 
   3641 	    string_append (&decl, ")");
   3642 
   3643 	    /* We don't need to prepend `::' for a qualified name;
   3644 	       demangle_qualified will do that for us.  */
   3645 	    if (**mangled != 'Q')
   3646 	      string_prepend (&decl, SCOPE_STRING (work));
   3647 
   3648 	    if (ISDIGIT ((unsigned char)**mangled))
   3649 	      {
   3650 		n = consume_count (mangled);
   3651 		if (n == -1
   3652 		    || (int) strlen (*mangled) < n)
   3653 		  {
   3654 		    success = 0;
   3655 		    break;
   3656 		  }
   3657 		string_prependn (&decl, *mangled, n);
   3658 		*mangled += n;
   3659 	      }
   3660 	    else if (**mangled == 'X' || **mangled == 'Y')
   3661 	      {
   3662 		string temp;
   3663 		do_type (work, mangled, &temp);
   3664 		string_prepends (&decl, &temp);
   3665 		string_delete (&temp);
   3666 	      }
   3667 	    else if (**mangled == 't')
   3668 	      {
   3669 		string temp;
   3670 		string_init (&temp);
   3671 		success = demangle_template (work, mangled, &temp,
   3672 					     NULL, 1, 1);
   3673 		if (success)
   3674 		  {
   3675 		    string_prependn (&decl, temp.b, temp.p - temp.b);
   3676 		    string_delete (&temp);
   3677 		  }
   3678 		else
   3679 		  {
   3680 		    string_delete (&temp);
   3681 		    break;
   3682 		  }
   3683 	      }
   3684 	    else if (**mangled == 'Q')
   3685 	      {
   3686 		success = demangle_qualified (work, mangled, &decl,
   3687 					      /*isfuncnam=*/0,
   3688 					      /*append=*/0);
   3689 		if (!success)
   3690 		  break;
   3691 	      }
   3692 	    else
   3693 	      {
   3694 		success = 0;
   3695 		break;
   3696 	      }
   3697 
   3698 	    string_prepend (&decl, "(");
   3699 	    if (member)
   3700 	      {
   3701 		switch (**mangled)
   3702 		  {
   3703 		  case 'C':
   3704 		  case 'V':
   3705 		  case 'u':
   3706 		    type_quals |= code_for_qualifier (**mangled);
   3707 		    (*mangled)++;
   3708 		    break;
   3709 
   3710 		  default:
   3711 		    break;
   3712 		  }
   3713 
   3714 		if (*(*mangled)++ != 'F')
   3715 		  {
   3716 		    success = 0;
   3717 		    break;
   3718 		  }
   3719 	      }
   3720 	    if ((member && !demangle_nested_args (work, mangled, &decl))
   3721 		|| **mangled != '_')
   3722 	      {
   3723 		success = 0;
   3724 		break;
   3725 	      }
   3726 	    (*mangled)++;
   3727 	    if (! PRINT_ANSI_QUALIFIERS)
   3728 	      {
   3729 		break;
   3730 	      }
   3731 	    if (type_quals != TYPE_UNQUALIFIED)
   3732 	      {
   3733 		APPEND_BLANK (&decl);
   3734 		string_append (&decl, qualifier_string (type_quals));
   3735 	      }
   3736 	    break;
   3737 	  }
   3738         case 'G':
   3739 	  (*mangled)++;
   3740 	  break;
   3741 
   3742 	case 'C':
   3743 	case 'V':
   3744 	case 'u':
   3745 	  if (PRINT_ANSI_QUALIFIERS)
   3746 	    {
   3747 	      if (!STRING_EMPTY (&decl))
   3748 		string_prepend (&decl, " ");
   3749 
   3750 	      string_prepend (&decl, demangle_qualifier (**mangled));
   3751 	    }
   3752 	  (*mangled)++;
   3753 	  break;
   3754 	  /*
   3755 	    }
   3756 	    */
   3757 
   3758 	  /* fall through */
   3759 	default:
   3760 	  done = 1;
   3761 	  break;
   3762 	}
   3763     }
   3764 
   3765   if (success) switch (**mangled)
   3766     {
   3767       /* A qualified name, such as "Outer::Inner".  */
   3768     case 'Q':
   3769     case 'K':
   3770       {
   3771         success = demangle_qualified (work, mangled, result, 0, 1);
   3772         break;
   3773       }
   3774 
   3775     /* A back reference to a previously seen squangled type */
   3776     case 'B':
   3777       (*mangled)++;
   3778       if (!get_count (mangled, &n) || n >= work -> numb)
   3779 	success = 0;
   3780       else
   3781 	string_append (result, work->btypevec[n]);
   3782       break;
   3783 
   3784     case 'X':
   3785     case 'Y':
   3786       /* A template parm.  We substitute the corresponding argument. */
   3787       {
   3788 	int idx;
   3789 
   3790 	(*mangled)++;
   3791 	idx = consume_count_with_underscores (mangled);
   3792 
   3793 	if (idx == -1
   3794 	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
   3795 	    || consume_count_with_underscores (mangled) == -1)
   3796 	  {
   3797 	    success = 0;
   3798 	    break;
   3799 	  }
   3800 
   3801 	if (work->tmpl_argvec)
   3802 	  string_append (result, work->tmpl_argvec[idx]);
   3803 	else
   3804 	  string_append_template_idx (result, idx);
   3805 
   3806 	success = 1;
   3807       }
   3808     break;
   3809 
   3810     default:
   3811       success = demangle_fund_type (work, mangled, result);
   3812       if (tk == tk_none)
   3813 	tk = (type_kind_t) success;
   3814       break;
   3815     }
   3816 
   3817   if (success)
   3818     {
   3819       if (!STRING_EMPTY (&decl))
   3820 	{
   3821 	  string_append (result, " ");
   3822 	  string_appends (result, &decl);
   3823 	}
   3824     }
   3825   else
   3826     string_delete (result);
   3827   string_delete (&decl);
   3828 
   3829   if (success)
   3830     /* Assume an integral type, if we're not sure.  */
   3831     return (int) ((tk == tk_none) ? tk_integral : tk);
   3832   else
   3833     return 0;
   3834 }
   3835 
   3836 /* Given a pointer to a type string that represents a fundamental type
   3837    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
   3838    string in which the demangled output is being built in RESULT, and
   3839    the WORK structure, decode the types and add them to the result.
   3840 
   3841    For example:
   3842 
   3843    	"Ci"	=>	"const int"
   3844 	"Sl"	=>	"signed long"
   3845 	"CUs"	=>	"const unsigned short"
   3846 
   3847    The value returned is really a type_kind_t.  */
   3848 
   3849 static int
   3850 demangle_fund_type (struct work_stuff *work,
   3851                     const char **mangled, string *result)
   3852 {
   3853   int done = 0;
   3854   int success = 1;
   3855   char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
   3856   unsigned int dec = 0;
   3857   type_kind_t tk = tk_integral;
   3858 
   3859   /* First pick off any type qualifiers.  There can be more than one.  */
   3860 
   3861   while (!done)
   3862     {
   3863       switch (**mangled)
   3864 	{
   3865 	case 'C':
   3866 	case 'V':
   3867 	case 'u':
   3868 	  if (PRINT_ANSI_QUALIFIERS)
   3869 	    {
   3870               if (!STRING_EMPTY (result))
   3871                 string_prepend (result, " ");
   3872 	      string_prepend (result, demangle_qualifier (**mangled));
   3873 	    }
   3874 	  (*mangled)++;
   3875 	  break;
   3876 	case 'U':
   3877 	  (*mangled)++;
   3878 	  APPEND_BLANK (result);
   3879 	  string_append (result, "unsigned");
   3880 	  break;
   3881 	case 'S': /* signed char only */
   3882 	  (*mangled)++;
   3883 	  APPEND_BLANK (result);
   3884 	  string_append (result, "signed");
   3885 	  break;
   3886 	case 'J':
   3887 	  (*mangled)++;
   3888 	  APPEND_BLANK (result);
   3889 	  string_append (result, "__complex");
   3890 	  break;
   3891 	default:
   3892 	  done = 1;
   3893 	  break;
   3894 	}
   3895     }
   3896 
   3897   /* Now pick off the fundamental type.  There can be only one.  */
   3898 
   3899   switch (**mangled)
   3900     {
   3901     case '\0':
   3902     case '_':
   3903       break;
   3904     case 'v':
   3905       (*mangled)++;
   3906       APPEND_BLANK (result);
   3907       string_append (result, "void");
   3908       break;
   3909     case 'x':
   3910       (*mangled)++;
   3911       APPEND_BLANK (result);
   3912       string_append (result, "long long");
   3913       break;
   3914     case 'l':
   3915       (*mangled)++;
   3916       APPEND_BLANK (result);
   3917       string_append (result, "long");
   3918       break;
   3919     case 'i':
   3920       (*mangled)++;
   3921       APPEND_BLANK (result);
   3922       string_append (result, "int");
   3923       break;
   3924     case 's':
   3925       (*mangled)++;
   3926       APPEND_BLANK (result);
   3927       string_append (result, "short");
   3928       break;
   3929     case 'b':
   3930       (*mangled)++;
   3931       APPEND_BLANK (result);
   3932       string_append (result, "bool");
   3933       tk = tk_bool;
   3934       break;
   3935     case 'c':
   3936       (*mangled)++;
   3937       APPEND_BLANK (result);
   3938       string_append (result, "char");
   3939       tk = tk_char;
   3940       break;
   3941     case 'w':
   3942       (*mangled)++;
   3943       APPEND_BLANK (result);
   3944       string_append (result, "wchar_t");
   3945       tk = tk_char;
   3946       break;
   3947     case 'r':
   3948       (*mangled)++;
   3949       APPEND_BLANK (result);
   3950       string_append (result, "long double");
   3951       tk = tk_real;
   3952       break;
   3953     case 'd':
   3954       (*mangled)++;
   3955       APPEND_BLANK (result);
   3956       string_append (result, "double");
   3957       tk = tk_real;
   3958       break;
   3959     case 'f':
   3960       (*mangled)++;
   3961       APPEND_BLANK (result);
   3962       string_append (result, "float");
   3963       tk = tk_real;
   3964       break;
   3965     case 'G':
   3966       (*mangled)++;
   3967       if (!ISDIGIT ((unsigned char)**mangled))
   3968 	{
   3969 	  success = 0;
   3970 	  break;
   3971 	}
   3972     case 'I':
   3973       (*mangled)++;
   3974       if (**mangled == '_')
   3975 	{
   3976 	  int i;
   3977 	  (*mangled)++;
   3978 	  for (i = 0;
   3979 	       i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
   3980 	       (*mangled)++, i++)
   3981 	    buf[i] = **mangled;
   3982 	  if (**mangled != '_')
   3983 	    {
   3984 	      success = 0;
   3985 	      break;
   3986 	    }
   3987 	  buf[i] = '\0';
   3988 	  (*mangled)++;
   3989 	}
   3990       else
   3991 	{
   3992 	  strncpy (buf, *mangled, 2);
   3993 	  buf[2] = '\0';
   3994 	  *mangled += min (strlen (*mangled), 2);
   3995 	}
   3996       sscanf (buf, "%x", &dec);
   3997       sprintf (buf, "int%u_t", dec);
   3998       APPEND_BLANK (result);
   3999       string_append (result, buf);
   4000       break;
   4001 
   4002       /* fall through */
   4003       /* An explicit type, such as "6mytype" or "7integer" */
   4004     case '0':
   4005     case '1':
   4006     case '2':
   4007     case '3':
   4008     case '4':
   4009     case '5':
   4010     case '6':
   4011     case '7':
   4012     case '8':
   4013     case '9':
   4014       {
   4015         int bindex = register_Btype (work);
   4016         string btype;
   4017         string_init (&btype);
   4018         if (demangle_class_name (work, mangled, &btype)) {
   4019           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
   4020           APPEND_BLANK (result);
   4021           string_appends (result, &btype);
   4022         }
   4023         else
   4024           success = 0;
   4025         string_delete (&btype);
   4026         break;
   4027       }
   4028     case 't':
   4029       {
   4030         string btype;
   4031         string_init (&btype);
   4032         success = demangle_template (work, mangled, &btype, 0, 1, 1);
   4033         string_appends (result, &btype);
   4034         string_delete (&btype);
   4035         break;
   4036       }
   4037     default:
   4038       success = 0;
   4039       break;
   4040     }
   4041 
   4042   return success ? ((int) tk) : 0;
   4043 }
   4044 
   4045 
   4046 /* Handle a template's value parameter for HP aCC (extension from ARM)
   4047    **mangled points to 'S' or 'U' */
   4048 
   4049 static int
   4050 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
   4051                                const char **mangled, string *result)
   4052 {
   4053   int unsigned_const;
   4054 
   4055   if (**mangled != 'U' && **mangled != 'S')
   4056     return 0;
   4057 
   4058   unsigned_const = (**mangled == 'U');
   4059 
   4060   (*mangled)++;
   4061 
   4062   switch (**mangled)
   4063     {
   4064       case 'N':
   4065         string_append (result, "-");
   4066         /* fall through */
   4067       case 'P':
   4068         (*mangled)++;
   4069         break;
   4070       case 'M':
   4071         /* special case for -2^31 */
   4072         string_append (result, "-2147483648");
   4073         (*mangled)++;
   4074         return 1;
   4075       default:
   4076         return 0;
   4077     }
   4078 
   4079   /* We have to be looking at an integer now */
   4080   if (!(ISDIGIT ((unsigned char)**mangled)))
   4081     return 0;
   4082 
   4083   /* We only deal with integral values for template
   4084      parameters -- so it's OK to look only for digits */
   4085   while (ISDIGIT ((unsigned char)**mangled))
   4086     {
   4087       char_str[0] = **mangled;
   4088       string_append (result, char_str);
   4089       (*mangled)++;
   4090     }
   4091 
   4092   if (unsigned_const)
   4093     string_append (result, "U");
   4094 
   4095   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
   4096      with L or LL suffixes. pai/1997-09-03 */
   4097 
   4098   return 1; /* success */
   4099 }
   4100 
   4101 /* Handle a template's literal parameter for HP aCC (extension from ARM)
   4102    **mangled is pointing to the 'A' */
   4103 
   4104 static int
   4105 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
   4106                            string *result)
   4107 {
   4108   int literal_len = 0;
   4109   char * recurse;
   4110   char * recurse_dem;
   4111 
   4112   if (**mangled != 'A')
   4113     return 0;
   4114 
   4115   (*mangled)++;
   4116 
   4117   literal_len = consume_count (mangled);
   4118 
   4119   if (literal_len <= 0)
   4120     return 0;
   4121 
   4122   /* Literal parameters are names of arrays, functions, etc.  and the
   4123      canonical representation uses the address operator */
   4124   string_append (result, "&");
   4125 
   4126   /* Now recursively demangle the literal name */
   4127   recurse = XNEWVEC (char, literal_len + 1);
   4128   memcpy (recurse, *mangled, literal_len);
   4129   recurse[literal_len] = '\000';
   4130 
   4131   recurse_dem = cplus_demangle (recurse, work->options);
   4132 
   4133   if (recurse_dem)
   4134     {
   4135       string_append (result, recurse_dem);
   4136       free (recurse_dem);
   4137     }
   4138   else
   4139     {
   4140       string_appendn (result, *mangled, literal_len);
   4141     }
   4142   (*mangled) += literal_len;
   4143   free (recurse);
   4144 
   4145   return 1;
   4146 }
   4147 
   4148 static int
   4149 snarf_numeric_literal (const char **args, string *arg)
   4150 {
   4151   if (**args == '-')
   4152     {
   4153       char_str[0] = '-';
   4154       string_append (arg, char_str);
   4155       (*args)++;
   4156     }
   4157   else if (**args == '+')
   4158     (*args)++;
   4159 
   4160   if (!ISDIGIT ((unsigned char)**args))
   4161     return 0;
   4162 
   4163   while (ISDIGIT ((unsigned char)**args))
   4164     {
   4165       char_str[0] = **args;
   4166       string_append (arg, char_str);
   4167       (*args)++;
   4168     }
   4169 
   4170   return 1;
   4171 }
   4172 
   4173 /* Demangle the next argument, given by MANGLED into RESULT, which
   4174    *should be an uninitialized* string.  It will be initialized here,
   4175    and free'd should anything go wrong.  */
   4176 
   4177 static int
   4178 do_arg (struct work_stuff *work, const char **mangled, string *result)
   4179 {
   4180   /* Remember where we started so that we can record the type, for
   4181      non-squangling type remembering.  */
   4182   const char *start = *mangled;
   4183 
   4184   string_init (result);
   4185 
   4186   if (work->nrepeats > 0)
   4187     {
   4188       --work->nrepeats;
   4189 
   4190       if (work->previous_argument == 0)
   4191 	return 0;
   4192 
   4193       /* We want to reissue the previous type in this argument list.  */
   4194       string_appends (result, work->previous_argument);
   4195       return 1;
   4196     }
   4197 
   4198   if (**mangled == 'n')
   4199     {
   4200       /* A squangling-style repeat.  */
   4201       (*mangled)++;
   4202       work->nrepeats = consume_count(mangled);
   4203 
   4204       if (work->nrepeats <= 0)
   4205 	/* This was not a repeat count after all.  */
   4206 	return 0;
   4207 
   4208       if (work->nrepeats > 9)
   4209 	{
   4210 	  if (**mangled != '_')
   4211 	    /* The repeat count should be followed by an '_' in this
   4212 	       case.  */
   4213 	    return 0;
   4214 	  else
   4215 	    (*mangled)++;
   4216 	}
   4217 
   4218       /* Now, the repeat is all set up.  */
   4219       return do_arg (work, mangled, result);
   4220     }
   4221 
   4222   /* Save the result in WORK->previous_argument so that we can find it
   4223      if it's repeated.  Note that saving START is not good enough: we
   4224      do not want to add additional types to the back-referenceable
   4225      type vector when processing a repeated type.  */
   4226   if (work->previous_argument)
   4227     string_delete (work->previous_argument);
   4228   else
   4229     work->previous_argument = XNEW (string);
   4230 
   4231   if (!do_type (work, mangled, work->previous_argument))
   4232     return 0;
   4233 
   4234   string_appends (result, work->previous_argument);
   4235 
   4236   remember_type (work, start, *mangled - start);
   4237   return 1;
   4238 }
   4239 
   4240 static void
   4241 remember_type (struct work_stuff *work, const char *start, int len)
   4242 {
   4243   char *tem;
   4244 
   4245   if (work->forgetting_types)
   4246     return;
   4247 
   4248   if (work -> ntypes >= work -> typevec_size)
   4249     {
   4250       if (work -> typevec_size == 0)
   4251 	{
   4252 	  work -> typevec_size = 3;
   4253 	  work -> typevec = XNEWVEC (char *, work->typevec_size);
   4254 	}
   4255       else
   4256 	{
   4257 	  work -> typevec_size *= 2;
   4258 	  work -> typevec
   4259 	    = XRESIZEVEC (char *, work->typevec, work->typevec_size);
   4260 	}
   4261     }
   4262   tem = XNEWVEC (char, len + 1);
   4263   memcpy (tem, start, len);
   4264   tem[len] = '\0';
   4265   work -> typevec[work -> ntypes++] = tem;
   4266 }
   4267 
   4268 
   4269 /* Remember a K type class qualifier. */
   4270 static void
   4271 remember_Ktype (struct work_stuff *work, const char *start, int len)
   4272 {
   4273   char *tem;
   4274 
   4275   if (work -> numk >= work -> ksize)
   4276     {
   4277       if (work -> ksize == 0)
   4278 	{
   4279 	  work -> ksize = 5;
   4280 	  work -> ktypevec = XNEWVEC (char *, work->ksize);
   4281 	}
   4282       else
   4283 	{
   4284 	  work -> ksize *= 2;
   4285 	  work -> ktypevec
   4286 	    = XRESIZEVEC (char *, work->ktypevec, work->ksize);
   4287 	}
   4288     }
   4289   tem = XNEWVEC (char, len + 1);
   4290   memcpy (tem, start, len);
   4291   tem[len] = '\0';
   4292   work -> ktypevec[work -> numk++] = tem;
   4293 }
   4294 
   4295 /* Register a B code, and get an index for it. B codes are registered
   4296    as they are seen, rather than as they are completed, so map<temp<char> >
   4297    registers map<temp<char> > as B0, and temp<char> as B1 */
   4298 
   4299 static int
   4300 register_Btype (struct work_stuff *work)
   4301 {
   4302   int ret;
   4303 
   4304   if (work -> numb >= work -> bsize)
   4305     {
   4306       if (work -> bsize == 0)
   4307 	{
   4308 	  work -> bsize = 5;
   4309 	  work -> btypevec = XNEWVEC (char *, work->bsize);
   4310 	}
   4311       else
   4312 	{
   4313 	  work -> bsize *= 2;
   4314 	  work -> btypevec
   4315 	    = XRESIZEVEC (char *, work->btypevec, work->bsize);
   4316 	}
   4317     }
   4318   ret = work -> numb++;
   4319   work -> btypevec[ret] = NULL;
   4320   return(ret);
   4321 }
   4322 
   4323 /* Store a value into a previously registered B code type. */
   4324 
   4325 static void
   4326 remember_Btype (struct work_stuff *work, const char *start,
   4327                 int len, int index)
   4328 {
   4329   char *tem;
   4330 
   4331   tem = XNEWVEC (char, len + 1);
   4332   memcpy (tem, start, len);
   4333   tem[len] = '\0';
   4334   work -> btypevec[index] = tem;
   4335 }
   4336 
   4337 /* Lose all the info related to B and K type codes. */
   4338 static void
   4339 forget_B_and_K_types (struct work_stuff *work)
   4340 {
   4341   int i;
   4342 
   4343   while (work -> numk > 0)
   4344     {
   4345       i = --(work -> numk);
   4346       if (work -> ktypevec[i] != NULL)
   4347 	{
   4348 	  free (work -> ktypevec[i]);
   4349 	  work -> ktypevec[i] = NULL;
   4350 	}
   4351     }
   4352 
   4353   while (work -> numb > 0)
   4354     {
   4355       i = --(work -> numb);
   4356       if (work -> btypevec[i] != NULL)
   4357 	{
   4358 	  free (work -> btypevec[i]);
   4359 	  work -> btypevec[i] = NULL;
   4360 	}
   4361     }
   4362 }
   4363 /* Forget the remembered types, but not the type vector itself.  */
   4364 
   4365 static void
   4366 forget_types (struct work_stuff *work)
   4367 {
   4368   int i;
   4369 
   4370   while (work -> ntypes > 0)
   4371     {
   4372       i = --(work -> ntypes);
   4373       if (work -> typevec[i] != NULL)
   4374 	{
   4375 	  free (work -> typevec[i]);
   4376 	  work -> typevec[i] = NULL;
   4377 	}
   4378     }
   4379 }
   4380 
   4381 /* Process the argument list part of the signature, after any class spec
   4382    has been consumed, as well as the first 'F' character (if any).  For
   4383    example:
   4384 
   4385    "__als__3fooRT0"		=>	process "RT0"
   4386    "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
   4387 
   4388    DECLP must be already initialised, usually non-empty.  It won't be freed
   4389    on failure.
   4390 
   4391    Note that g++ differs significantly from ARM and lucid style mangling
   4392    with regards to references to previously seen types.  For example, given
   4393    the source fragment:
   4394 
   4395      class foo {
   4396        public:
   4397        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
   4398      };
   4399 
   4400      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
   4401      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
   4402 
   4403    g++ produces the names:
   4404 
   4405      __3fooiRT0iT2iT2
   4406      foo__FiR3fooiT1iT1
   4407 
   4408    while lcc (and presumably other ARM style compilers as well) produces:
   4409 
   4410      foo__FiR3fooT1T2T1T2
   4411      __ct__3fooFiR3fooT1T2T1T2
   4412 
   4413    Note that g++ bases its type numbers starting at zero and counts all
   4414    previously seen types, while lucid/ARM bases its type numbers starting
   4415    at one and only considers types after it has seen the 'F' character
   4416    indicating the start of the function args.  For lucid/ARM style, we
   4417    account for this difference by discarding any previously seen types when
   4418    we see the 'F' character, and subtracting one from the type number
   4419    reference.
   4420 
   4421  */
   4422 
   4423 static int
   4424 demangle_args (struct work_stuff *work, const char **mangled,
   4425                string *declp)
   4426 {
   4427   string arg;
   4428   int need_comma = 0;
   4429   int r;
   4430   int t;
   4431   const char *tem;
   4432   char temptype;
   4433 
   4434   if (PRINT_ARG_TYPES)
   4435     {
   4436       string_append (declp, "(");
   4437       if (**mangled == '\0')
   4438 	{
   4439 	  string_append (declp, "void");
   4440 	}
   4441     }
   4442 
   4443   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
   4444 	 || work->nrepeats > 0)
   4445     {
   4446       if ((**mangled == 'N') || (**mangled == 'T'))
   4447 	{
   4448 	  temptype = *(*mangled)++;
   4449 
   4450 	  if (temptype == 'N')
   4451 	    {
   4452 	      if (!get_count (mangled, &r))
   4453 		{
   4454 		  return (0);
   4455 		}
   4456 	    }
   4457 	  else
   4458 	    {
   4459 	      r = 1;
   4460 	    }
   4461           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
   4462             {
   4463               /* If we have 10 or more types we might have more than a 1 digit
   4464                  index so we'll have to consume the whole count here. This
   4465                  will lose if the next thing is a type name preceded by a
   4466                  count but it's impossible to demangle that case properly
   4467                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
   4468                  Pc, ...)"  or "(..., type12, char *, ...)" */
   4469               if ((t = consume_count(mangled)) <= 0)
   4470                 {
   4471                   return (0);
   4472                 }
   4473             }
   4474           else
   4475 	    {
   4476 	      if (!get_count (mangled, &t))
   4477 	    	{
   4478 	          return (0);
   4479 	    	}
   4480 	    }
   4481 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
   4482 	    {
   4483 	      t--;
   4484 	    }
   4485 	  /* Validate the type index.  Protect against illegal indices from
   4486 	     malformed type strings.  */
   4487 	  if ((t < 0) || (t >= work -> ntypes))
   4488 	    {
   4489 	      return (0);
   4490 	    }
   4491 	  while (work->nrepeats > 0 || --r >= 0)
   4492 	    {
   4493 	      tem = work -> typevec[t];
   4494 	      if (need_comma && PRINT_ARG_TYPES)
   4495 		{
   4496 		  string_append (declp, ", ");
   4497 		}
   4498 	      if (!do_arg (work, &tem, &arg))
   4499 		{
   4500 		  return (0);
   4501 		}
   4502 	      if (PRINT_ARG_TYPES)
   4503 		{
   4504 		  string_appends (declp, &arg);
   4505 		}
   4506 	      string_delete (&arg);
   4507 	      need_comma = 1;
   4508 	    }
   4509 	}
   4510       else
   4511 	{
   4512 	  if (need_comma && PRINT_ARG_TYPES)
   4513 	    string_append (declp, ", ");
   4514 	  if (!do_arg (work, mangled, &arg))
   4515 	    return (0);
   4516 	  if (PRINT_ARG_TYPES)
   4517 	    string_appends (declp, &arg);
   4518 	  string_delete (&arg);
   4519 	  need_comma = 1;
   4520 	}
   4521     }
   4522 
   4523   if (**mangled == 'e')
   4524     {
   4525       (*mangled)++;
   4526       if (PRINT_ARG_TYPES)
   4527 	{
   4528 	  if (need_comma)
   4529 	    {
   4530 	      string_append (declp, ",");
   4531 	    }
   4532 	  string_append (declp, "...");
   4533 	}
   4534     }
   4535 
   4536   if (PRINT_ARG_TYPES)
   4537     {
   4538       string_append (declp, ")");
   4539     }
   4540   return (1);
   4541 }
   4542 
   4543 /* Like demangle_args, but for demangling the argument lists of function
   4544    and method pointers or references, not top-level declarations.  */
   4545 
   4546 static int
   4547 demangle_nested_args (struct work_stuff *work, const char **mangled,
   4548                       string *declp)
   4549 {
   4550   string* saved_previous_argument;
   4551   int result;
   4552   int saved_nrepeats;
   4553 
   4554   /* The G++ name-mangling algorithm does not remember types on nested
   4555      argument lists, unless -fsquangling is used, and in that case the
   4556      type vector updated by remember_type is not used.  So, we turn
   4557      off remembering of types here.  */
   4558   ++work->forgetting_types;
   4559 
   4560   /* For the repeat codes used with -fsquangling, we must keep track of
   4561      the last argument.  */
   4562   saved_previous_argument = work->previous_argument;
   4563   saved_nrepeats = work->nrepeats;
   4564   work->previous_argument = 0;
   4565   work->nrepeats = 0;
   4566 
   4567   /* Actually demangle the arguments.  */
   4568   result = demangle_args (work, mangled, declp);
   4569 
   4570   /* Restore the previous_argument field.  */
   4571   if (work->previous_argument)
   4572     {
   4573       string_delete (work->previous_argument);
   4574       free ((char *) work->previous_argument);
   4575     }
   4576   work->previous_argument = saved_previous_argument;
   4577   --work->forgetting_types;
   4578   work->nrepeats = saved_nrepeats;
   4579 
   4580   return result;
   4581 }
   4582 
   4583 /* Returns 1 if a valid function name was found or 0 otherwise.  */
   4584 
   4585 static int
   4586 demangle_function_name (struct work_stuff *work, const char **mangled,
   4587                         string *declp, const char *scan)
   4588 {
   4589   size_t i;
   4590   string type;
   4591   const char *tem;
   4592 
   4593   string_appendn (declp, (*mangled), scan - (*mangled));
   4594   string_need (declp, 1);
   4595   *(declp -> p) = '\0';
   4596 
   4597   /* Consume the function name, including the "__" separating the name
   4598      from the signature.  We are guaranteed that SCAN points to the
   4599      separator.  */
   4600 
   4601   (*mangled) = scan + 2;
   4602   /* We may be looking at an instantiation of a template function:
   4603      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
   4604      following _F marks the start of the function arguments.  Handle
   4605      the template arguments first. */
   4606 
   4607   if (HP_DEMANGLING && (**mangled == 'X'))
   4608     {
   4609       demangle_arm_hp_template (work, mangled, 0, declp);
   4610       /* This leaves MANGLED pointing to the 'F' marking func args */
   4611     }
   4612 
   4613   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
   4614     {
   4615 
   4616       /* See if we have an ARM style constructor or destructor operator.
   4617 	 If so, then just record it, clear the decl, and return.
   4618 	 We can't build the actual constructor/destructor decl until later,
   4619 	 when we recover the class name from the signature.  */
   4620 
   4621       if (strcmp (declp -> b, "__ct") == 0)
   4622 	{
   4623 	  work -> constructor += 1;
   4624 	  string_clear (declp);
   4625 	  return 1;
   4626 	}
   4627       else if (strcmp (declp -> b, "__dt") == 0)
   4628 	{
   4629 	  work -> destructor += 1;
   4630 	  string_clear (declp);
   4631 	  return 1;
   4632 	}
   4633     }
   4634 
   4635   if (declp->p - declp->b >= 3
   4636       && declp->b[0] == 'o'
   4637       && declp->b[1] == 'p'
   4638       && strchr (cplus_markers, declp->b[2]) != NULL)
   4639     {
   4640       /* see if it's an assignment expression */
   4641       if (declp->p - declp->b >= 10 /* op$assign_ */
   4642 	  && memcmp (declp->b + 3, "assign_", 7) == 0)
   4643 	{
   4644 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
   4645 	    {
   4646 	      int len = declp->p - declp->b - 10;
   4647 	      if ((int) strlen (optable[i].in) == len
   4648 		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
   4649 		{
   4650 		  string_clear (declp);
   4651 		  string_append (declp, "operator");
   4652 		  string_append (declp, optable[i].out);
   4653 		  string_append (declp, "=");
   4654 		  break;
   4655 		}
   4656 	    }
   4657 	}
   4658       else
   4659 	{
   4660 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
   4661 	    {
   4662 	      int len = declp->p - declp->b - 3;
   4663 	      if ((int) strlen (optable[i].in) == len
   4664 		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
   4665 		{
   4666 		  string_clear (declp);
   4667 		  string_append (declp, "operator");
   4668 		  string_append (declp, optable[i].out);
   4669 		  break;
   4670 		}
   4671 	    }
   4672 	}
   4673     }
   4674   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
   4675 	   && strchr (cplus_markers, declp->b[4]) != NULL)
   4676     {
   4677       /* type conversion operator */
   4678       tem = declp->b + 5;
   4679       if (do_type (work, &tem, &type))
   4680 	{
   4681 	  string_clear (declp);
   4682 	  string_append (declp, "operator ");
   4683 	  string_appends (declp, &type);
   4684 	  string_delete (&type);
   4685 	}
   4686     }
   4687   else if (declp->b[0] == '_' && declp->b[1] == '_'
   4688 	   && declp->b[2] == 'o' && declp->b[3] == 'p')
   4689     {
   4690       /* ANSI.  */
   4691       /* type conversion operator.  */
   4692       tem = declp->b + 4;
   4693       if (do_type (work, &tem, &type))
   4694 	{
   4695 	  string_clear (declp);
   4696 	  string_append (declp, "operator ");
   4697 	  string_appends (declp, &type);
   4698 	  string_delete (&type);
   4699 	}
   4700     }
   4701   else if (declp->b[0] == '_' && declp->b[1] == '_'
   4702 	   && ISLOWER((unsigned char)declp->b[2])
   4703 	   && ISLOWER((unsigned char)declp->b[3]))
   4704     {
   4705       if (declp->b[4] == '\0')
   4706 	{
   4707 	  /* Operator.  */
   4708 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
   4709 	    {
   4710 	      if (strlen (optable[i].in) == 2
   4711 		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
   4712 		{
   4713 		  string_clear (declp);
   4714 		  string_append (declp, "operator");
   4715 		  string_append (declp, optable[i].out);
   4716 		  break;
   4717 		}
   4718 	    }
   4719 	}
   4720       else
   4721 	{
   4722 	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
   4723 	    {
   4724 	      /* Assignment.  */
   4725 	      for (i = 0; i < ARRAY_SIZE (optable); i++)
   4726 		{
   4727 		  if (strlen (optable[i].in) == 3
   4728 		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
   4729 		    {
   4730 		      string_clear (declp);
   4731 		      string_append (declp, "operator");
   4732 		      string_append (declp, optable[i].out);
   4733 		      break;
   4734 		    }
   4735 		}
   4736 	    }
   4737 	}
   4738     }
   4739 
   4740   /* If a function name was obtained but it's not valid, we were not
   4741      successful.  */
   4742   if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
   4743     return 0;
   4744   else
   4745     return 1;
   4746 }
   4747 
   4748 /* a mini string-handling package */
   4749 
   4750 static void
   4751 string_need (string *s, int n)
   4752 {
   4753   int tem;
   4754 
   4755   if (s->b == NULL)
   4756     {
   4757       if (n < 32)
   4758 	{
   4759 	  n = 32;
   4760 	}
   4761       s->p = s->b = XNEWVEC (char, n);
   4762       s->e = s->b + n;
   4763     }
   4764   else if (s->e - s->p < n)
   4765     {
   4766       tem = s->p - s->b;
   4767       n += tem;
   4768       n *= 2;
   4769       s->b = XRESIZEVEC (char, s->b, n);
   4770       s->p = s->b + tem;
   4771       s->e = s->b + n;
   4772     }
   4773 }
   4774 
   4775 static void
   4776 string_delete (string *s)
   4777 {
   4778   if (s->b != NULL)
   4779     {
   4780       free (s->b);
   4781       s->b = s->e = s->p = NULL;
   4782     }
   4783 }
   4784 
   4785 static void
   4786 string_init (string *s)
   4787 {
   4788   s->b = s->p = s->e = NULL;
   4789 }
   4790 
   4791 static void
   4792 string_clear (string *s)
   4793 {
   4794   s->p = s->b;
   4795 }
   4796 
   4797 #if 0
   4798 
   4799 static int
   4800 string_empty (string *s)
   4801 {
   4802   return (s->b == s->p);
   4803 }
   4804 
   4805 #endif
   4806 
   4807 static void
   4808 string_append (string *p, const char *s)
   4809 {
   4810   int n;
   4811   if (s == NULL || *s == '\0')
   4812     return;
   4813   n = strlen (s);
   4814   string_need (p, n);
   4815   memcpy (p->p, s, n);
   4816   p->p += n;
   4817 }
   4818 
   4819 static void
   4820 string_appends (string *p, string *s)
   4821 {
   4822   int n;
   4823 
   4824   if (s->b != s->p)
   4825     {
   4826       n = s->p - s->b;
   4827       string_need (p, n);
   4828       memcpy (p->p, s->b, n);
   4829       p->p += n;
   4830     }
   4831 }
   4832 
   4833 static void
   4834 string_appendn (string *p, const char *s, int n)
   4835 {
   4836   if (n != 0)
   4837     {
   4838       string_need (p, n);
   4839       memcpy (p->p, s, n);
   4840       p->p += n;
   4841     }
   4842 }
   4843 
   4844 static void
   4845 string_prepend (string *p, const char *s)
   4846 {
   4847   if (s != NULL && *s != '\0')
   4848     {
   4849       string_prependn (p, s, strlen (s));
   4850     }
   4851 }
   4852 
   4853 static void
   4854 string_prepends (string *p, string *s)
   4855 {
   4856   if (s->b != s->p)
   4857     {
   4858       string_prependn (p, s->b, s->p - s->b);
   4859     }
   4860 }
   4861 
   4862 static void
   4863 string_prependn (string *p, const char *s, int n)
   4864 {
   4865   char *q;
   4866 
   4867   if (n != 0)
   4868     {
   4869       string_need (p, n);
   4870       for (q = p->p - 1; q >= p->b; q--)
   4871 	{
   4872 	  q[n] = q[0];
   4873 	}
   4874       memcpy (p->b, s, n);
   4875       p->p += n;
   4876     }
   4877 }
   4878 
   4879 static void
   4880 string_append_template_idx (string *s, int idx)
   4881 {
   4882   char buf[INTBUF_SIZE + 1 /* 'T' */];
   4883   sprintf(buf, "T%d", idx);
   4884   string_append (s, buf);
   4885 }
   4886