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