OSDN Git Service

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