OSDN Git Service

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