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