OSDN Git Service

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