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