OSDN Git Service

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