OSDN Git Service

* config.sub: Import from master repository
[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               }
1433             oldmangled = NULL;
1434             expect_func = 1;
1435           }
1436           break;
1437
1438         case 'F':
1439           /* Function */
1440           /* ARM/HP style demangling includes a specific 'F' character after
1441              the class name.  For GNU style, it is just implied.  So we can
1442              safely just consume any 'F' at this point and be compatible
1443              with either style.  */
1444
1445           oldmangled = NULL;
1446           func_done = 1;
1447           (*mangled)++;
1448
1449           /* For lucid/ARM/HP style we have to forget any types we might
1450              have remembered up to this point, since they were not argument
1451              types.  GNU style considers all types seen as available for
1452              back references.  See comment in demangle_args() */
1453
1454           if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1455             {
1456               forget_types (work);
1457             }
1458           success = demangle_args (work, mangled, declp);
1459           /* After picking off the function args, we expect to either
1460              find the function return type (preceded by an '_') or the
1461              end of the string. */
1462           if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1463             {
1464               ++(*mangled);
1465               /* At this level, we do not care about the return type. */
1466               success = do_type (work, mangled, &tname);
1467               string_delete (&tname);
1468             }
1469
1470           break;
1471
1472         case 't':
1473           /* G++ Template */
1474           string_init(&trawname);
1475           string_init(&tname);
1476           if (oldmangled == NULL)
1477             {
1478               oldmangled = *mangled;
1479             }
1480           success = demangle_template (work, mangled, &tname,
1481                                        &trawname, 1, 1);
1482           if (success)
1483             {
1484               remember_type (work, oldmangled, *mangled - oldmangled);
1485             }
1486           string_append (&tname, SCOPE_STRING (work));
1487
1488           string_prepends(declp, &tname);
1489           if (work -> destructor & 1)
1490             {
1491               string_prepend (&trawname, "~");
1492               string_appends (declp, &trawname);
1493               work->destructor -= 1;
1494             }
1495           if ((work->constructor & 1) || (work->destructor & 1))
1496             {
1497               string_appends (declp, &trawname);
1498               work->constructor -= 1;
1499             }
1500           string_delete(&trawname);
1501           string_delete(&tname);
1502           oldmangled = NULL;
1503           expect_func = 1;
1504           break;
1505
1506         case '_':
1507           if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1508             {
1509               /* Read the return type. */
1510               string return_type;
1511               string_init (&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_clear (&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_clear (&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_append (&arg, ")");
2397             if (*args != 'L')
2398               goto cfront_template_args_done;
2399             args++;
2400             /* Now snarf a literal value following 'L' */
2401             if (!snarf_numeric_literal (&args, &arg))
2402               goto cfront_template_args_done;
2403             break;
2404
2405           case 'L':
2406             /* Snarf a literal following 'L' */
2407             args++;
2408             if (!snarf_numeric_literal (&args, &arg))
2409               goto cfront_template_args_done;
2410             break;
2411           default:
2412             /* Not handling other HP cfront stuff */
2413             {
2414               const char* old_args = args;
2415               if (!do_type (work, &args, &arg))
2416                 goto cfront_template_args_done;
2417
2418               /* Fail if we didn't make any progress: prevent infinite loop. */
2419               if (args == old_args)
2420                 return;
2421             }
2422           }
2423         string_appends (declp, &arg);
2424         string_append (declp, ",");
2425       }
2426     cfront_template_args_done:
2427       string_delete (&arg);
2428       if (args >= e)
2429         --declp->p; /* remove extra comma */
2430       string_append (declp, ">");
2431     }
2432   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2433            && (*mangled)[9] == 'N'
2434            && (*mangled)[8] == (*mangled)[10]
2435            && strchr (cplus_markers, (*mangled)[8]))
2436     {
2437       /* A member of the anonymous namespace.  */
2438       string_append (declp, "{anonymous}");
2439     }
2440   else
2441     {
2442       if (work->temp_start == -1) /* non-recursive call only */
2443         work->temp_start = 0;     /* disable in recursive calls */
2444       string_appendn (declp, *mangled, n);
2445     }
2446   *mangled += n;
2447 }
2448
2449 /* Extract a class name, possibly a template with arguments, from the
2450    mangled string; qualifiers, local class indicators, etc. have
2451    already been dealt with */
2452
2453 static int
2454 demangle_class_name (work, mangled, declp)
2455      struct work_stuff *work;
2456      const char **mangled;
2457      string *declp;
2458 {
2459   int n;
2460   int success = 0;
2461
2462   n = consume_count (mangled);
2463   if (n == -1)
2464     return 0;
2465   if ((int) strlen (*mangled) >= n)
2466     {
2467       demangle_arm_hp_template (work, mangled, n, declp);
2468       success = 1;
2469     }
2470
2471   return (success);
2472 }
2473
2474 /*
2475
2476 LOCAL FUNCTION
2477
2478         demangle_class -- demangle a mangled class sequence
2479
2480 SYNOPSIS
2481
2482         static int
2483         demangle_class (struct work_stuff *work, const char **mangled,
2484                         strint *declp)
2485
2486 DESCRIPTION
2487
2488         DECLP points to the buffer into which demangling is being done.
2489
2490         *MANGLED points to the current token to be demangled.  On input,
2491         it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2492         On exit, it points to the next token after the mangled class on
2493         success, or the first unconsumed token on failure.
2494
2495         If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2496         we are demangling a constructor or destructor.  In this case
2497         we prepend "class::class" or "class::~class" to DECLP.
2498
2499         Otherwise, we prepend "class::" to the current DECLP.
2500
2501         Reset the constructor/destructor flags once they have been
2502         "consumed".  This allows demangle_class to be called later during
2503         the same demangling, to do normal class demangling.
2504
2505         Returns 1 if demangling is successful, 0 otherwise.
2506
2507 */
2508
2509 static int
2510 demangle_class (work, mangled, declp)
2511      struct work_stuff *work;
2512      const char **mangled;
2513      string *declp;
2514 {
2515   int success = 0;
2516   int btype;
2517   string class_name;
2518   char *save_class_name_end = 0;
2519
2520   string_init (&class_name);
2521   btype = register_Btype (work);
2522   if (demangle_class_name (work, mangled, &class_name))
2523     {
2524       save_class_name_end = class_name.p;
2525       if ((work->constructor & 1) || (work->destructor & 1))
2526         {
2527           /* adjust so we don't include template args */
2528           if (work->temp_start && (work->temp_start != -1))
2529             {
2530               class_name.p = class_name.b + work->temp_start;
2531             }
2532           string_prepends (declp, &class_name);
2533           if (work -> destructor & 1)
2534             {
2535               string_prepend (declp, "~");
2536               work -> destructor -= 1;
2537             }
2538           else
2539             {
2540               work -> constructor -= 1;
2541             }
2542         }
2543       class_name.p = save_class_name_end;
2544       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2545       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2546       string_prepend (declp, SCOPE_STRING (work));
2547       string_prepends (declp, &class_name);
2548       success = 1;
2549     }
2550   string_delete (&class_name);
2551   return (success);
2552 }
2553
2554
2555 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2556    the rightmost guess.
2557
2558    Find the correct "__"-sequence where the function name ends and the
2559    signature starts, which is ambiguous with GNU mangling.
2560    Call demangle_signature here, so we can make sure we found the right
2561    one; *mangled will be consumed so caller will not make further calls to
2562    demangle_signature.  */
2563
2564 static int
2565 iterate_demangle_function (work, mangled, declp, scan)
2566      struct work_stuff *work;
2567      const char **mangled;
2568      string *declp;
2569      const char *scan;
2570 {
2571   const char *mangle_init = *mangled;
2572   int success = 0;
2573   string decl_init;
2574   struct work_stuff work_init;
2575
2576   if (*(scan + 2) == '\0')
2577     return 0;
2578
2579   /* Do not iterate for some demangling modes, or if there's only one
2580      "__"-sequence.  This is the normal case.  */
2581   if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2582       || strstr (scan + 2, "__") == NULL)
2583     {
2584       demangle_function_name (work, mangled, declp, scan);
2585       return 1;
2586     }
2587
2588   /* Save state so we can restart if the guess at the correct "__" was
2589      wrong.  */
2590   string_init (&decl_init);
2591   string_appends (&decl_init, declp);
2592   memset (&work_init, 0, sizeof work_init);
2593   work_stuff_copy_to_from (&work_init, work);
2594
2595   /* Iterate over occurrences of __, allowing names and types to have a
2596      "__" sequence in them.  We must start with the first (not the last)
2597      occurrence, since "__" most often occur between independent mangled
2598      parts, hence starting at the last occurence inside a signature
2599      might get us a "successful" demangling of the signature.  */
2600
2601   while (scan[2])
2602     {
2603       demangle_function_name (work, mangled, declp, scan);
2604       success = demangle_signature (work, mangled, declp);
2605       if (success)
2606         break;
2607
2608       /* Reset demangle state for the next round.  */
2609       *mangled = mangle_init;
2610       string_clear (declp);
2611       string_appends (declp, &decl_init);
2612       work_stuff_copy_to_from (work, &work_init);
2613
2614       /* Leave this underscore-sequence.  */
2615       scan += 2;
2616
2617       /* Scan for the next "__" sequence.  */
2618       while (*scan && (scan[0] != '_' || scan[1] != '_'))
2619         scan++;
2620
2621       /* Move to last "__" in this sequence.  */
2622       while (*scan && *scan == '_')
2623         scan++;
2624       scan -= 2;
2625     }
2626
2627   /* Delete saved state.  */
2628   delete_work_stuff (&work_init);
2629   string_delete (&decl_init);
2630
2631   return success;
2632 }
2633
2634 /*
2635
2636 LOCAL FUNCTION
2637
2638         demangle_prefix -- consume the mangled name prefix and find signature
2639
2640 SYNOPSIS
2641
2642         static int
2643         demangle_prefix (struct work_stuff *work, const char **mangled,
2644                          string *declp);
2645
2646 DESCRIPTION
2647
2648         Consume and demangle the prefix of the mangled name.
2649         While processing the function name root, arrange to call
2650         demangle_signature if the root is ambiguous.
2651
2652         DECLP points to the string buffer into which demangled output is
2653         placed.  On entry, the buffer is empty.  On exit it contains
2654         the root function name, the demangled operator name, or in some
2655         special cases either nothing or the completely demangled result.
2656
2657         MANGLED points to the current pointer into the mangled name.  As each
2658         token of the mangled name is consumed, it is updated.  Upon entry
2659         the current mangled name pointer points to the first character of
2660         the mangled name.  Upon exit, it should point to the first character
2661         of the signature if demangling was successful, or to the first
2662         unconsumed character if demangling of the prefix was unsuccessful.
2663
2664         Returns 1 on success, 0 otherwise.
2665  */
2666
2667 static int
2668 demangle_prefix (work, mangled, declp)
2669      struct work_stuff *work;
2670      const char **mangled;
2671      string *declp;
2672 {
2673   int success = 1;
2674   const char *scan;
2675   int i;
2676
2677   if (strlen(*mangled) > 6
2678       && (strncmp(*mangled, "_imp__", 6) == 0
2679           || strncmp(*mangled, "__imp_", 6) == 0))
2680     {
2681       /* it's a symbol imported from a PE dynamic library. Check for both
2682          new style prefix _imp__ and legacy __imp_ used by older versions
2683          of dlltool. */
2684       (*mangled) += 6;
2685       work->dllimported = 1;
2686     }
2687   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2688     {
2689       char *marker = strchr (cplus_markers, (*mangled)[8]);
2690       if (marker != NULL && *marker == (*mangled)[10])
2691         {
2692           if ((*mangled)[9] == 'D')
2693             {
2694               /* it's a GNU global destructor to be executed at program exit */
2695               (*mangled) += 11;
2696               work->destructor = 2;
2697               if (gnu_special (work, mangled, declp))
2698                 return success;
2699             }
2700           else if ((*mangled)[9] == 'I')
2701             {
2702               /* it's a GNU global constructor to be executed at program init */
2703               (*mangled) += 11;
2704               work->constructor = 2;
2705               if (gnu_special (work, mangled, declp))
2706                 return success;
2707             }
2708         }
2709     }
2710   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2711     {
2712       /* it's a ARM global destructor to be executed at program exit */
2713       (*mangled) += 7;
2714       work->destructor = 2;
2715     }
2716   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2717     {
2718       /* it's a ARM global constructor to be executed at program initial */
2719       (*mangled) += 7;
2720       work->constructor = 2;
2721     }
2722
2723   /*  This block of code is a reduction in strength time optimization
2724       of:
2725       scan = strstr (*mangled, "__"); */
2726
2727   {
2728     scan = *mangled;
2729
2730     do {
2731       scan = strchr (scan, '_');
2732     } while (scan != NULL && *++scan != '_');
2733
2734     if (scan != NULL) --scan;
2735   }
2736
2737   if (scan != NULL)
2738     {
2739       /* We found a sequence of two or more '_', ensure that we start at
2740          the last pair in the sequence.  */
2741       i = strspn (scan, "_");
2742       if (i > 2)
2743         {
2744           scan += (i - 2);
2745         }
2746     }
2747
2748   if (scan == NULL)
2749     {
2750       success = 0;
2751     }
2752   else if (work -> static_type)
2753     {
2754       if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2755         {
2756           success = 0;
2757         }
2758     }
2759   else if ((scan == *mangled)
2760            && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2761                || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2762     {
2763       /* The ARM says nothing about the mangling of local variables.
2764          But cfront mangles local variables by prepending __<nesting_level>
2765          to them. As an extension to ARM demangling we handle this case.  */
2766       if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2767           && ISDIGIT ((unsigned char)scan[2]))
2768         {
2769           *mangled = scan + 2;
2770           consume_count (mangled);
2771           string_append (declp, *mangled);
2772           *mangled += strlen (*mangled);
2773           success = 1;
2774         }
2775       else
2776         {
2777           /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2778              names like __Q2_3foo3bar for nested type names.  So don't accept
2779              this style of constructor for cfront demangling.  A GNU
2780              style member-template constructor starts with 'H'. */
2781           if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2782             work -> constructor += 1;
2783           *mangled = scan + 2;
2784         }
2785     }
2786   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2787     {
2788       /* Cfront-style parameterized type.  Handled later as a signature. */
2789       success = 1;
2790
2791       /* ARM template? */
2792       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2793     }
2794   else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2795                               || (scan[2] == 'p' && scan[3] == 's')
2796                               || (scan[2] == 'p' && scan[3] == 't')))
2797     {
2798       /* EDG-style parameterized type.  Handled later as a signature. */
2799       success = 1;
2800
2801       /* EDG template? */
2802       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2803     }
2804   else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2805            && (scan[2] != 't'))
2806     {
2807       /* Mangled name starts with "__".  Skip over any leading '_' characters,
2808          then find the next "__" that separates the prefix from the signature.
2809          */
2810       if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2811           || (arm_special (mangled, declp) == 0))
2812         {
2813           while (*scan == '_')
2814             {
2815               scan++;
2816             }
2817           if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2818             {
2819               /* No separator (I.E. "__not_mangled"), or empty signature
2820                  (I.E. "__not_mangled_either__") */
2821               success = 0;
2822             }
2823           else
2824             return iterate_demangle_function (work, mangled, declp, scan);
2825         }
2826     }
2827   else if (*(scan + 2) != '\0')
2828     {
2829       /* Mangled name does not start with "__" but does have one somewhere
2830          in there with non empty stuff after it.  Looks like a global
2831          function name.  Iterate over all "__":s until the right
2832          one is found.  */
2833       return iterate_demangle_function (work, mangled, declp, scan);
2834     }
2835   else
2836     {
2837       /* Doesn't look like a mangled name */
2838       success = 0;
2839     }
2840
2841   if (!success && (work->constructor == 2 || work->destructor == 2))
2842     {
2843       string_append (declp, *mangled);
2844       *mangled += strlen (*mangled);
2845       success = 1;
2846     }
2847   return (success);
2848 }
2849
2850 /*
2851
2852 LOCAL FUNCTION
2853
2854         gnu_special -- special handling of gnu mangled strings
2855
2856 SYNOPSIS
2857
2858         static int
2859         gnu_special (struct work_stuff *work, const char **mangled,
2860                      string *declp);
2861
2862
2863 DESCRIPTION
2864
2865         Process some special GNU style mangling forms that don't fit
2866         the normal pattern.  For example:
2867
2868                 _$_3foo         (destructor for class foo)
2869                 _vt$foo         (foo virtual table)
2870                 _vt$foo$bar     (foo::bar virtual table)
2871                 __vt_foo        (foo virtual table, new style with thunks)
2872                 _3foo$varname   (static data member)
2873                 _Q22rs2tu$vw    (static data member)
2874                 __t6vector1Zii  (constructor with template)
2875                 __thunk_4__$_7ostream (virtual function thunk)
2876  */
2877
2878 static int
2879 gnu_special (work, mangled, declp)
2880      struct work_stuff *work;
2881      const char **mangled;
2882      string *declp;
2883 {
2884   int n;
2885   int success = 1;
2886   const char *p;
2887
2888   if ((*mangled)[0] == '_'
2889       && strchr (cplus_markers, (*mangled)[1]) != NULL
2890       && (*mangled)[2] == '_')
2891     {
2892       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2893       (*mangled) += 3;
2894       work -> destructor += 1;
2895     }
2896   else if ((*mangled)[0] == '_'
2897            && (((*mangled)[1] == '_'
2898                 && (*mangled)[2] == 'v'
2899                 && (*mangled)[3] == 't'
2900                 && (*mangled)[4] == '_')
2901                || ((*mangled)[1] == 'v'
2902                    && (*mangled)[2] == 't'
2903                    && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2904     {
2905       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2906          and create the decl.  Note that we consume the entire mangled
2907          input string, which means that demangle_signature has no work
2908          to do.  */
2909       if ((*mangled)[2] == 'v')
2910         (*mangled) += 5; /* New style, with thunks: "__vt_" */
2911       else
2912         (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2913       while (**mangled != '\0')
2914         {
2915           switch (**mangled)
2916             {
2917             case 'Q':
2918             case 'K':
2919               success = demangle_qualified (work, mangled, declp, 0, 1);
2920               break;
2921             case 't':
2922               success = demangle_template (work, mangled, declp, 0, 1,
2923                                            1);
2924               break;
2925             default:
2926               if (ISDIGIT((unsigned char)*mangled[0]))
2927                 {
2928                   n = consume_count(mangled);
2929                   /* We may be seeing a too-large size, or else a
2930                      ".<digits>" indicating a static local symbol.  In
2931                      any case, declare victory and move on; *don't* try
2932                      to use n to allocate.  */
2933                   if (n > (int) strlen (*mangled))
2934                     {
2935                       success = 1;
2936                       break;
2937                     }
2938                 }
2939               else
2940                 {
2941                   n = strcspn (*mangled, cplus_markers);
2942                 }
2943               string_appendn (declp, *mangled, n);
2944               (*mangled) += n;
2945             }
2946
2947           p = strpbrk (*mangled, cplus_markers);
2948           if (success && ((p == NULL) || (p == *mangled)))
2949             {
2950               if (p != NULL)
2951                 {
2952                   string_append (declp, SCOPE_STRING (work));
2953                   (*mangled)++;
2954                 }
2955             }
2956           else
2957             {
2958               success = 0;
2959               break;
2960             }
2961         }
2962       if (success)
2963         string_append (declp, " virtual table");
2964     }
2965   else if ((*mangled)[0] == '_'
2966            && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2967            && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2968     {
2969       /* static data member, "_3foo$varname" for example */
2970       (*mangled)++;
2971       switch (**mangled)
2972         {
2973         case 'Q':
2974         case 'K':
2975           success = demangle_qualified (work, mangled, declp, 0, 1);
2976           break;
2977         case 't':
2978           success = demangle_template (work, mangled, declp, 0, 1, 1);
2979           break;
2980         default:
2981           n = consume_count (mangled);
2982           if (n < 0 || n > (long) strlen (*mangled))
2983             {
2984               success = 0;
2985               break;
2986             }
2987
2988           if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2989               && (*mangled)[9] == 'N'
2990               && (*mangled)[8] == (*mangled)[10]
2991               && strchr (cplus_markers, (*mangled)[8]))
2992             {
2993               /* A member of the anonymous namespace.  There's information
2994                  about what identifier or filename it was keyed to, but
2995                  it's just there to make the mangled name unique; we just
2996                  step over it.  */
2997               string_append (declp, "{anonymous}");
2998               (*mangled) += n;
2999
3000               /* Now p points to the marker before the N, so we need to
3001                  update it to the first marker after what we consumed.  */
3002               p = strpbrk (*mangled, cplus_markers);
3003               break;
3004             }
3005
3006           string_appendn (declp, *mangled, n);
3007           (*mangled) += n;
3008         }
3009       if (success && (p == *mangled))
3010         {
3011           /* Consumed everything up to the cplus_marker, append the
3012              variable name.  */
3013           (*mangled)++;
3014           string_append (declp, SCOPE_STRING (work));
3015           n = strlen (*mangled);
3016           string_appendn (declp, *mangled, n);
3017           (*mangled) += n;
3018         }
3019       else
3020         {
3021           success = 0;
3022         }
3023     }
3024   else if (strncmp (*mangled, "__thunk_", 8) == 0)
3025     {
3026       int delta;
3027
3028       (*mangled) += 8;
3029       delta = consume_count (mangled);
3030       if (delta == -1)
3031         success = 0;
3032       else
3033         {
3034           char *method = internal_cplus_demangle (work, ++*mangled);
3035
3036           if (method)
3037             {
3038               char buf[50];
3039               sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3040               string_append (declp, buf);
3041               string_append (declp, method);
3042               free (method);
3043               n = strlen (*mangled);
3044               (*mangled) += n;
3045             }
3046           else
3047             {
3048               success = 0;
3049             }
3050         }
3051     }
3052   else if (strncmp (*mangled, "__t", 3) == 0
3053            && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3054     {
3055       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3056       (*mangled) += 4;
3057       switch (**mangled)
3058         {
3059         case 'Q':
3060         case 'K':
3061           success = demangle_qualified (work, mangled, declp, 0, 1);
3062           break;
3063         case 't':
3064           success = demangle_template (work, mangled, declp, 0, 1, 1);
3065           break;
3066         default:
3067           success = do_type (work, mangled, declp);
3068           break;
3069         }
3070       if (success && **mangled != '\0')
3071         success = 0;
3072       if (success)
3073         string_append (declp, p);
3074     }
3075   else
3076     {
3077       success = 0;
3078     }
3079   return (success);
3080 }
3081
3082 static void
3083 recursively_demangle(work, mangled, result, namelength)
3084      struct work_stuff *work;
3085      const char **mangled;
3086      string *result;
3087      int namelength;
3088 {
3089   char * recurse = (char *)NULL;
3090   char * recurse_dem = (char *)NULL;
3091
3092   recurse = (char *) xmalloc (namelength + 1);
3093   memcpy (recurse, *mangled, namelength);
3094   recurse[namelength] = '\000';
3095
3096   recurse_dem = cplus_demangle (recurse, work->options);
3097
3098   if (recurse_dem)
3099     {
3100       string_append (result, recurse_dem);
3101       free (recurse_dem);
3102     }
3103   else
3104     {
3105       string_appendn (result, *mangled, namelength);
3106     }
3107   free (recurse);
3108   *mangled += namelength;
3109 }
3110
3111 /*
3112
3113 LOCAL FUNCTION
3114
3115         arm_special -- special handling of ARM/lucid mangled strings
3116
3117 SYNOPSIS
3118
3119         static int
3120         arm_special (const char **mangled,
3121                      string *declp);
3122
3123
3124 DESCRIPTION
3125
3126         Process some special ARM style mangling forms that don't fit
3127         the normal pattern.  For example:
3128
3129                 __vtbl__3foo            (foo virtual table)
3130                 __vtbl__3foo__3bar      (bar::foo virtual table)
3131
3132  */
3133
3134 static int
3135 arm_special (mangled, declp)
3136      const char **mangled;
3137      string *declp;
3138 {
3139   int n;
3140   int success = 1;
3141   const char *scan;
3142
3143   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3144     {
3145       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3146          and create the decl.  Note that we consume the entire mangled
3147          input string, which means that demangle_signature has no work
3148          to do.  */
3149       scan = *mangled + ARM_VTABLE_STRLEN;
3150       while (*scan != '\0')        /* first check it can be demangled */
3151         {
3152           n = consume_count (&scan);
3153           if (n == -1)
3154             {
3155               return (0);           /* no good */
3156             }
3157           scan += n;
3158           if (scan[0] == '_' && scan[1] == '_')
3159             {
3160               scan += 2;
3161             }
3162         }
3163       (*mangled) += ARM_VTABLE_STRLEN;
3164       while (**mangled != '\0')
3165         {
3166           n = consume_count (mangled);
3167           if (n == -1
3168               || n > (long) strlen (*mangled))
3169             return 0;
3170           string_prependn (declp, *mangled, n);
3171           (*mangled) += n;
3172           if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3173             {
3174               string_prepend (declp, "::");
3175               (*mangled) += 2;
3176             }
3177         }
3178       string_append (declp, " virtual table");
3179     }
3180   else
3181     {
3182       success = 0;
3183     }
3184   return (success);
3185 }
3186
3187 /*
3188
3189 LOCAL FUNCTION
3190
3191         demangle_qualified -- demangle 'Q' qualified name strings
3192
3193 SYNOPSIS
3194
3195         static int
3196         demangle_qualified (struct work_stuff *, const char *mangled,
3197                             string *result, int isfuncname, int append);
3198
3199 DESCRIPTION
3200
3201         Demangle a qualified name, such as "Q25Outer5Inner" which is
3202         the mangled form of "Outer::Inner".  The demangled output is
3203         prepended or appended to the result string according to the
3204         state of the append flag.
3205
3206         If isfuncname is nonzero, then the qualified name we are building
3207         is going to be used as a member function name, so if it is a
3208         constructor or destructor function, append an appropriate
3209         constructor or destructor name.  I.E. for the above example,
3210         the result for use as a constructor is "Outer::Inner::Inner"
3211         and the result for use as a destructor is "Outer::Inner::~Inner".
3212
3213 BUGS
3214
3215         Numeric conversion is ASCII dependent (FIXME).
3216
3217  */
3218
3219 static int
3220 demangle_qualified (work, mangled, result, isfuncname, append)
3221      struct work_stuff *work;
3222      const char **mangled;
3223      string *result;
3224      int isfuncname;
3225      int append;
3226 {
3227   int qualifiers = 0;
3228   int success = 1;
3229   char num[2];
3230   string temp;
3231   string last_name;
3232   int bindex = register_Btype (work);
3233
3234   /* We only make use of ISFUNCNAME if the entity is a constructor or
3235      destructor.  */
3236   isfuncname = (isfuncname
3237                 && ((work->constructor & 1) || (work->destructor & 1)));
3238
3239   string_init (&temp);
3240   string_init (&last_name);
3241
3242   if ((*mangled)[0] == 'K')
3243     {
3244     /* Squangling qualified name reuse */
3245       int idx;
3246       (*mangled)++;
3247       idx = consume_count_with_underscores (mangled);
3248       if (idx == -1 || idx >= work -> numk)
3249         success = 0;
3250       else
3251         string_append (&temp, work -> ktypevec[idx]);
3252     }
3253   else
3254     switch ((*mangled)[1])
3255     {
3256     case '_':
3257       /* GNU mangled name with more than 9 classes.  The count is preceded
3258          by an underscore (to distinguish it from the <= 9 case) and followed
3259          by an underscore.  */
3260       (*mangled)++;
3261       qualifiers = consume_count_with_underscores (mangled);
3262       if (qualifiers == -1)
3263         success = 0;
3264       break;
3265
3266     case '1':
3267     case '2':
3268     case '3':
3269     case '4':
3270     case '5':
3271     case '6':
3272     case '7':
3273     case '8':
3274     case '9':
3275       /* The count is in a single digit.  */
3276       num[0] = (*mangled)[1];
3277       num[1] = '\0';
3278       qualifiers = atoi (num);
3279
3280       /* If there is an underscore after the digit, skip it.  This is
3281          said to be for ARM-qualified names, but the ARM makes no
3282          mention of such an underscore.  Perhaps cfront uses one.  */
3283       if ((*mangled)[2] == '_')
3284         {
3285           (*mangled)++;
3286         }
3287       (*mangled) += 2;
3288       break;
3289
3290     case '0':
3291     default:
3292       success = 0;
3293     }
3294
3295   if (!success)
3296     return success;
3297
3298   /* Pick off the names and collect them in the temp buffer in the order
3299      in which they are found, separated by '::'.  */
3300
3301   while (qualifiers-- > 0)
3302     {
3303       int remember_K = 1;
3304       string_clear (&last_name);
3305
3306       if (*mangled[0] == '_')
3307         (*mangled)++;
3308
3309       if (*mangled[0] == 't')
3310         {
3311           /* Here we always append to TEMP since we will want to use
3312              the template name without the template parameters as a
3313              constructor or destructor name.  The appropriate
3314              (parameter-less) value is returned by demangle_template
3315              in LAST_NAME.  We do not remember the template type here,
3316              in order to match the G++ mangling algorithm.  */
3317           success = demangle_template(work, mangled, &temp,
3318                                       &last_name, 1, 0);
3319           if (!success)
3320             break;
3321         }
3322       else if (*mangled[0] == 'K')
3323         {
3324           int idx;
3325           (*mangled)++;
3326           idx = consume_count_with_underscores (mangled);
3327           if (idx == -1 || idx >= work->numk)
3328             success = 0;
3329           else
3330             string_append (&temp, work->ktypevec[idx]);
3331           remember_K = 0;
3332
3333           if (!success) break;
3334         }
3335       else
3336         {
3337           if (EDG_DEMANGLING)
3338             {
3339               int namelength;
3340               /* Now recursively demangle the qualifier
3341                * This is necessary to deal with templates in
3342                * mangling styles like EDG */
3343               namelength = consume_count (mangled);
3344               if (namelength == -1)
3345                 {
3346                   success = 0;
3347                   break;
3348                 }
3349               recursively_demangle(work, mangled, &temp, namelength);
3350             }
3351           else
3352             {
3353               success = do_type (work, mangled, &last_name);
3354               if (!success)
3355                 break;
3356               string_appends (&temp, &last_name);
3357             }
3358         }
3359
3360       if (remember_K)
3361         remember_Ktype (work, temp.b, LEN_STRING (&temp));
3362
3363       if (qualifiers > 0)
3364         string_append (&temp, SCOPE_STRING (work));
3365     }
3366
3367   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3368
3369   /* If we are using the result as a function name, we need to append
3370      the appropriate '::' separated constructor or destructor name.
3371      We do this here because this is the most convenient place, where
3372      we already have a pointer to the name and the length of the name.  */
3373
3374   if (isfuncname)
3375     {
3376       string_append (&temp, SCOPE_STRING (work));
3377       if (work -> destructor & 1)
3378         string_append (&temp, "~");
3379       string_appends (&temp, &last_name);
3380     }
3381
3382   /* Now either prepend the temp buffer to the result, or append it,
3383      depending upon the state of the append flag.  */
3384
3385   if (append)
3386     string_appends (result, &temp);
3387   else
3388     {
3389       if (!STRING_EMPTY (result))
3390         string_append (&temp, SCOPE_STRING (work));
3391       string_prepends (result, &temp);
3392     }
3393
3394   string_delete (&last_name);
3395   string_delete (&temp);
3396   return (success);
3397 }
3398
3399 /*
3400
3401 LOCAL FUNCTION
3402
3403         get_count -- convert an ascii count to integer, consuming tokens
3404
3405 SYNOPSIS
3406
3407         static int
3408         get_count (const char **type, int *count)
3409
3410 DESCRIPTION
3411
3412         Assume that *type points at a count in a mangled name; set
3413         *count to its value, and set *type to the next character after
3414         the count.  There are some weird rules in effect here.
3415
3416         If *type does not point at a string of digits, return zero.
3417
3418         If *type points at a string of digits followed by an
3419         underscore, set *count to their value as an integer, advance
3420         *type to point *after the underscore, and return 1.
3421
3422         If *type points at a string of digits not followed by an
3423         underscore, consume only the first digit.  Set *count to its
3424         value as an integer, leave *type pointing after that digit,
3425         and return 1.
3426
3427         The excuse for this odd behavior: in the ARM and HP demangling
3428         styles, a type can be followed by a repeat count of the form
3429         `Nxy', where:
3430
3431         `x' is a single digit specifying how many additional copies
3432             of the type to append to the argument list, and
3433
3434         `y' is one or more digits, specifying the zero-based index of
3435             the first repeated argument in the list.  Yes, as you're
3436             unmangling the name you can figure this out yourself, but
3437             it's there anyway.
3438
3439         So, for example, in `bar__3fooFPiN51', the first argument is a
3440         pointer to an integer (`Pi'), and then the next five arguments
3441         are the same (`N5'), and the first repeat is the function's
3442         second argument (`1').
3443 */
3444
3445 static int
3446 get_count (type, count)
3447      const char **type;
3448      int *count;
3449 {
3450   const char *p;
3451   int n;
3452
3453   if (!ISDIGIT ((unsigned char)**type))
3454     return (0);
3455   else
3456     {
3457       *count = **type - '0';
3458       (*type)++;
3459       if (ISDIGIT ((unsigned char)**type))
3460         {
3461           p = *type;
3462           n = *count;
3463           do
3464             {
3465               n *= 10;
3466               n += *p - '0';
3467               p++;
3468             }
3469           while (ISDIGIT ((unsigned char)*p));
3470           if (*p == '_')
3471             {
3472               *type = p + 1;
3473               *count = n;
3474             }
3475         }
3476     }
3477   return (1);
3478 }
3479
3480 /* RESULT will be initialised here; it will be freed on failure.  The
3481    value returned is really a type_kind_t.  */
3482
3483 static int
3484 do_type (work, mangled, result)
3485      struct work_stuff *work;
3486      const char **mangled;
3487      string *result;
3488 {
3489   int n;
3490   int done;
3491   int success;
3492   string decl;
3493   const char *remembered_type;
3494   int type_quals;
3495   string btype;
3496   type_kind_t tk = tk_none;
3497
3498   string_init (&btype);
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               }
3617             else if (**mangled == 't')
3618               {
3619                 string temp;
3620                 string_init (&temp);
3621                 success = demangle_template (work, mangled, &temp,
3622                                              NULL, 1, 1);
3623                 if (success)
3624                   {
3625                     string_prependn (&decl, temp.b, temp.p - temp.b);
3626                     string_clear (&temp);
3627                   }
3628                 else
3629                   break;
3630               }
3631             else if (**mangled == 'Q')
3632               {
3633                 success = demangle_qualified (work, mangled, &decl,
3634                                               /*isfuncnam=*/0, 
3635                                               /*append=*/0);
3636                 if (!success)
3637                   break;
3638               }
3639             else
3640               {
3641                 success = 0;
3642                 break;
3643               }
3644
3645             string_prepend (&decl, "(");
3646             if (member)
3647               {
3648                 switch (**mangled)
3649                   {
3650                   case 'C':
3651                   case 'V':
3652                   case 'u':
3653                     type_quals |= code_for_qualifier (**mangled);
3654                     (*mangled)++;
3655                     break;
3656
3657                   default:
3658                     break;
3659                   }
3660
3661                 if (*(*mangled)++ != 'F')
3662                   {
3663                     success = 0;
3664                     break;
3665                   }
3666               }
3667             if ((member && !demangle_nested_args (work, mangled, &decl))
3668                 || **mangled != '_')
3669               {
3670                 success = 0;
3671                 break;
3672               }
3673             (*mangled)++;
3674             if (! PRINT_ANSI_QUALIFIERS)
3675               {
3676                 break;
3677               }
3678             if (type_quals != TYPE_UNQUALIFIED)
3679               {
3680                 APPEND_BLANK (&decl);
3681                 string_append (&decl, qualifier_string (type_quals));
3682               }
3683             break;
3684           }
3685         case 'G':
3686           (*mangled)++;
3687           break;
3688
3689         case 'C':
3690         case 'V':
3691         case 'u':
3692           if (PRINT_ANSI_QUALIFIERS)
3693             {
3694               if (!STRING_EMPTY (&decl))
3695                 string_prepend (&decl, " ");
3696
3697               string_prepend (&decl, demangle_qualifier (**mangled));
3698             }
3699           (*mangled)++;
3700           break;
3701           /*
3702             }
3703             */
3704
3705           /* fall through */
3706         default:
3707           done = 1;
3708           break;
3709         }
3710     }
3711
3712   if (success) switch (**mangled)
3713     {
3714       /* A qualified name, such as "Outer::Inner".  */
3715     case 'Q':
3716     case 'K':
3717       {
3718         success = demangle_qualified (work, mangled, result, 0, 1);
3719         break;
3720       }
3721
3722     /* A back reference to a previously seen squangled type */
3723     case 'B':
3724       (*mangled)++;
3725       if (!get_count (mangled, &n) || n >= work -> numb)
3726         success = 0;
3727       else
3728         string_append (result, work->btypevec[n]);
3729       break;
3730
3731     case 'X':
3732     case 'Y':
3733       /* A template parm.  We substitute the corresponding argument. */
3734       {
3735         int idx;
3736
3737         (*mangled)++;
3738         idx = consume_count_with_underscores (mangled);
3739
3740         if (idx == -1
3741             || (work->tmpl_argvec && idx >= work->ntmpl_args)
3742             || consume_count_with_underscores (mangled) == -1)
3743           {
3744             success = 0;
3745             break;
3746           }
3747
3748         if (work->tmpl_argvec)
3749           string_append (result, work->tmpl_argvec[idx]);
3750         else
3751           string_append_template_idx (result, idx);
3752
3753         success = 1;
3754       }
3755     break;
3756
3757     default:
3758       success = demangle_fund_type (work, mangled, result);
3759       if (tk == tk_none)
3760         tk = (type_kind_t) success;
3761       break;
3762     }
3763
3764   if (success)
3765     {
3766       if (!STRING_EMPTY (&decl))
3767         {
3768           string_append (result, " ");
3769           string_appends (result, &decl);
3770         }
3771     }
3772   else
3773     string_delete (result);
3774   string_delete (&decl);
3775
3776   if (success)
3777     /* Assume an integral type, if we're not sure.  */
3778     return (int) ((tk == tk_none) ? tk_integral : tk);
3779   else
3780     return 0;
3781 }
3782
3783 /* Given a pointer to a type string that represents a fundamental type
3784    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3785    string in which the demangled output is being built in RESULT, and
3786    the WORK structure, decode the types and add them to the result.
3787
3788    For example:
3789
3790         "Ci"    =>      "const int"
3791         "Sl"    =>      "signed long"
3792         "CUs"   =>      "const unsigned short"
3793
3794    The value returned is really a type_kind_t.  */
3795
3796 static int
3797 demangle_fund_type (work, mangled, result)
3798      struct work_stuff *work;
3799      const char **mangled;
3800      string *result;
3801 {
3802   int done = 0;
3803   int success = 1;
3804   char buf[10];
3805   unsigned int dec = 0;
3806   string btype;
3807   type_kind_t tk = tk_integral;
3808
3809   string_init (&btype);
3810
3811   /* First pick off any type qualifiers.  There can be more than one.  */
3812
3813   while (!done)
3814     {
3815       switch (**mangled)
3816         {
3817         case 'C':
3818         case 'V':
3819         case 'u':
3820           if (PRINT_ANSI_QUALIFIERS)
3821             {
3822               if (!STRING_EMPTY (result))
3823                 string_prepend (result, " ");
3824               string_prepend (result, demangle_qualifier (**mangled));
3825             }
3826           (*mangled)++;
3827           break;
3828         case 'U':
3829           (*mangled)++;
3830           APPEND_BLANK (result);
3831           string_append (result, "unsigned");
3832           break;
3833         case 'S': /* signed char only */
3834           (*mangled)++;
3835           APPEND_BLANK (result);
3836           string_append (result, "signed");
3837           break;
3838         case 'J':
3839           (*mangled)++;
3840           APPEND_BLANK (result);
3841           string_append (result, "__complex");
3842           break;
3843         default:
3844           done = 1;
3845           break;
3846         }
3847     }
3848
3849   /* Now pick off the fundamental type.  There can be only one.  */
3850
3851   switch (**mangled)
3852     {
3853     case '\0':
3854     case '_':
3855       break;
3856     case 'v':
3857       (*mangled)++;
3858       APPEND_BLANK (result);
3859       string_append (result, "void");
3860       break;
3861     case 'x':
3862       (*mangled)++;
3863       APPEND_BLANK (result);
3864       string_append (result, "long long");
3865       break;
3866     case 'l':
3867       (*mangled)++;
3868       APPEND_BLANK (result);
3869       string_append (result, "long");
3870       break;
3871     case 'i':
3872       (*mangled)++;
3873       APPEND_BLANK (result);
3874       string_append (result, "int");
3875       break;
3876     case 's':
3877       (*mangled)++;
3878       APPEND_BLANK (result);
3879       string_append (result, "short");
3880       break;
3881     case 'b':
3882       (*mangled)++;
3883       APPEND_BLANK (result);
3884       string_append (result, "bool");
3885       tk = tk_bool;
3886       break;
3887     case 'c':
3888       (*mangled)++;
3889       APPEND_BLANK (result);
3890       string_append (result, "char");
3891       tk = tk_char;
3892       break;
3893     case 'w':
3894       (*mangled)++;
3895       APPEND_BLANK (result);
3896       string_append (result, "wchar_t");
3897       tk = tk_char;
3898       break;
3899     case 'r':
3900       (*mangled)++;
3901       APPEND_BLANK (result);
3902       string_append (result, "long double");
3903       tk = tk_real;
3904       break;
3905     case 'd':
3906       (*mangled)++;
3907       APPEND_BLANK (result);
3908       string_append (result, "double");
3909       tk = tk_real;
3910       break;
3911     case 'f':
3912       (*mangled)++;
3913       APPEND_BLANK (result);
3914       string_append (result, "float");
3915       tk = tk_real;
3916       break;
3917     case 'G':
3918       (*mangled)++;
3919       if (!ISDIGIT ((unsigned char)**mangled))
3920         {
3921           success = 0;
3922           break;
3923         }
3924     case 'I':
3925       (*mangled)++;
3926       if (**mangled == '_')
3927         {
3928           int i;
3929           (*mangled)++;
3930           for (i = 0;
3931                i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3932                (*mangled)++, i++)
3933             buf[i] = **mangled;
3934           if (**mangled != '_')
3935             {
3936               success = 0;
3937               break;
3938             }
3939           buf[i] = '\0';
3940           (*mangled)++;
3941         }
3942       else
3943         {
3944           strncpy (buf, *mangled, 2);
3945           buf[2] = '\0';
3946           *mangled += min (strlen (*mangled), 2);
3947         }
3948       sscanf (buf, "%x", &dec);
3949       sprintf (buf, "int%u_t", dec);
3950       APPEND_BLANK (result);
3951       string_append (result, buf);
3952       break;
3953
3954       /* fall through */
3955       /* An explicit type, such as "6mytype" or "7integer" */
3956     case '0':
3957     case '1':
3958     case '2':
3959     case '3':
3960     case '4':
3961     case '5':
3962     case '6':
3963     case '7':
3964     case '8':
3965     case '9':
3966       {
3967         int bindex = register_Btype (work);
3968         string btype;
3969         string_init (&btype);
3970         if (demangle_class_name (work, mangled, &btype)) {
3971           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3972           APPEND_BLANK (result);
3973           string_appends (result, &btype);
3974         }
3975         else
3976           success = 0;
3977         string_delete (&btype);
3978         break;
3979       }
3980     case 't':
3981       {
3982         success = demangle_template (work, mangled, &btype, 0, 1, 1);
3983         string_appends (result, &btype);
3984         break;
3985       }
3986     default:
3987       success = 0;
3988       break;
3989     }
3990
3991   return success ? ((int) tk) : 0;
3992 }
3993
3994
3995 /* Handle a template's value parameter for HP aCC (extension from ARM)
3996    **mangled points to 'S' or 'U' */
3997
3998 static int
3999 do_hpacc_template_const_value (work, mangled, result)
4000      struct work_stuff *work ATTRIBUTE_UNUSED;
4001      const char **mangled;
4002      string *result;
4003 {
4004   int unsigned_const;
4005
4006   if (**mangled != 'U' && **mangled != 'S')
4007     return 0;
4008
4009   unsigned_const = (**mangled == 'U');
4010
4011   (*mangled)++;
4012
4013   switch (**mangled)
4014     {
4015       case 'N':
4016         string_append (result, "-");
4017         /* fall through */
4018       case 'P':
4019         (*mangled)++;
4020         break;
4021       case 'M':
4022         /* special case for -2^31 */
4023         string_append (result, "-2147483648");
4024         (*mangled)++;
4025         return 1;
4026       default:
4027         return 0;
4028     }
4029
4030   /* We have to be looking at an integer now */
4031   if (!(ISDIGIT ((unsigned char)**mangled)))
4032     return 0;
4033
4034   /* We only deal with integral values for template
4035      parameters -- so it's OK to look only for digits */
4036   while (ISDIGIT ((unsigned char)**mangled))
4037     {
4038       char_str[0] = **mangled;
4039       string_append (result, char_str);
4040       (*mangled)++;
4041     }
4042
4043   if (unsigned_const)
4044     string_append (result, "U");
4045
4046   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4047      with L or LL suffixes. pai/1997-09-03 */
4048
4049   return 1; /* success */
4050 }
4051
4052 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4053    **mangled is pointing to the 'A' */
4054
4055 static int
4056 do_hpacc_template_literal (work, mangled, result)
4057      struct work_stuff *work;
4058      const char **mangled;
4059      string *result;
4060 {
4061   int literal_len = 0;
4062   char * recurse;
4063   char * recurse_dem;
4064
4065   if (**mangled != 'A')
4066     return 0;
4067
4068   (*mangled)++;
4069
4070   literal_len = consume_count (mangled);
4071
4072   if (literal_len <= 0)
4073     return 0;
4074
4075   /* Literal parameters are names of arrays, functions, etc.  and the
4076      canonical representation uses the address operator */
4077   string_append (result, "&");
4078
4079   /* Now recursively demangle the literal name */
4080   recurse = (char *) xmalloc (literal_len + 1);
4081   memcpy (recurse, *mangled, literal_len);
4082   recurse[literal_len] = '\000';
4083
4084   recurse_dem = cplus_demangle (recurse, work->options);
4085
4086   if (recurse_dem)
4087     {
4088       string_append (result, recurse_dem);
4089       free (recurse_dem);
4090     }
4091   else
4092     {
4093       string_appendn (result, *mangled, literal_len);
4094     }
4095   (*mangled) += literal_len;
4096   free (recurse);
4097
4098   return 1;
4099 }
4100
4101 static int
4102 snarf_numeric_literal (args, arg)
4103      const char ** args;
4104      string * arg;
4105 {
4106   if (**args == '-')
4107     {
4108       char_str[0] = '-';
4109       string_append (arg, char_str);
4110       (*args)++;
4111     }
4112   else if (**args == '+')
4113     (*args)++;
4114
4115   if (!ISDIGIT ((unsigned char)**args))
4116     return 0;
4117
4118   while (ISDIGIT ((unsigned char)**args))
4119     {
4120       char_str[0] = **args;
4121       string_append (arg, char_str);
4122       (*args)++;
4123     }
4124
4125   return 1;
4126 }
4127
4128 /* Demangle the next argument, given by MANGLED into RESULT, which
4129    *should be an uninitialized* string.  It will be initialized here,
4130    and free'd should anything go wrong.  */
4131
4132 static int
4133 do_arg (work, mangled, result)
4134      struct work_stuff *work;
4135      const char **mangled;
4136      string *result;
4137 {
4138   /* Remember where we started so that we can record the type, for
4139      non-squangling type remembering.  */
4140   const char *start = *mangled;
4141
4142   string_init (result);
4143
4144   if (work->nrepeats > 0)
4145     {
4146       --work->nrepeats;
4147
4148       if (work->previous_argument == 0)
4149         return 0;
4150
4151       /* We want to reissue the previous type in this argument list.  */
4152       string_appends (result, work->previous_argument);
4153       return 1;
4154     }
4155
4156   if (**mangled == 'n')
4157     {
4158       /* A squangling-style repeat.  */
4159       (*mangled)++;
4160       work->nrepeats = consume_count(mangled);
4161
4162       if (work->nrepeats <= 0)
4163         /* This was not a repeat count after all.  */
4164         return 0;
4165
4166       if (work->nrepeats > 9)
4167         {
4168           if (**mangled != '_')
4169             /* The repeat count should be followed by an '_' in this
4170                case.  */
4171             return 0;
4172           else
4173             (*mangled)++;
4174         }
4175
4176       /* Now, the repeat is all set up.  */
4177       return do_arg (work, mangled, result);
4178     }
4179
4180   /* Save the result in WORK->previous_argument so that we can find it
4181      if it's repeated.  Note that saving START is not good enough: we
4182      do not want to add additional types to the back-referenceable
4183      type vector when processing a repeated type.  */
4184   if (work->previous_argument)
4185     string_clear (work->previous_argument);
4186   else
4187     {
4188       work->previous_argument = (string*) xmalloc (sizeof (string));
4189       string_init (work->previous_argument);
4190     }
4191
4192   if (!do_type (work, mangled, work->previous_argument))
4193     return 0;
4194
4195   string_appends (result, work->previous_argument);
4196
4197   remember_type (work, start, *mangled - start);
4198   return 1;
4199 }
4200
4201 static void
4202 remember_type (work, start, len)
4203      struct work_stuff *work;
4204      const char *start;
4205      int len;
4206 {
4207   char *tem;
4208
4209   if (work->forgetting_types)
4210     return;
4211
4212   if (work -> ntypes >= work -> typevec_size)
4213     {
4214       if (work -> typevec_size == 0)
4215         {
4216           work -> typevec_size = 3;
4217           work -> typevec
4218             = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4219         }
4220       else
4221         {
4222           work -> typevec_size *= 2;
4223           work -> typevec
4224             = (char **) xrealloc ((char *)work -> typevec,
4225                                   sizeof (char *) * work -> typevec_size);
4226         }
4227     }
4228   tem = xmalloc (len + 1);
4229   memcpy (tem, start, len);
4230   tem[len] = '\0';
4231   work -> typevec[work -> ntypes++] = tem;
4232 }
4233
4234
4235 /* Remember a K type class qualifier. */
4236 static void
4237 remember_Ktype (work, start, len)
4238      struct work_stuff *work;
4239      const char *start;
4240      int len;
4241 {
4242   char *tem;
4243
4244   if (work -> numk >= work -> ksize)
4245     {
4246       if (work -> ksize == 0)
4247         {
4248           work -> ksize = 5;
4249           work -> ktypevec
4250             = (char **) xmalloc (sizeof (char *) * work -> ksize);
4251         }
4252       else
4253         {
4254           work -> ksize *= 2;
4255           work -> ktypevec
4256             = (char **) xrealloc ((char *)work -> ktypevec,
4257                                   sizeof (char *) * work -> ksize);
4258         }
4259     }
4260   tem = xmalloc (len + 1);
4261   memcpy (tem, start, len);
4262   tem[len] = '\0';
4263   work -> ktypevec[work -> numk++] = tem;
4264 }
4265
4266 /* Register a B code, and get an index for it. B codes are registered
4267    as they are seen, rather than as they are completed, so map<temp<char> >
4268    registers map<temp<char> > as B0, and temp<char> as B1 */
4269
4270 static int
4271 register_Btype (work)
4272      struct work_stuff *work;
4273 {
4274   int ret;
4275
4276   if (work -> numb >= work -> bsize)
4277     {
4278       if (work -> bsize == 0)
4279         {
4280           work -> bsize = 5;
4281           work -> btypevec
4282             = (char **) xmalloc (sizeof (char *) * work -> bsize);
4283         }
4284       else
4285         {
4286           work -> bsize *= 2;
4287           work -> btypevec
4288             = (char **) xrealloc ((char *)work -> btypevec,
4289                                   sizeof (char *) * work -> bsize);
4290         }
4291     }
4292   ret = work -> numb++;
4293   work -> btypevec[ret] = NULL;
4294   return(ret);
4295 }
4296
4297 /* Store a value into a previously registered B code type. */
4298
4299 static void
4300 remember_Btype (work, start, len, index)
4301      struct work_stuff *work;
4302      const char *start;
4303      int len, index;
4304 {
4305   char *tem;
4306
4307   tem = xmalloc (len + 1);
4308   memcpy (tem, start, len);
4309   tem[len] = '\0';
4310   work -> btypevec[index] = tem;
4311 }
4312
4313 /* Lose all the info related to B and K type codes. */
4314 static void
4315 forget_B_and_K_types (work)
4316      struct work_stuff *work;
4317 {
4318   int i;
4319
4320   while (work -> numk > 0)
4321     {
4322       i = --(work -> numk);
4323       if (work -> ktypevec[i] != NULL)
4324         {
4325           free (work -> ktypevec[i]);
4326           work -> ktypevec[i] = NULL;
4327         }
4328     }
4329
4330   while (work -> numb > 0)
4331     {
4332       i = --(work -> numb);
4333       if (work -> btypevec[i] != NULL)
4334         {
4335           free (work -> btypevec[i]);
4336           work -> btypevec[i] = NULL;
4337         }
4338     }
4339 }
4340 /* Forget the remembered types, but not the type vector itself.  */
4341
4342 static void
4343 forget_types (work)
4344      struct work_stuff *work;
4345 {
4346   int i;
4347
4348   while (work -> ntypes > 0)
4349     {
4350       i = --(work -> ntypes);
4351       if (work -> typevec[i] != NULL)
4352         {
4353           free (work -> typevec[i]);
4354           work -> typevec[i] = NULL;
4355         }
4356     }
4357 }
4358
4359 /* Process the argument list part of the signature, after any class spec
4360    has been consumed, as well as the first 'F' character (if any).  For
4361    example:
4362
4363    "__als__3fooRT0"             =>      process "RT0"
4364    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
4365
4366    DECLP must be already initialised, usually non-empty.  It won't be freed
4367    on failure.
4368
4369    Note that g++ differs significantly from ARM and lucid style mangling
4370    with regards to references to previously seen types.  For example, given
4371    the source fragment:
4372
4373      class foo {
4374        public:
4375        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4376      };
4377
4378      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4379      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4380
4381    g++ produces the names:
4382
4383      __3fooiRT0iT2iT2
4384      foo__FiR3fooiT1iT1
4385
4386    while lcc (and presumably other ARM style compilers as well) produces:
4387
4388      foo__FiR3fooT1T2T1T2
4389      __ct__3fooFiR3fooT1T2T1T2
4390
4391    Note that g++ bases its type numbers starting at zero and counts all
4392    previously seen types, while lucid/ARM bases its type numbers starting
4393    at one and only considers types after it has seen the 'F' character
4394    indicating the start of the function args.  For lucid/ARM style, we
4395    account for this difference by discarding any previously seen types when
4396    we see the 'F' character, and subtracting one from the type number
4397    reference.
4398
4399  */
4400
4401 static int
4402 demangle_args (work, mangled, declp)
4403      struct work_stuff *work;
4404      const char **mangled;
4405      string *declp;
4406 {
4407   string arg;
4408   int need_comma = 0;
4409   int r;
4410   int t;
4411   const char *tem;
4412   char temptype;
4413
4414   if (PRINT_ARG_TYPES)
4415     {
4416       string_append (declp, "(");
4417       if (**mangled == '\0')
4418         {
4419           string_append (declp, "void");
4420         }
4421     }
4422
4423   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4424          || work->nrepeats > 0)
4425     {
4426       if ((**mangled == 'N') || (**mangled == 'T'))
4427         {
4428           temptype = *(*mangled)++;
4429
4430           if (temptype == 'N')
4431             {
4432               if (!get_count (mangled, &r))
4433                 {
4434                   return (0);
4435                 }
4436             }
4437           else
4438             {
4439               r = 1;
4440             }
4441           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4442             {
4443               /* If we have 10 or more types we might have more than a 1 digit
4444                  index so we'll have to consume the whole count here. This
4445                  will lose if the next thing is a type name preceded by a
4446                  count but it's impossible to demangle that case properly
4447                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4448                  Pc, ...)"  or "(..., type12, char *, ...)" */
4449               if ((t = consume_count(mangled)) <= 0)
4450                 {
4451                   return (0);
4452                 }
4453             }
4454           else
4455             {
4456               if (!get_count (mangled, &t))
4457                 {
4458                   return (0);
4459                 }
4460             }
4461           if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4462             {
4463               t--;
4464             }
4465           /* Validate the type index.  Protect against illegal indices from
4466              malformed type strings.  */
4467           if ((t < 0) || (t >= work -> ntypes))
4468             {
4469               return (0);
4470             }
4471           while (work->nrepeats > 0 || --r >= 0)
4472             {
4473               tem = work -> typevec[t];
4474               if (need_comma && PRINT_ARG_TYPES)
4475                 {
4476                   string_append (declp, ", ");
4477                 }
4478               if (!do_arg (work, &tem, &arg))
4479                 {
4480                   return (0);
4481                 }
4482               if (PRINT_ARG_TYPES)
4483                 {
4484                   string_appends (declp, &arg);
4485                 }
4486               string_delete (&arg);
4487               need_comma = 1;
4488             }
4489         }
4490       else
4491         {
4492           if (need_comma && PRINT_ARG_TYPES)
4493             string_append (declp, ", ");
4494           if (!do_arg (work, mangled, &arg))
4495             return (0);
4496           if (PRINT_ARG_TYPES)
4497             string_appends (declp, &arg);
4498           string_delete (&arg);
4499           need_comma = 1;
4500         }
4501     }
4502
4503   if (**mangled == 'e')
4504     {
4505       (*mangled)++;
4506       if (PRINT_ARG_TYPES)
4507         {
4508           if (need_comma)
4509             {
4510               string_append (declp, ",");
4511             }
4512           string_append (declp, "...");
4513         }
4514     }
4515
4516   if (PRINT_ARG_TYPES)
4517     {
4518       string_append (declp, ")");
4519     }
4520   return (1);
4521 }
4522
4523 /* Like demangle_args, but for demangling the argument lists of function
4524    and method pointers or references, not top-level declarations.  */
4525
4526 static int
4527 demangle_nested_args (work, mangled, declp)
4528      struct work_stuff *work;
4529      const char **mangled;
4530      string *declp;
4531 {
4532   string* saved_previous_argument;
4533   int result;
4534   int saved_nrepeats;
4535
4536   /* The G++ name-mangling algorithm does not remember types on nested
4537      argument lists, unless -fsquangling is used, and in that case the
4538      type vector updated by remember_type is not used.  So, we turn
4539      off remembering of types here.  */
4540   ++work->forgetting_types;
4541
4542   /* For the repeat codes used with -fsquangling, we must keep track of
4543      the last argument.  */
4544   saved_previous_argument = work->previous_argument;
4545   saved_nrepeats = work->nrepeats;
4546   work->previous_argument = 0;
4547   work->nrepeats = 0;
4548
4549   /* Actually demangle the arguments.  */
4550   result = demangle_args (work, mangled, declp);
4551
4552   /* Restore the previous_argument field.  */
4553   if (work->previous_argument)
4554     string_delete (work->previous_argument);
4555   work->previous_argument = saved_previous_argument;
4556   --work->forgetting_types;
4557   work->nrepeats = saved_nrepeats;
4558
4559   return result;
4560 }
4561
4562 static void
4563 demangle_function_name (work, mangled, declp, scan)
4564      struct work_stuff *work;
4565      const char **mangled;
4566      string *declp;
4567      const char *scan;
4568 {
4569   size_t i;
4570   string type;
4571   const char *tem;
4572
4573   string_appendn (declp, (*mangled), scan - (*mangled));
4574   string_need (declp, 1);
4575   *(declp -> p) = '\0';
4576
4577   /* Consume the function name, including the "__" separating the name
4578      from the signature.  We are guaranteed that SCAN points to the
4579      separator.  */
4580
4581   (*mangled) = scan + 2;
4582   /* We may be looking at an instantiation of a template function:
4583      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4584      following _F marks the start of the function arguments.  Handle
4585      the template arguments first. */
4586
4587   if (HP_DEMANGLING && (**mangled == 'X'))
4588     {
4589       demangle_arm_hp_template (work, mangled, 0, declp);
4590       /* This leaves MANGLED pointing to the 'F' marking func args */
4591     }
4592
4593   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4594     {
4595
4596       /* See if we have an ARM style constructor or destructor operator.
4597          If so, then just record it, clear the decl, and return.
4598          We can't build the actual constructor/destructor decl until later,
4599          when we recover the class name from the signature.  */
4600
4601       if (strcmp (declp -> b, "__ct") == 0)
4602         {
4603           work -> constructor += 1;
4604           string_clear (declp);
4605           return;
4606         }
4607       else if (strcmp (declp -> b, "__dt") == 0)
4608         {
4609           work -> destructor += 1;
4610           string_clear (declp);
4611           return;
4612         }
4613     }
4614
4615   if (declp->p - declp->b >= 3
4616       && declp->b[0] == 'o'
4617       && declp->b[1] == 'p'
4618       && strchr (cplus_markers, declp->b[2]) != NULL)
4619     {
4620       /* see if it's an assignment expression */
4621       if (declp->p - declp->b >= 10 /* op$assign_ */
4622           && memcmp (declp->b + 3, "assign_", 7) == 0)
4623         {
4624           for (i = 0; i < ARRAY_SIZE (optable); i++)
4625             {
4626               int len = declp->p - declp->b - 10;
4627               if ((int) strlen (optable[i].in) == len
4628                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
4629                 {
4630                   string_clear (declp);
4631                   string_append (declp, "operator");
4632                   string_append (declp, optable[i].out);
4633                   string_append (declp, "=");
4634                   break;
4635                 }
4636             }
4637         }
4638       else
4639         {
4640           for (i = 0; i < ARRAY_SIZE (optable); i++)
4641             {
4642               int len = declp->p - declp->b - 3;
4643               if ((int) strlen (optable[i].in) == len
4644                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
4645                 {
4646                   string_clear (declp);
4647                   string_append (declp, "operator");
4648                   string_append (declp, optable[i].out);
4649                   break;
4650                 }
4651             }
4652         }
4653     }
4654   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4655            && strchr (cplus_markers, declp->b[4]) != NULL)
4656     {
4657       /* type conversion operator */
4658       tem = declp->b + 5;
4659       if (do_type (work, &tem, &type))
4660         {
4661           string_clear (declp);
4662           string_append (declp, "operator ");
4663           string_appends (declp, &type);
4664           string_delete (&type);
4665         }
4666     }
4667   else if (declp->b[0] == '_' && declp->b[1] == '_'
4668            && declp->b[2] == 'o' && declp->b[3] == 'p')
4669     {
4670       /* ANSI.  */
4671       /* type conversion operator.  */
4672       tem = declp->b + 4;
4673       if (do_type (work, &tem, &type))
4674         {
4675           string_clear (declp);
4676           string_append (declp, "operator ");
4677           string_appends (declp, &type);
4678           string_delete (&type);
4679         }
4680     }
4681   else if (declp->b[0] == '_' && declp->b[1] == '_'
4682            && ISLOWER((unsigned char)declp->b[2])
4683            && ISLOWER((unsigned char)declp->b[3]))
4684     {
4685       if (declp->b[4] == '\0')
4686         {
4687           /* Operator.  */
4688           for (i = 0; i < ARRAY_SIZE (optable); i++)
4689             {
4690               if (strlen (optable[i].in) == 2
4691                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4692                 {
4693                   string_clear (declp);
4694                   string_append (declp, "operator");
4695                   string_append (declp, optable[i].out);
4696                   break;
4697                 }
4698             }
4699         }
4700       else
4701         {
4702           if (declp->b[2] == 'a' && declp->b[5] == '\0')
4703             {
4704               /* Assignment.  */
4705               for (i = 0; i < ARRAY_SIZE (optable); i++)
4706                 {
4707                   if (strlen (optable[i].in) == 3
4708                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4709                     {
4710                       string_clear (declp);
4711                       string_append (declp, "operator");
4712                       string_append (declp, optable[i].out);
4713                       break;
4714                     }
4715                 }
4716             }
4717         }
4718     }
4719 }
4720
4721 /* a mini string-handling package */
4722
4723 static void
4724 string_need (s, n)
4725      string *s;
4726      int n;
4727 {
4728   int tem;
4729
4730   if (s->b == NULL)
4731     {
4732       if (n < 32)
4733         {
4734           n = 32;
4735         }
4736       s->p = s->b = xmalloc (n);
4737       s->e = s->b + n;
4738     }
4739   else if (s->e - s->p < n)
4740     {
4741       tem = s->p - s->b;
4742       n += tem;
4743       n *= 2;
4744       s->b = xrealloc (s->b, n);
4745       s->p = s->b + tem;
4746       s->e = s->b + n;
4747     }
4748 }
4749
4750 static void
4751 string_delete (s)
4752      string *s;
4753 {
4754   if (s->b != NULL)
4755     {
4756       free (s->b);
4757       s->b = s->e = s->p = NULL;
4758     }
4759 }
4760
4761 static void
4762 string_init (s)
4763      string *s;
4764 {
4765   s->b = s->p = s->e = NULL;
4766 }
4767
4768 static void
4769 string_clear (s)
4770      string *s;
4771 {
4772   s->p = s->b;
4773 }
4774
4775 #if 0
4776
4777 static int
4778 string_empty (s)
4779      string *s;
4780 {
4781   return (s->b == s->p);
4782 }
4783
4784 #endif
4785
4786 static void
4787 string_append (p, s)
4788      string *p;
4789      const char *s;
4790 {
4791   int n;
4792   if (s == NULL || *s == '\0')
4793     return;
4794   n = strlen (s);
4795   string_need (p, n);
4796   memcpy (p->p, s, n);
4797   p->p += n;
4798 }
4799
4800 static void
4801 string_appends (p, s)
4802      string *p, *s;
4803 {
4804   int n;
4805
4806   if (s->b != s->p)
4807     {
4808       n = s->p - s->b;
4809       string_need (p, n);
4810       memcpy (p->p, s->b, n);
4811       p->p += n;
4812     }
4813 }
4814
4815 static void
4816 string_appendn (p, s, n)
4817      string *p;
4818      const char *s;
4819      int n;
4820 {
4821   if (n != 0)
4822     {
4823       string_need (p, n);
4824       memcpy (p->p, s, n);
4825       p->p += n;
4826     }
4827 }
4828
4829 static void
4830 string_prepend (p, s)
4831      string *p;
4832      const char *s;
4833 {
4834   if (s != NULL && *s != '\0')
4835     {
4836       string_prependn (p, s, strlen (s));
4837     }
4838 }
4839
4840 static void
4841 string_prepends (p, s)
4842      string *p, *s;
4843 {
4844   if (s->b != s->p)
4845     {
4846       string_prependn (p, s->b, s->p - s->b);
4847     }
4848 }
4849
4850 static void
4851 string_prependn (p, s, n)
4852      string *p;
4853      const char *s;
4854      int n;
4855 {
4856   char *q;
4857
4858   if (n != 0)
4859     {
4860       string_need (p, n);
4861       for (q = p->p - 1; q >= p->b; q--)
4862         {
4863           q[n] = q[0];
4864         }
4865       memcpy (p->b, s, n);
4866       p->p += n;
4867     }
4868 }
4869
4870 static void
4871 string_append_template_idx (s, idx)
4872      string *s;
4873      int idx;
4874 {
4875   char buf[INTBUF_SIZE + 1 /* 'T' */];
4876   sprintf(buf, "T%d", idx);
4877   string_append (s, buf);
4878 }