OSDN Git Service

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