OSDN Git Service

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