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