"Fossies" - the Fresh Open Source Software Archive

Member "mpr-2.8/demangle/cplus-dem.c" (11 Mar 2003, 120025 Bytes) of package /linux/misc/old/mpr-2.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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