This fixes a thinko in the LEON support recently added to the assembler.
[external/binutils.git] / libiberty / cplus-dem.c
1 /* Demangler for GNU C++
2    Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
4    Written by James Clark (jjc@jclark.uucp)
5    Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6    Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file.  (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
21 combined executable.)
22
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26 Library General Public License for more details.
27
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB.  If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA.  */
32
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
34
35    This file imports xmalloc and xrealloc, which are like malloc and
36    realloc except that they generate a fatal error if there is no
37    available memory.  */
38
39 /* This file lives in both GCC and libiberty.  When making changes, please
40    try not to break either.  */
41
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #include "safe-ctype.h"
47
48 #include <sys/types.h>
49 #include <string.h>
50 #include <stdio.h>
51
52 #ifdef HAVE_STDLIB_H
53 #include <stdlib.h>
54 #else
55 void * malloc ();
56 void * realloc ();
57 #endif
58
59 #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                   break;
3667               }
3668             else if (**mangled == 'Q')
3669               {
3670                 success = demangle_qualified (work, mangled, &decl,
3671                                               /*isfuncnam=*/0, 
3672                                               /*append=*/0);
3673                 if (!success)
3674                   break;
3675               }
3676             else
3677               {
3678                 success = 0;
3679                 break;
3680               }
3681
3682             string_prepend (&decl, "(");
3683             if (member)
3684               {
3685                 switch (**mangled)
3686                   {
3687                   case 'C':
3688                   case 'V':
3689                   case 'u':
3690                     type_quals |= code_for_qualifier (**mangled);
3691                     (*mangled)++;
3692                     break;
3693
3694                   default:
3695                     break;
3696                   }
3697
3698                 if (*(*mangled)++ != 'F')
3699                   {
3700                     success = 0;
3701                     break;
3702                   }
3703               }
3704             if ((member && !demangle_nested_args (work, mangled, &decl))
3705                 || **mangled != '_')
3706               {
3707                 success = 0;
3708                 break;
3709               }
3710             (*mangled)++;
3711             if (! PRINT_ANSI_QUALIFIERS)
3712               {
3713                 break;
3714               }
3715             if (type_quals != TYPE_UNQUALIFIED)
3716               {
3717                 APPEND_BLANK (&decl);
3718                 string_append (&decl, qualifier_string (type_quals));
3719               }
3720             break;
3721           }
3722         case 'G':
3723           (*mangled)++;
3724           break;
3725
3726         case 'C':
3727         case 'V':
3728         case 'u':
3729           if (PRINT_ANSI_QUALIFIERS)
3730             {
3731               if (!STRING_EMPTY (&decl))
3732                 string_prepend (&decl, " ");
3733
3734               string_prepend (&decl, demangle_qualifier (**mangled));
3735             }
3736           (*mangled)++;
3737           break;
3738           /*
3739             }
3740             */
3741
3742           /* fall through */
3743         default:
3744           done = 1;
3745           break;
3746         }
3747     }
3748
3749   if (success) switch (**mangled)
3750     {
3751       /* A qualified name, such as "Outer::Inner".  */
3752     case 'Q':
3753     case 'K':
3754       {
3755         success = demangle_qualified (work, mangled, result, 0, 1);
3756         break;
3757       }
3758
3759     /* A back reference to a previously seen squangled type */
3760     case 'B':
3761       (*mangled)++;
3762       if (!get_count (mangled, &n) || n >= work -> numb)
3763         success = 0;
3764       else
3765         string_append (result, work->btypevec[n]);
3766       break;
3767
3768     case 'X':
3769     case 'Y':
3770       /* A template parm.  We substitute the corresponding argument. */
3771       {
3772         int idx;
3773
3774         (*mangled)++;
3775         idx = consume_count_with_underscores (mangled);
3776
3777         if (idx == -1
3778             || (work->tmpl_argvec && idx >= work->ntmpl_args)
3779             || consume_count_with_underscores (mangled) == -1)
3780           {
3781             success = 0;
3782             break;
3783           }
3784
3785         if (work->tmpl_argvec)
3786           string_append (result, work->tmpl_argvec[idx]);
3787         else
3788           string_append_template_idx (result, idx);
3789
3790         success = 1;
3791       }
3792     break;
3793
3794     default:
3795       success = demangle_fund_type (work, mangled, result);
3796       if (tk == tk_none)
3797         tk = (type_kind_t) success;
3798       break;
3799     }
3800
3801   if (success)
3802     {
3803       if (!STRING_EMPTY (&decl))
3804         {
3805           string_append (result, " ");
3806           string_appends (result, &decl);
3807         }
3808     }
3809   else
3810     string_delete (result);
3811   string_delete (&decl);
3812
3813   if (success)
3814     /* Assume an integral type, if we're not sure.  */
3815     return (int) ((tk == tk_none) ? tk_integral : tk);
3816   else
3817     return 0;
3818 }
3819
3820 /* Given a pointer to a type string that represents a fundamental type
3821    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3822    string in which the demangled output is being built in RESULT, and
3823    the WORK structure, decode the types and add them to the result.
3824
3825    For example:
3826
3827         "Ci"    =>      "const int"
3828         "Sl"    =>      "signed long"
3829         "CUs"   =>      "const unsigned short"
3830
3831    The value returned is really a type_kind_t.  */
3832
3833 static int
3834 demangle_fund_type (struct work_stuff *work,
3835                     const char **mangled, string *result)
3836 {
3837   int done = 0;
3838   int success = 1;
3839   char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3840   unsigned int dec = 0;
3841   type_kind_t tk = tk_integral;
3842
3843   /* First pick off any type qualifiers.  There can be more than one.  */
3844
3845   while (!done)
3846     {
3847       switch (**mangled)
3848         {
3849         case 'C':
3850         case 'V':
3851         case 'u':
3852           if (PRINT_ANSI_QUALIFIERS)
3853             {
3854               if (!STRING_EMPTY (result))
3855                 string_prepend (result, " ");
3856               string_prepend (result, demangle_qualifier (**mangled));
3857             }
3858           (*mangled)++;
3859           break;
3860         case 'U':
3861           (*mangled)++;
3862           APPEND_BLANK (result);
3863           string_append (result, "unsigned");
3864           break;
3865         case 'S': /* signed char only */
3866           (*mangled)++;
3867           APPEND_BLANK (result);
3868           string_append (result, "signed");
3869           break;
3870         case 'J':
3871           (*mangled)++;
3872           APPEND_BLANK (result);
3873           string_append (result, "__complex");
3874           break;
3875         default:
3876           done = 1;
3877           break;
3878         }
3879     }
3880
3881   /* Now pick off the fundamental type.  There can be only one.  */
3882
3883   switch (**mangled)
3884     {
3885     case '\0':
3886     case '_':
3887       break;
3888     case 'v':
3889       (*mangled)++;
3890       APPEND_BLANK (result);
3891       string_append (result, "void");
3892       break;
3893     case 'x':
3894       (*mangled)++;
3895       APPEND_BLANK (result);
3896       string_append (result, "long long");
3897       break;
3898     case 'l':
3899       (*mangled)++;
3900       APPEND_BLANK (result);
3901       string_append (result, "long");
3902       break;
3903     case 'i':
3904       (*mangled)++;
3905       APPEND_BLANK (result);
3906       string_append (result, "int");
3907       break;
3908     case 's':
3909       (*mangled)++;
3910       APPEND_BLANK (result);
3911       string_append (result, "short");
3912       break;
3913     case 'b':
3914       (*mangled)++;
3915       APPEND_BLANK (result);
3916       string_append (result, "bool");
3917       tk = tk_bool;
3918       break;
3919     case 'c':
3920       (*mangled)++;
3921       APPEND_BLANK (result);
3922       string_append (result, "char");
3923       tk = tk_char;
3924       break;
3925     case 'w':
3926       (*mangled)++;
3927       APPEND_BLANK (result);
3928       string_append (result, "wchar_t");
3929       tk = tk_char;
3930       break;
3931     case 'r':
3932       (*mangled)++;
3933       APPEND_BLANK (result);
3934       string_append (result, "long double");
3935       tk = tk_real;
3936       break;
3937     case 'd':
3938       (*mangled)++;
3939       APPEND_BLANK (result);
3940       string_append (result, "double");
3941       tk = tk_real;
3942       break;
3943     case 'f':
3944       (*mangled)++;
3945       APPEND_BLANK (result);
3946       string_append (result, "float");
3947       tk = tk_real;
3948       break;
3949     case 'G':
3950       (*mangled)++;
3951       if (!ISDIGIT ((unsigned char)**mangled))
3952         {
3953           success = 0;
3954           break;
3955         }
3956     case 'I':
3957       (*mangled)++;
3958       if (**mangled == '_')
3959         {
3960           int i;
3961           (*mangled)++;
3962           for (i = 0;
3963                i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3964                (*mangled)++, i++)
3965             buf[i] = **mangled;
3966           if (**mangled != '_')
3967             {
3968               success = 0;
3969               break;
3970             }
3971           buf[i] = '\0';
3972           (*mangled)++;
3973         }
3974       else
3975         {
3976           strncpy (buf, *mangled, 2);
3977           buf[2] = '\0';
3978           *mangled += min (strlen (*mangled), 2);
3979         }
3980       sscanf (buf, "%x", &dec);
3981       sprintf (buf, "int%u_t", dec);
3982       APPEND_BLANK (result);
3983       string_append (result, buf);
3984       break;
3985
3986       /* fall through */
3987       /* An explicit type, such as "6mytype" or "7integer" */
3988     case '0':
3989     case '1':
3990     case '2':
3991     case '3':
3992     case '4':
3993     case '5':
3994     case '6':
3995     case '7':
3996     case '8':
3997     case '9':
3998       {
3999         int bindex = register_Btype (work);
4000         string btype;
4001         string_init (&btype);
4002         if (demangle_class_name (work, mangled, &btype)) {
4003           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
4004           APPEND_BLANK (result);
4005           string_appends (result, &btype);
4006         }
4007         else
4008           success = 0;
4009         string_delete (&btype);
4010         break;
4011       }
4012     case 't':
4013       {
4014         string btype;
4015         string_init (&btype);
4016         success = demangle_template (work, mangled, &btype, 0, 1, 1);
4017         string_appends (result, &btype);
4018         string_delete (&btype);
4019         break;
4020       }
4021     default:
4022       success = 0;
4023       break;
4024     }
4025
4026   return success ? ((int) tk) : 0;
4027 }
4028
4029
4030 /* Handle a template's value parameter for HP aCC (extension from ARM)
4031    **mangled points to 'S' or 'U' */
4032
4033 static int
4034 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
4035                                const char **mangled, string *result)
4036 {
4037   int unsigned_const;
4038
4039   if (**mangled != 'U' && **mangled != 'S')
4040     return 0;
4041
4042   unsigned_const = (**mangled == 'U');
4043
4044   (*mangled)++;
4045
4046   switch (**mangled)
4047     {
4048       case 'N':
4049         string_append (result, "-");
4050         /* fall through */
4051       case 'P':
4052         (*mangled)++;
4053         break;
4054       case 'M':
4055         /* special case for -2^31 */
4056         string_append (result, "-2147483648");
4057         (*mangled)++;
4058         return 1;
4059       default:
4060         return 0;
4061     }
4062
4063   /* We have to be looking at an integer now */
4064   if (!(ISDIGIT ((unsigned char)**mangled)))
4065     return 0;
4066
4067   /* We only deal with integral values for template
4068      parameters -- so it's OK to look only for digits */
4069   while (ISDIGIT ((unsigned char)**mangled))
4070     {
4071       char_str[0] = **mangled;
4072       string_append (result, char_str);
4073       (*mangled)++;
4074     }
4075
4076   if (unsigned_const)
4077     string_append (result, "U");
4078
4079   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4080      with L or LL suffixes. pai/1997-09-03 */
4081
4082   return 1; /* success */
4083 }
4084
4085 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4086    **mangled is pointing to the 'A' */
4087
4088 static int
4089 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
4090                            string *result)
4091 {
4092   int literal_len = 0;
4093   char * recurse;
4094   char * recurse_dem;
4095
4096   if (**mangled != 'A')
4097     return 0;
4098
4099   (*mangled)++;
4100
4101   literal_len = consume_count (mangled);
4102
4103   if (literal_len <= 0)
4104     return 0;
4105
4106   /* Literal parameters are names of arrays, functions, etc.  and the
4107      canonical representation uses the address operator */
4108   string_append (result, "&");
4109
4110   /* Now recursively demangle the literal name */
4111   recurse = XNEWVEC (char, literal_len + 1);
4112   memcpy (recurse, *mangled, literal_len);
4113   recurse[literal_len] = '\000';
4114
4115   recurse_dem = cplus_demangle (recurse, work->options);
4116
4117   if (recurse_dem)
4118     {
4119       string_append (result, recurse_dem);
4120       free (recurse_dem);
4121     }
4122   else
4123     {
4124       string_appendn (result, *mangled, literal_len);
4125     }
4126   (*mangled) += literal_len;
4127   free (recurse);
4128
4129   return 1;
4130 }
4131
4132 static int
4133 snarf_numeric_literal (const char **args, string *arg)
4134 {
4135   if (**args == '-')
4136     {
4137       char_str[0] = '-';
4138       string_append (arg, char_str);
4139       (*args)++;
4140     }
4141   else if (**args == '+')
4142     (*args)++;
4143
4144   if (!ISDIGIT ((unsigned char)**args))
4145     return 0;
4146
4147   while (ISDIGIT ((unsigned char)**args))
4148     {
4149       char_str[0] = **args;
4150       string_append (arg, char_str);
4151       (*args)++;
4152     }
4153
4154   return 1;
4155 }
4156
4157 /* Demangle the next argument, given by MANGLED into RESULT, which
4158    *should be an uninitialized* string.  It will be initialized here,
4159    and free'd should anything go wrong.  */
4160
4161 static int
4162 do_arg (struct work_stuff *work, const char **mangled, string *result)
4163 {
4164   /* Remember where we started so that we can record the type, for
4165      non-squangling type remembering.  */
4166   const char *start = *mangled;
4167
4168   string_init (result);
4169
4170   if (work->nrepeats > 0)
4171     {
4172       --work->nrepeats;
4173
4174       if (work->previous_argument == 0)
4175         return 0;
4176
4177       /* We want to reissue the previous type in this argument list.  */
4178       string_appends (result, work->previous_argument);
4179       return 1;
4180     }
4181
4182   if (**mangled == 'n')
4183     {
4184       /* A squangling-style repeat.  */
4185       (*mangled)++;
4186       work->nrepeats = consume_count(mangled);
4187
4188       if (work->nrepeats <= 0)
4189         /* This was not a repeat count after all.  */
4190         return 0;
4191
4192       if (work->nrepeats > 9)
4193         {
4194           if (**mangled != '_')
4195             /* The repeat count should be followed by an '_' in this
4196                case.  */
4197             return 0;
4198           else
4199             (*mangled)++;
4200         }
4201
4202       /* Now, the repeat is all set up.  */
4203       return do_arg (work, mangled, result);
4204     }
4205
4206   /* Save the result in WORK->previous_argument so that we can find it
4207      if it's repeated.  Note that saving START is not good enough: we
4208      do not want to add additional types to the back-referenceable
4209      type vector when processing a repeated type.  */
4210   if (work->previous_argument)
4211     string_delete (work->previous_argument);
4212   else
4213     work->previous_argument = XNEW (string);
4214
4215   if (!do_type (work, mangled, work->previous_argument))
4216     return 0;
4217
4218   string_appends (result, work->previous_argument);
4219
4220   remember_type (work, start, *mangled - start);
4221   return 1;
4222 }
4223
4224 static void
4225 remember_type (struct work_stuff *work, const char *start, int len)
4226 {
4227   char *tem;
4228
4229   if (work->forgetting_types)
4230     return;
4231
4232   if (work -> ntypes >= work -> typevec_size)
4233     {
4234       if (work -> typevec_size == 0)
4235         {
4236           work -> typevec_size = 3;
4237           work -> typevec = XNEWVEC (char *, work->typevec_size);
4238         }
4239       else
4240         {
4241           work -> typevec_size *= 2;
4242           work -> typevec
4243             = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4244         }
4245     }
4246   tem = XNEWVEC (char, len + 1);
4247   memcpy (tem, start, len);
4248   tem[len] = '\0';
4249   work -> typevec[work -> ntypes++] = tem;
4250 }
4251
4252
4253 /* Remember a K type class qualifier. */
4254 static void
4255 remember_Ktype (struct work_stuff *work, const char *start, int len)
4256 {
4257   char *tem;
4258
4259   if (work -> numk >= work -> ksize)
4260     {
4261       if (work -> ksize == 0)
4262         {
4263           work -> ksize = 5;
4264           work -> ktypevec = XNEWVEC (char *, work->ksize);
4265         }
4266       else
4267         {
4268           work -> ksize *= 2;
4269           work -> ktypevec
4270             = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4271         }
4272     }
4273   tem = XNEWVEC (char, len + 1);
4274   memcpy (tem, start, len);
4275   tem[len] = '\0';
4276   work -> ktypevec[work -> numk++] = tem;
4277 }
4278
4279 /* Register a B code, and get an index for it. B codes are registered
4280    as they are seen, rather than as they are completed, so map<temp<char> >
4281    registers map<temp<char> > as B0, and temp<char> as B1 */
4282
4283 static int
4284 register_Btype (struct work_stuff *work)
4285 {
4286   int ret;
4287
4288   if (work -> numb >= work -> bsize)
4289     {
4290       if (work -> bsize == 0)
4291         {
4292           work -> bsize = 5;
4293           work -> btypevec = XNEWVEC (char *, work->bsize);
4294         }
4295       else
4296         {
4297           work -> bsize *= 2;
4298           work -> btypevec
4299             = XRESIZEVEC (char *, work->btypevec, work->bsize);
4300         }
4301     }
4302   ret = work -> numb++;
4303   work -> btypevec[ret] = NULL;
4304   return(ret);
4305 }
4306
4307 /* Store a value into a previously registered B code type. */
4308
4309 static void
4310 remember_Btype (struct work_stuff *work, const char *start,
4311                 int len, int index)
4312 {
4313   char *tem;
4314
4315   tem = XNEWVEC (char, len + 1);
4316   memcpy (tem, start, len);
4317   tem[len] = '\0';
4318   work -> btypevec[index] = tem;
4319 }
4320
4321 /* Lose all the info related to B and K type codes. */
4322 static void
4323 forget_B_and_K_types (struct work_stuff *work)
4324 {
4325   int i;
4326
4327   while (work -> numk > 0)
4328     {
4329       i = --(work -> numk);
4330       if (work -> ktypevec[i] != NULL)
4331         {
4332           free (work -> ktypevec[i]);
4333           work -> ktypevec[i] = NULL;
4334         }
4335     }
4336
4337   while (work -> numb > 0)
4338     {
4339       i = --(work -> numb);
4340       if (work -> btypevec[i] != NULL)
4341         {
4342           free (work -> btypevec[i]);
4343           work -> btypevec[i] = NULL;
4344         }
4345     }
4346 }
4347 /* Forget the remembered types, but not the type vector itself.  */
4348
4349 static void
4350 forget_types (struct work_stuff *work)
4351 {
4352   int i;
4353
4354   while (work -> ntypes > 0)
4355     {
4356       i = --(work -> ntypes);
4357       if (work -> typevec[i] != NULL)
4358         {
4359           free (work -> typevec[i]);
4360           work -> typevec[i] = NULL;
4361         }
4362     }
4363 }
4364
4365 /* Process the argument list part of the signature, after any class spec
4366    has been consumed, as well as the first 'F' character (if any).  For
4367    example:
4368
4369    "__als__3fooRT0"             =>      process "RT0"
4370    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
4371
4372    DECLP must be already initialised, usually non-empty.  It won't be freed
4373    on failure.
4374
4375    Note that g++ differs significantly from ARM and lucid style mangling
4376    with regards to references to previously seen types.  For example, given
4377    the source fragment:
4378
4379      class foo {
4380        public:
4381        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4382      };
4383
4384      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4385      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4386
4387    g++ produces the names:
4388
4389      __3fooiRT0iT2iT2
4390      foo__FiR3fooiT1iT1
4391
4392    while lcc (and presumably other ARM style compilers as well) produces:
4393
4394      foo__FiR3fooT1T2T1T2
4395      __ct__3fooFiR3fooT1T2T1T2
4396
4397    Note that g++ bases its type numbers starting at zero and counts all
4398    previously seen types, while lucid/ARM bases its type numbers starting
4399    at one and only considers types after it has seen the 'F' character
4400    indicating the start of the function args.  For lucid/ARM style, we
4401    account for this difference by discarding any previously seen types when
4402    we see the 'F' character, and subtracting one from the type number
4403    reference.
4404
4405  */
4406
4407 static int
4408 demangle_args (struct work_stuff *work, const char **mangled,
4409                string *declp)
4410 {
4411   string arg;
4412   int need_comma = 0;
4413   int r;
4414   int t;
4415   const char *tem;
4416   char temptype;
4417
4418   if (PRINT_ARG_TYPES)
4419     {
4420       string_append (declp, "(");
4421       if (**mangled == '\0')
4422         {
4423           string_append (declp, "void");
4424         }
4425     }
4426
4427   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4428          || work->nrepeats > 0)
4429     {
4430       if ((**mangled == 'N') || (**mangled == 'T'))
4431         {
4432           temptype = *(*mangled)++;
4433
4434           if (temptype == 'N')
4435             {
4436               if (!get_count (mangled, &r))
4437                 {
4438                   return (0);
4439                 }
4440             }
4441           else
4442             {
4443               r = 1;
4444             }
4445           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4446             {
4447               /* If we have 10 or more types we might have more than a 1 digit
4448                  index so we'll have to consume the whole count here. This
4449                  will lose if the next thing is a type name preceded by a
4450                  count but it's impossible to demangle that case properly
4451                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4452                  Pc, ...)"  or "(..., type12, char *, ...)" */
4453               if ((t = consume_count(mangled)) <= 0)
4454                 {
4455                   return (0);
4456                 }
4457             }
4458           else
4459             {
4460               if (!get_count (mangled, &t))
4461                 {
4462                   return (0);
4463                 }
4464             }
4465           if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4466             {
4467               t--;
4468             }
4469           /* Validate the type index.  Protect against illegal indices from
4470              malformed type strings.  */
4471           if ((t < 0) || (t >= work -> ntypes))
4472             {
4473               return (0);
4474             }
4475           while (work->nrepeats > 0 || --r >= 0)
4476             {
4477               tem = work -> typevec[t];
4478               if (need_comma && PRINT_ARG_TYPES)
4479                 {
4480                   string_append (declp, ", ");
4481                 }
4482               if (!do_arg (work, &tem, &arg))
4483                 {
4484                   return (0);
4485                 }
4486               if (PRINT_ARG_TYPES)
4487                 {
4488                   string_appends (declp, &arg);
4489                 }
4490               string_delete (&arg);
4491               need_comma = 1;
4492             }
4493         }
4494       else
4495         {
4496           if (need_comma && PRINT_ARG_TYPES)
4497             string_append (declp, ", ");
4498           if (!do_arg (work, mangled, &arg))
4499             return (0);
4500           if (PRINT_ARG_TYPES)
4501             string_appends (declp, &arg);
4502           string_delete (&arg);
4503           need_comma = 1;
4504         }
4505     }
4506
4507   if (**mangled == 'e')
4508     {
4509       (*mangled)++;
4510       if (PRINT_ARG_TYPES)
4511         {
4512           if (need_comma)
4513             {
4514               string_append (declp, ",");
4515             }
4516           string_append (declp, "...");
4517         }
4518     }
4519
4520   if (PRINT_ARG_TYPES)
4521     {
4522       string_append (declp, ")");
4523     }
4524   return (1);
4525 }
4526
4527 /* Like demangle_args, but for demangling the argument lists of function
4528    and method pointers or references, not top-level declarations.  */
4529
4530 static int
4531 demangle_nested_args (struct work_stuff *work, const char **mangled,
4532                       string *declp)
4533 {
4534   string* saved_previous_argument;
4535   int result;
4536   int saved_nrepeats;
4537
4538   /* The G++ name-mangling algorithm does not remember types on nested
4539      argument lists, unless -fsquangling is used, and in that case the
4540      type vector updated by remember_type is not used.  So, we turn
4541      off remembering of types here.  */
4542   ++work->forgetting_types;
4543
4544   /* For the repeat codes used with -fsquangling, we must keep track of
4545      the last argument.  */
4546   saved_previous_argument = work->previous_argument;
4547   saved_nrepeats = work->nrepeats;
4548   work->previous_argument = 0;
4549   work->nrepeats = 0;
4550
4551   /* Actually demangle the arguments.  */
4552   result = demangle_args (work, mangled, declp);
4553
4554   /* Restore the previous_argument field.  */
4555   if (work->previous_argument)
4556     {
4557       string_delete (work->previous_argument);
4558       free ((char *) work->previous_argument);
4559     }
4560   work->previous_argument = saved_previous_argument;
4561   --work->forgetting_types;
4562   work->nrepeats = saved_nrepeats;
4563
4564   return result;
4565 }
4566
4567 /* Returns 1 if a valid function name was found or 0 otherwise.  */
4568
4569 static int 
4570 demangle_function_name (struct work_stuff *work, const char **mangled,
4571                         string *declp, const char *scan)
4572 {
4573   size_t i;
4574   string type;
4575   const char *tem;
4576
4577   string_appendn (declp, (*mangled), scan - (*mangled));
4578   string_need (declp, 1);
4579   *(declp -> p) = '\0';
4580
4581   /* Consume the function name, including the "__" separating the name
4582      from the signature.  We are guaranteed that SCAN points to the
4583      separator.  */
4584
4585   (*mangled) = scan + 2;
4586   /* We may be looking at an instantiation of a template function:
4587      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4588      following _F marks the start of the function arguments.  Handle
4589      the template arguments first. */
4590
4591   if (HP_DEMANGLING && (**mangled == 'X'))
4592     {
4593       demangle_arm_hp_template (work, mangled, 0, declp);
4594       /* This leaves MANGLED pointing to the 'F' marking func args */
4595     }
4596
4597   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4598     {
4599
4600       /* See if we have an ARM style constructor or destructor operator.
4601          If so, then just record it, clear the decl, and return.
4602          We can't build the actual constructor/destructor decl until later,
4603          when we recover the class name from the signature.  */
4604
4605       if (strcmp (declp -> b, "__ct") == 0)
4606         {
4607           work -> constructor += 1;
4608           string_clear (declp);
4609           return 1;
4610         }
4611       else if (strcmp (declp -> b, "__dt") == 0)
4612         {
4613           work -> destructor += 1;
4614           string_clear (declp);
4615           return 1;
4616         }
4617     }
4618
4619   if (declp->p - declp->b >= 3
4620       && declp->b[0] == 'o'
4621       && declp->b[1] == 'p'
4622       && strchr (cplus_markers, declp->b[2]) != NULL)
4623     {
4624       /* see if it's an assignment expression */
4625       if (declp->p - declp->b >= 10 /* op$assign_ */
4626           && memcmp (declp->b + 3, "assign_", 7) == 0)
4627         {
4628           for (i = 0; i < ARRAY_SIZE (optable); i++)
4629             {
4630               int len = declp->p - declp->b - 10;
4631               if ((int) strlen (optable[i].in) == len
4632                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
4633                 {
4634                   string_clear (declp);
4635                   string_append (declp, "operator");
4636                   string_append (declp, optable[i].out);
4637                   string_append (declp, "=");
4638                   break;
4639                 }
4640             }
4641         }
4642       else
4643         {
4644           for (i = 0; i < ARRAY_SIZE (optable); i++)
4645             {
4646               int len = declp->p - declp->b - 3;
4647               if ((int) strlen (optable[i].in) == len
4648                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
4649                 {
4650                   string_clear (declp);
4651                   string_append (declp, "operator");
4652                   string_append (declp, optable[i].out);
4653                   break;
4654                 }
4655             }
4656         }
4657     }
4658   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4659            && strchr (cplus_markers, declp->b[4]) != NULL)
4660     {
4661       /* type conversion operator */
4662       tem = declp->b + 5;
4663       if (do_type (work, &tem, &type))
4664         {
4665           string_clear (declp);
4666           string_append (declp, "operator ");
4667           string_appends (declp, &type);
4668           string_delete (&type);
4669         }
4670     }
4671   else if (declp->b[0] == '_' && declp->b[1] == '_'
4672            && declp->b[2] == 'o' && declp->b[3] == 'p')
4673     {
4674       /* ANSI.  */
4675       /* type conversion operator.  */
4676       tem = declp->b + 4;
4677       if (do_type (work, &tem, &type))
4678         {
4679           string_clear (declp);
4680           string_append (declp, "operator ");
4681           string_appends (declp, &type);
4682           string_delete (&type);
4683         }
4684     }
4685   else if (declp->b[0] == '_' && declp->b[1] == '_'
4686            && ISLOWER((unsigned char)declp->b[2])
4687            && ISLOWER((unsigned char)declp->b[3]))
4688     {
4689       if (declp->b[4] == '\0')
4690         {
4691           /* Operator.  */
4692           for (i = 0; i < ARRAY_SIZE (optable); i++)
4693             {
4694               if (strlen (optable[i].in) == 2
4695                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4696                 {
4697                   string_clear (declp);
4698                   string_append (declp, "operator");
4699                   string_append (declp, optable[i].out);
4700                   break;
4701                 }
4702             }
4703         }
4704       else
4705         {
4706           if (declp->b[2] == 'a' && declp->b[5] == '\0')
4707             {
4708               /* Assignment.  */
4709               for (i = 0; i < ARRAY_SIZE (optable); i++)
4710                 {
4711                   if (strlen (optable[i].in) == 3
4712                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4713                     {
4714                       string_clear (declp);
4715                       string_append (declp, "operator");
4716                       string_append (declp, optable[i].out);
4717                       break;
4718                     }
4719                 }
4720             }
4721         }
4722     }
4723
4724   /* If a function name was obtained but it's not valid, we were not
4725      successful.  */
4726   if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
4727     return 0;
4728   else
4729     return 1;
4730 }
4731
4732 /* a mini string-handling package */
4733
4734 static void
4735 string_need (string *s, int n)
4736 {
4737   int tem;
4738
4739   if (s->b == NULL)
4740     {
4741       if (n < 32)
4742         {
4743           n = 32;
4744         }
4745       s->p = s->b = XNEWVEC (char, n);
4746       s->e = s->b + n;
4747     }
4748   else if (s->e - s->p < n)
4749     {
4750       tem = s->p - s->b;
4751       n += tem;
4752       n *= 2;
4753       s->b = XRESIZEVEC (char, s->b, n);
4754       s->p = s->b + tem;
4755       s->e = s->b + n;
4756     }
4757 }
4758
4759 static void
4760 string_delete (string *s)
4761 {
4762   if (s->b != NULL)
4763     {
4764       free (s->b);
4765       s->b = s->e = s->p = NULL;
4766     }
4767 }
4768
4769 static void
4770 string_init (string *s)
4771 {
4772   s->b = s->p = s->e = NULL;
4773 }
4774
4775 static void
4776 string_clear (string *s)
4777 {
4778   s->p = s->b;
4779 }
4780
4781 #if 0
4782
4783 static int
4784 string_empty (string *s)
4785 {
4786   return (s->b == s->p);
4787 }
4788
4789 #endif
4790
4791 static void
4792 string_append (string *p, const char *s)
4793 {
4794   int n;
4795   if (s == NULL || *s == '\0')
4796     return;
4797   n = strlen (s);
4798   string_need (p, n);
4799   memcpy (p->p, s, n);
4800   p->p += n;
4801 }
4802
4803 static void
4804 string_appends (string *p, string *s)
4805 {
4806   int n;
4807
4808   if (s->b != s->p)
4809     {
4810       n = s->p - s->b;
4811       string_need (p, n);
4812       memcpy (p->p, s->b, n);
4813       p->p += n;
4814     }
4815 }
4816
4817 static void
4818 string_appendn (string *p, const char *s, int n)
4819 {
4820   if (n != 0)
4821     {
4822       string_need (p, n);
4823       memcpy (p->p, s, n);
4824       p->p += n;
4825     }
4826 }
4827
4828 static void
4829 string_prepend (string *p, const char *s)
4830 {
4831   if (s != NULL && *s != '\0')
4832     {
4833       string_prependn (p, s, strlen (s));
4834     }
4835 }
4836
4837 static void
4838 string_prepends (string *p, string *s)
4839 {
4840   if (s->b != s->p)
4841     {
4842       string_prependn (p, s->b, s->p - s->b);
4843     }
4844 }
4845
4846 static void
4847 string_prependn (string *p, const char *s, int n)
4848 {
4849   char *q;
4850
4851   if (n != 0)
4852     {
4853       string_need (p, n);
4854       for (q = p->p - 1; q >= p->b; q--)
4855         {
4856           q[n] = q[0];
4857         }
4858       memcpy (p->b, s, n);
4859       p->p += n;
4860     }
4861 }
4862
4863 static void
4864 string_append_template_idx (string *s, int idx)
4865 {
4866   char buf[INTBUF_SIZE + 1 /* 'T' */];
4867   sprintf(buf, "T%d", idx);
4868   string_append (s, buf);
4869 }