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