OSDN Git Service

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