OSDN Git Service

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