OSDN Git Service

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