OSDN Git Service

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