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