OSDN Git Service

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