OSDN Git Service

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