OSDN Git Service

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