OSDN Git Service

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