OSDN Git Service

(add_eh_table_entry): Multiply realloc size by sizeof int.
[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               if (!get_count (mangled, &symbol_len))
1059                 {
1060                   success = 0;
1061                   break;
1062                 }
1063               if (symbol_len == 0)
1064                 string_appendn (tname, "0", 1);
1065               else
1066                 {
1067                   char *p = xmalloc (symbol_len + 1), *q;
1068                   strncpy (p, *mangled, symbol_len);
1069                   p [symbol_len] = '\0';
1070                   q = cplus_demangle (p, work->options);
1071                   string_appendn (tname, "&", 1);
1072                   if (q)
1073                     {
1074                       string_append (tname, q);
1075                       free (q);
1076                     }
1077                   else
1078                     string_append (tname, p);
1079                   free (p);
1080                 }
1081               *mangled += symbol_len;
1082             }
1083         }
1084       need_comma = 1;
1085     }
1086   if (tname->p[-1] == '>')
1087     string_append (tname, " ");
1088   string_append (tname, ">");
1089   
1090 /*
1091       if (work -> static_type)
1092         {
1093           string_append (declp, *mangled + 1);
1094           *mangled += strlen (*mangled);
1095           success = 1;
1096         }
1097       else
1098         {
1099           success = demangle_args (work, mangled, declp);
1100         }
1101     }
1102 */
1103   return (success);
1104 }
1105
1106 static int
1107 arm_pt (work, mangled, n, anchor, args)
1108      struct work_stuff *work;
1109      const char *mangled;
1110      int n;
1111      const char **anchor, **args;
1112 {
1113   /* ARM template? */
1114   if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1115     {
1116         int len;
1117         *args = *anchor + 6;
1118         len = consume_count (args);
1119         if (*args + len == mangled + n && **args == '_')
1120           {
1121             ++*args;
1122             return 1;
1123           }
1124     }
1125   return 0;
1126 }
1127
1128 static void
1129 demangle_arm_pt (work, mangled, n, declp)
1130      struct work_stuff *work;
1131      const char **mangled;
1132      int n;
1133      string *declp;
1134 {
1135   const char *p;
1136   const char *args;
1137   const char *e = *mangled + n;
1138
1139   /* ARM template? */
1140   if (arm_pt (work, *mangled, n, &p, &args))
1141   {
1142     string arg;
1143     string_init (&arg);
1144     string_appendn (declp, *mangled, p - *mangled);
1145     string_append (declp, "<");
1146     /* should do error checking here */
1147     while (args < e) {
1148       string_clear (&arg);
1149       do_type (work, &args, &arg);
1150       string_appends (declp, &arg);
1151       string_append (declp, ",");
1152     }
1153     string_delete (&arg);
1154     --declp->p;
1155     string_append (declp, ">");
1156   }
1157   else
1158   {
1159     string_appendn (declp, *mangled, n);
1160   }
1161   *mangled += n;
1162 }
1163
1164 static int
1165 demangle_class_name (work, mangled, declp)
1166      struct work_stuff *work;
1167      const char **mangled;
1168      string *declp;
1169 {
1170   int n;
1171   int success = 0;
1172
1173   n = consume_count (mangled);
1174   if (strlen (*mangled) >= n)
1175   {
1176     demangle_arm_pt (work, mangled, n, declp);
1177     success = 1;
1178   }
1179
1180   return (success);
1181 }
1182
1183 /*
1184
1185 LOCAL FUNCTION
1186
1187         demangle_class -- demangle a mangled class sequence
1188
1189 SYNOPSIS
1190
1191         static int
1192         demangle_class (struct work_stuff *work, const char **mangled,
1193                         strint *declp)
1194
1195 DESCRIPTION
1196
1197         DECLP points to the buffer into which demangling is being done.
1198
1199         *MANGLED points to the current token to be demangled.  On input,
1200         it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1201         On exit, it points to the next token after the mangled class on
1202         success, or the first unconsumed token on failure.
1203
1204         If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1205         we are demangling a constructor or destructor.  In this case
1206         we prepend "class::class" or "class::~class" to DECLP.
1207
1208         Otherwise, we prepend "class::" to the current DECLP.
1209
1210         Reset the constructor/destructor flags once they have been
1211         "consumed".  This allows demangle_class to be called later during
1212         the same demangling, to do normal class demangling.
1213
1214         Returns 1 if demangling is successful, 0 otherwise.
1215
1216 */
1217
1218 static int
1219 demangle_class (work, mangled, declp)
1220      struct work_stuff *work;
1221      const char **mangled;
1222      string *declp;
1223 {
1224   int success = 0;
1225   string class_name;
1226
1227   string_init (&class_name);
1228   if (demangle_class_name (work, mangled, &class_name))
1229     {
1230       if ((work->constructor & 1) || (work->destructor & 1))
1231         {
1232           string_prepends (declp, &class_name);
1233           if (work -> destructor & 1)
1234             {
1235               string_prepend (declp, "~");
1236               work -> destructor -= 1;
1237             }
1238           else
1239             {
1240               work -> constructor -= 1; 
1241             }
1242         }
1243       string_prepend (declp, "::");
1244       string_prepends (declp, &class_name);
1245       success = 1;
1246     }
1247   string_delete (&class_name);
1248   return (success);
1249 }
1250
1251 /*
1252
1253 LOCAL FUNCTION
1254
1255         demangle_prefix -- consume the mangled name prefix and find signature
1256
1257 SYNOPSIS
1258
1259         static int
1260         demangle_prefix (struct work_stuff *work, const char **mangled,
1261                          string *declp);
1262
1263 DESCRIPTION
1264
1265         Consume and demangle the prefix of the mangled name.
1266
1267         DECLP points to the string buffer into which demangled output is
1268         placed.  On entry, the buffer is empty.  On exit it contains
1269         the root function name, the demangled operator name, or in some
1270         special cases either nothing or the completely demangled result.
1271
1272         MANGLED points to the current pointer into the mangled name.  As each
1273         token of the mangled name is consumed, it is updated.  Upon entry
1274         the current mangled name pointer points to the first character of
1275         the mangled name.  Upon exit, it should point to the first character
1276         of the signature if demangling was successful, or to the first
1277         unconsumed character if demangling of the prefix was unsuccessful.
1278         
1279         Returns 1 on success, 0 otherwise.
1280  */
1281
1282 static int
1283 demangle_prefix (work, mangled, declp)
1284      struct work_stuff *work;
1285      const char **mangled;
1286      string *declp;
1287 {
1288   int success = 1;
1289   const char *scan;
1290   int i;
1291
1292   if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1293     {
1294       char *marker = strchr (cplus_markers, (*mangled)[8]);
1295       if (marker != NULL && *marker == (*mangled)[10])
1296         {
1297           if ((*mangled)[9] == 'D')
1298             {
1299               /* it's a GNU global destructor to be executed at program exit */
1300               (*mangled) += 11;
1301               work->destructor = 2;
1302               if (gnu_special (work, mangled, declp))
1303                 return success;
1304             }
1305           else if ((*mangled)[9] == 'I')
1306             {
1307               /* it's a GNU global constructor to be executed at program init */
1308               (*mangled) += 11;
1309               work->constructor = 2;
1310               if (gnu_special (work, mangled, declp))
1311                 return success;
1312             }
1313         }
1314     }
1315   else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1316     {
1317       /* it's a ARM global destructor to be executed at program exit */
1318       (*mangled) += 7;
1319       work->destructor = 2;
1320     }
1321   else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1322     {
1323       /* it's a ARM global constructor to be executed at program initial */
1324       (*mangled) += 7;
1325       work->constructor = 2;
1326     }
1327
1328 /*  This block of code is a reduction in strength time optimization
1329     of:
1330         scan = mystrstr (*mangled, "__"); */
1331
1332   {
1333     scan = *mangled;
1334
1335     do {
1336       scan = strchr (scan, '_');
1337     } while (scan != NULL && *++scan != '_');
1338
1339     if (scan != NULL) --scan;
1340   }
1341
1342   if (scan != NULL)
1343     {
1344       /* We found a sequence of two or more '_', ensure that we start at
1345          the last pair in the sequence.  */
1346       i = strspn (scan, "_");
1347       if (i > 2)
1348         {
1349           scan += (i - 2); 
1350         }
1351     }
1352  
1353   if (scan == NULL)
1354     {
1355       success = 0;
1356     }
1357   else if (work -> static_type)
1358     {
1359       if (!isdigit (scan[0]) && (scan[0] != 't'))
1360         {
1361           success = 0;
1362         }
1363     }
1364   else if ((scan == *mangled) &&
1365            (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1366     {
1367       /* The ARM says nothing about the mangling of local variables.
1368          But cfront mangles local variables by prepending __<nesting_level>
1369          to them. As an extension to ARM demangling we handle this case.  */
1370       if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1371         {
1372           *mangled = scan + 2;
1373           consume_count (mangled);
1374           string_append (declp, *mangled);
1375           *mangled += strlen (*mangled);
1376           success = 1; 
1377         }
1378       else
1379         {
1380           /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
1381              names like __Q2_3foo3bar for nested type names.  So don't accept
1382              this style of constructor for cfront demangling.  */
1383           if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1384             work -> constructor += 1;
1385           *mangled = scan + 2;
1386         }
1387     }
1388   else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1389     {
1390       /* Mangled name starts with "__".  Skip over any leading '_' characters,
1391          then find the next "__" that separates the prefix from the signature.
1392          */
1393       if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1394           || (arm_special (work, mangled, declp) == 0))
1395         {
1396           while (*scan == '_')
1397             {
1398               scan++;
1399             }
1400           if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1401             {
1402               /* No separator (I.E. "__not_mangled"), or empty signature
1403                  (I.E. "__not_mangled_either__") */
1404               success = 0;
1405             }
1406           else
1407             {
1408               demangle_function_name (work, mangled, declp, scan);
1409             }
1410         }
1411     }
1412   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1413     {
1414       /* Cfront-style parameterized type.  Handled later as a signature.  */
1415       success = 1;
1416
1417       /* ARM template? */
1418       demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1419     }
1420   else if (*(scan + 2) != '\0')
1421     {
1422       /* Mangled name does not start with "__" but does have one somewhere
1423          in there with non empty stuff after it.  Looks like a global
1424          function name.  */
1425       demangle_function_name (work, mangled, declp, scan);
1426     }
1427   else
1428     {
1429       /* Doesn't look like a mangled name */
1430       success = 0;
1431     }
1432
1433   if (!success && (work->constructor == 2 || work->destructor == 2))
1434     {
1435       string_append (declp, *mangled);
1436       *mangled += strlen (*mangled);
1437       success = 1;
1438     } 
1439   return (success);
1440 }
1441
1442 /*
1443
1444 LOCAL FUNCTION
1445
1446         gnu_special -- special handling of gnu mangled strings
1447
1448 SYNOPSIS
1449
1450         static int
1451         gnu_special (struct work_stuff *work, const char **mangled,
1452                      string *declp);
1453
1454
1455 DESCRIPTION
1456
1457         Process some special GNU style mangling forms that don't fit
1458         the normal pattern.  For example:
1459
1460                 _$_3foo         (destructor for class foo)
1461                 _vt$foo         (foo virtual table)
1462                 _vt$foo$bar     (foo::bar virtual table)
1463                 __vt_foo        (foo virtual table, new style with thunks)
1464                 _3foo$varname   (static data member)
1465                 _Q22rs2tu$vw    (static data member)
1466                 __t6vector1Zii  (constructor with template)
1467                 __thunk_4__$_7ostream (virtual function thunk)
1468  */
1469
1470 static int
1471 gnu_special (work, mangled, declp)
1472      struct work_stuff *work;
1473      const char **mangled;
1474      string *declp;
1475 {
1476   int n;
1477   int success = 1;
1478   const char *p;
1479
1480   if ((*mangled)[0] == '_'
1481       && strchr (cplus_markers, (*mangled)[1]) != NULL
1482       && (*mangled)[2] == '_')
1483     {
1484       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1485       (*mangled) += 3;
1486       work -> destructor += 1;
1487     }
1488   else if ((*mangled)[0] == '_'
1489            && (((*mangled)[1] == '_'
1490                 && (*mangled)[2] == 'v'
1491                 && (*mangled)[3] == 't'
1492                 && (*mangled)[4] == '_')
1493              || ((*mangled)[1] == 'v'
1494                  && (*mangled)[2] == 't'
1495                  && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1496     {
1497       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1498          and create the decl.  Note that we consume the entire mangled
1499          input string, which means that demangle_signature has no work
1500          to do.  */
1501       if ((*mangled)[2] == 'v')
1502         (*mangled) += 5; /* New style, with thunks: "__vt_" */
1503       else
1504         (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1505       while (**mangled != '\0')
1506         {
1507           p = strpbrk (*mangled, cplus_markers);
1508           switch (**mangled)
1509             {
1510             case 'Q':
1511               success = demangle_qualified (work, mangled, declp, 0, 1);
1512               break;
1513             case 't':
1514               success = demangle_template (work, mangled, declp, 0);
1515               break;
1516             default:
1517               if (isdigit(*mangled[0]))
1518                 {
1519                   n = consume_count(mangled);
1520                 }
1521               else
1522                 {
1523                   n = strcspn (*mangled, cplus_markers);
1524                 }
1525               string_appendn (declp, *mangled, n);
1526               (*mangled) += n;
1527             }
1528
1529           if (success && ((p == NULL) || (p == *mangled)))
1530             {
1531               if (p != NULL)
1532                 {
1533                   string_append (declp, "::");
1534                   (*mangled)++;
1535                 }
1536             }
1537           else
1538             {
1539               success = 0;
1540               break;
1541             }
1542         }
1543       if (success)
1544         string_append (declp, " virtual table");
1545     }
1546   else if ((*mangled)[0] == '_'
1547            && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1548            && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1549     {
1550       /* static data member, "_3foo$varname" for example */
1551       (*mangled)++;
1552       switch (**mangled)
1553         {
1554           case 'Q':
1555             success = demangle_qualified (work, mangled, declp, 0, 1);
1556             break;
1557           case 't':
1558             success = demangle_template (work, mangled, declp, 0);
1559             break;
1560           default:
1561             n = consume_count (mangled);
1562             string_appendn (declp, *mangled, n);
1563             (*mangled) += n;
1564         }
1565       if (success && (p == *mangled))
1566         {
1567           /* Consumed everything up to the cplus_marker, append the
1568              variable name.  */
1569           (*mangled)++;
1570           string_append (declp, "::");
1571           n = strlen (*mangled);
1572           string_appendn (declp, *mangled, n);
1573           (*mangled) += n;
1574         }
1575       else
1576         {
1577           success = 0;
1578         }
1579     }
1580   else if (strncmp (*mangled, "__thunk_", 8) == 0)
1581     {
1582       int delta = ((*mangled) += 8, consume_count (mangled));
1583       char *method = cplus_demangle (++*mangled, work->options);
1584       if (method)
1585         {
1586           char buf[50];
1587           sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1588           string_append (declp, buf);
1589           string_append (declp, method);
1590           free (method);
1591           n = strlen (*mangled);
1592           (*mangled) += n;
1593         }
1594       else
1595         {
1596           success = 0;
1597         }
1598     }
1599   else
1600     {
1601       success = 0;
1602     }
1603   return (success);
1604 }
1605
1606 /*
1607
1608 LOCAL FUNCTION
1609
1610         arm_special -- special handling of ARM/lucid mangled strings
1611
1612 SYNOPSIS
1613
1614         static int
1615         arm_special (struct work_stuff *work, const char **mangled,
1616                         string *declp);
1617
1618
1619 DESCRIPTION
1620
1621         Process some special ARM style mangling forms that don't fit
1622         the normal pattern.  For example:
1623
1624                 __vtbl__3foo            (foo virtual table)
1625                 __vtbl__3foo__3bar      (bar::foo virtual table)
1626
1627  */
1628
1629 static int
1630 arm_special (work, mangled, declp)
1631      struct work_stuff *work;
1632      const char **mangled;
1633      string *declp;
1634 {
1635   int n;
1636   int success = 1;
1637   const char *scan;
1638
1639   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1640     {
1641       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1642          and create the decl.  Note that we consume the entire mangled
1643          input string, which means that demangle_signature has no work
1644          to do.  */
1645       scan = *mangled + ARM_VTABLE_STRLEN;
1646       while (*scan != '\0')        /* first check it can be demangled */
1647         {
1648           n = consume_count (&scan);
1649           if (n==0)
1650             {
1651               return (0);           /* no good */
1652             }
1653           scan += n;
1654           if (scan[0] == '_' && scan[1] == '_')
1655             {
1656               scan += 2;
1657             }
1658         }
1659       (*mangled) += ARM_VTABLE_STRLEN;
1660       while (**mangled != '\0')
1661         {
1662           n = consume_count (mangled);
1663           string_prependn (declp, *mangled, n);
1664           (*mangled) += n;
1665           if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1666             {
1667               string_prepend (declp, "::");
1668               (*mangled) += 2;
1669             }
1670         }
1671       string_append (declp, " virtual table");
1672     }
1673   else
1674     {
1675       success = 0;
1676     }
1677   return (success);
1678 }
1679
1680 /*
1681
1682 LOCAL FUNCTION
1683
1684         demangle_qualified -- demangle 'Q' qualified name strings
1685
1686 SYNOPSIS
1687
1688         static int
1689         demangle_qualified (struct work_stuff *, const char *mangled,
1690                             string *result, int isfuncname, int append);
1691
1692 DESCRIPTION
1693
1694         Demangle a qualified name, such as "Q25Outer5Inner" which is
1695         the mangled form of "Outer::Inner".  The demangled output is
1696         prepended or appended to the result string according to the
1697         state of the append flag.
1698
1699         If isfuncname is nonzero, then the qualified name we are building
1700         is going to be used as a member function name, so if it is a
1701         constructor or destructor function, append an appropriate
1702         constructor or destructor name.  I.E. for the above example,
1703         the result for use as a constructor is "Outer::Inner::Inner"
1704         and the result for use as a destructor is "Outer::Inner::~Inner".
1705
1706 BUGS
1707
1708         Numeric conversion is ASCII dependent (FIXME).
1709
1710  */
1711
1712 static int
1713 demangle_qualified (work, mangled, result, isfuncname, append)
1714      struct work_stuff *work;
1715      const char **mangled;
1716      string *result;
1717      int isfuncname;
1718      int append;
1719 {
1720   int qualifiers;
1721   int namelength;
1722   int success = 1;
1723   const char *p;
1724   char num[2];
1725   string temp;
1726
1727   string_init (&temp);
1728   switch ((*mangled)[1])
1729     {
1730     case '_':
1731       /* GNU mangled name with more than 9 classes.  The count is preceded
1732          by an underscore (to distinguish it from the <= 9 case) and followed
1733          by an underscore.  */
1734       p = *mangled + 2;
1735       qualifiers = atoi (p);
1736       if (!isdigit (*p) || *p == '0')
1737         success = 0;
1738
1739       /* Skip the digits.  */
1740       while (isdigit (*p))
1741         ++p;
1742
1743       if (*p != '_')
1744         success = 0;
1745
1746       *mangled = p + 1;
1747       break;
1748
1749     case '1':
1750     case '2':
1751     case '3':
1752     case '4':
1753     case '5':
1754     case '6':
1755     case '7':
1756     case '8':
1757     case '9':
1758       /* The count is in a single digit.  */
1759       num[0] = (*mangled)[1];
1760       num[1] = '\0';
1761       qualifiers = atoi (num);
1762
1763       /* If there is an underscore after the digit, skip it.  This is
1764          said to be for ARM-qualified names, but the ARM makes no
1765          mention of such an underscore.  Perhaps cfront uses one.  */
1766       if ((*mangled)[2] == '_')
1767         {
1768           (*mangled)++;
1769         }
1770       (*mangled) += 2;
1771       break;
1772
1773     case '0':
1774     default:
1775       success = 0;
1776     }
1777
1778   if (!success)
1779     return success;
1780
1781   /* Pick off the names and collect them in the temp buffer in the order
1782      in which they are found, separated by '::'.  */
1783
1784   while (qualifiers-- > 0)
1785     {
1786       if (*mangled[0] == '_') 
1787         *mangled = *mangled + 1;
1788       if (*mangled[0] == 't')
1789         {
1790           success = demangle_template(work, mangled, &temp, 0);
1791           if (!success) break;
1792         }
1793       else
1794         {       
1795           namelength = consume_count (mangled);
1796           if (strlen (*mangled) < namelength)
1797             {
1798             /* Simple sanity check failed */
1799                success = 0;
1800                break;
1801             }
1802           string_appendn (&temp, *mangled, namelength);
1803           *mangled += namelength;
1804         }
1805       if (qualifiers > 0)
1806         {
1807           string_appendn (&temp, "::", 2);
1808         }
1809     }
1810
1811   /* If we are using the result as a function name, we need to append
1812      the appropriate '::' separated constructor or destructor name.
1813      We do this here because this is the most convenient place, where
1814      we already have a pointer to the name and the length of the name.  */
1815
1816   if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1817     {
1818       string_appendn (&temp, "::", 2);
1819       if (work -> destructor & 1)
1820         {
1821           string_append (&temp, "~");
1822         }
1823       string_appendn (&temp, (*mangled) - namelength, namelength);
1824     }
1825
1826   /* Now either prepend the temp buffer to the result, or append it, 
1827      depending upon the state of the append flag.  */
1828
1829   if (append)
1830     {
1831       string_appends (result, &temp);
1832     }
1833   else
1834     {
1835       if (!STRING_EMPTY (result))
1836         {
1837           string_appendn (&temp, "::", 2);
1838         }
1839       string_prepends (result, &temp);
1840     }
1841
1842   string_delete (&temp);
1843   return (success);
1844 }
1845
1846 /*
1847
1848 LOCAL FUNCTION
1849
1850         get_count -- convert an ascii count to integer, consuming tokens
1851
1852 SYNOPSIS
1853
1854         static int
1855         get_count (const char **type, int *count)
1856
1857 DESCRIPTION
1858
1859         Return 0 if no conversion is performed, 1 if a string is converted.
1860 */
1861
1862 static int
1863 get_count (type, count)
1864      const char **type;
1865      int *count;
1866 {
1867   const char *p;
1868   int n;
1869
1870   if (!isdigit (**type))
1871     {
1872       return (0);
1873     }
1874   else
1875     {
1876       *count = **type - '0';
1877       (*type)++;
1878       if (isdigit (**type))
1879         {
1880           p = *type;
1881           n = *count;
1882           do 
1883             {
1884               n *= 10;
1885               n += *p - '0';
1886               p++;
1887             } 
1888           while (isdigit (*p));
1889           if (*p == '_')
1890             {
1891               *type = p + 1;
1892               *count = n;
1893             }
1894         }
1895     }
1896   return (1);
1897 }
1898
1899 /* result will be initialised here; it will be freed on failure */
1900
1901 static int
1902 do_type (work, mangled, result)
1903      struct work_stuff *work;
1904      const char **mangled;
1905      string *result;
1906 {
1907   int n;
1908   int done;
1909   int success;
1910   string decl;
1911   const char *remembered_type;
1912   int constp;
1913   int volatilep;
1914
1915   string_init (&decl);
1916   string_init (result);
1917
1918   done = 0;
1919   success = 1;
1920   while (success && !done)
1921     {
1922       int member;
1923       switch (**mangled)
1924         {
1925
1926         /* A pointer type */
1927         case 'P':
1928         case 'p':
1929           (*mangled)++;
1930           string_prepend (&decl, "*");
1931           break;
1932
1933         /* A reference type */
1934         case 'R':
1935           (*mangled)++;
1936           string_prepend (&decl, "&");
1937           break;
1938
1939         /* An array */
1940         case 'A':
1941           {
1942             const char *p = ++(*mangled);
1943
1944             string_prepend (&decl, "(");
1945             string_append (&decl, ")[");
1946             /* Copy anything up until the next underscore (the size of the
1947                array).  */
1948             while (**mangled && **mangled != '_')
1949               ++(*mangled);
1950             if (**mangled == '_')
1951               {
1952                 string_appendn (&decl, p, *mangled - p);
1953                 string_append (&decl, "]");             
1954                 *mangled += 1;
1955               }
1956             else
1957               success = 0;
1958             break;
1959           }
1960
1961         /* A back reference to a previously seen type */
1962         case 'T':
1963           (*mangled)++;
1964           if (!get_count (mangled, &n) || n >= work -> ntypes)
1965             {
1966               success = 0;
1967             }
1968           else
1969             {
1970               remembered_type = work -> typevec[n];
1971               mangled = &remembered_type;
1972             }
1973           break;
1974
1975         /* A function */
1976         case 'F':
1977           (*mangled)++;
1978           if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1979             {
1980               string_prepend (&decl, "(");
1981               string_append (&decl, ")");
1982             }
1983           /* After picking off the function args, we expect to either find the
1984              function return type (preceded by an '_') or the end of the
1985              string.  */
1986           if (!demangle_args (work, mangled, &decl)
1987               || (**mangled != '_' && **mangled != '\0'))
1988             {
1989               success = 0;
1990             }
1991           if (success && (**mangled == '_'))
1992             {
1993               (*mangled)++;
1994             }
1995           break;
1996
1997         case 'M':
1998         case 'O':
1999           {
2000             constp = 0;
2001             volatilep = 0;
2002
2003             member = **mangled == 'M';
2004             (*mangled)++;
2005             if (!isdigit (**mangled))
2006               {
2007                 success = 0;
2008                 break;
2009               }
2010             n = consume_count (mangled);
2011             if (strlen (*mangled) < n)
2012               {
2013                 success = 0;
2014                 break;
2015               }
2016             string_append (&decl, ")");
2017             string_prepend (&decl, "::");
2018             string_prependn (&decl, *mangled, n);
2019             string_prepend (&decl, "(");
2020             *mangled += n;
2021             if (member)
2022               {
2023                 if (**mangled == 'C')
2024                   {
2025                     (*mangled)++;
2026                     constp = 1;
2027                   }
2028                 if (**mangled == 'V')
2029                   {
2030                     (*mangled)++;
2031                     volatilep = 1;
2032                   }
2033                 if (*(*mangled)++ != 'F')
2034                   {
2035                     success = 0;
2036                     break;
2037                   }
2038               }
2039             if ((member && !demangle_args (work, mangled, &decl))
2040                 || **mangled != '_')
2041               {
2042                 success = 0;
2043                 break;
2044               }
2045             (*mangled)++;
2046             if (! PRINT_ANSI_QUALIFIERS)
2047               {
2048                 break;
2049               }
2050             if (constp)
2051               {
2052                 APPEND_BLANK (&decl);
2053                 string_append (&decl, "const");
2054               }
2055             if (volatilep)
2056               {
2057                 APPEND_BLANK (&decl);
2058                 string_append (&decl, "volatile");
2059               }
2060             break;
2061           }
2062         case 'G':
2063             (*mangled)++;
2064             break;
2065
2066         case 'C':
2067           (*mangled)++;
2068 /*
2069           if ((*mangled)[1] == 'P')
2070             {
2071 */
2072               if (PRINT_ANSI_QUALIFIERS)
2073                 {
2074                   if (!STRING_EMPTY (&decl))
2075                     {
2076                       string_prepend (&decl, " ");
2077                     }
2078                   string_prepend (&decl, "const");
2079                 }
2080               break;
2081 /*
2082             }
2083 */
2084
2085           /* fall through */
2086         default:
2087           done = 1;
2088           break;
2089         }
2090     }
2091
2092   switch (**mangled)
2093     {
2094       /* A qualified name, such as "Outer::Inner".  */
2095       case 'Q':
2096         success = demangle_qualified (work, mangled, result, 0, 1);
2097         break;
2098
2099       default:
2100         success = demangle_fund_type (work, mangled, result);
2101         break;
2102     }
2103
2104   if (success)
2105     {
2106       if (!STRING_EMPTY (&decl))
2107         {
2108           string_append (result, " ");
2109           string_appends (result, &decl);
2110         }
2111     }
2112   else
2113     {
2114       string_delete (result);
2115     }
2116   string_delete (&decl);
2117   return (success);
2118 }
2119
2120 /* Given a pointer to a type string that represents a fundamental type
2121    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2122    string in which the demangled output is being built in RESULT, and
2123    the WORK structure, decode the types and add them to the result.
2124
2125    For example:
2126
2127         "Ci"    =>      "const int"
2128         "Sl"    =>      "signed long"
2129         "CUs"   =>      "const unsigned short"
2130
2131    */
2132
2133 static int
2134 demangle_fund_type (work, mangled, result)
2135      struct work_stuff *work;
2136      const char **mangled;
2137      string *result;
2138 {
2139   int done = 0;
2140   int success = 1;
2141
2142   /* First pick off any type qualifiers.  There can be more than one.  */
2143
2144   while (!done)
2145     {
2146       switch (**mangled)
2147         {
2148           case 'C':
2149             (*mangled)++;
2150             if (PRINT_ANSI_QUALIFIERS)
2151               {
2152                 APPEND_BLANK (result);
2153                 string_append (result, "const");
2154               }
2155             break;
2156           case 'U':
2157             (*mangled)++;
2158             APPEND_BLANK (result);
2159             string_append (result, "unsigned");
2160             break;
2161           case 'S': /* signed char only */
2162             (*mangled)++;
2163             APPEND_BLANK (result);
2164             string_append (result, "signed");
2165             break;
2166           case 'V':
2167             (*mangled)++;
2168             if (PRINT_ANSI_QUALIFIERS)
2169               {
2170                 APPEND_BLANK (result);
2171                 string_append (result, "volatile");
2172               }
2173             break;
2174           default:
2175             done = 1;
2176             break;
2177         }
2178     }
2179
2180   /* Now pick off the fundamental type.  There can be only one.  */
2181
2182   switch (**mangled)
2183     {
2184       case '\0':
2185       case '_':
2186         break;
2187       case 'v':
2188         (*mangled)++;
2189         APPEND_BLANK (result);
2190         string_append (result, "void");
2191         break;
2192       case 'x':
2193         (*mangled)++;
2194         APPEND_BLANK (result);
2195         string_append (result, "long long");
2196         break;
2197       case 'l':
2198         (*mangled)++;
2199         APPEND_BLANK (result);
2200         string_append (result, "long");
2201         break;
2202       case 'i':
2203         (*mangled)++;
2204         APPEND_BLANK (result);
2205         string_append (result, "int");
2206         break;
2207       case 's':
2208         (*mangled)++;
2209         APPEND_BLANK (result);
2210         string_append (result, "short");
2211         break;
2212       case 'b':
2213         (*mangled)++;
2214         APPEND_BLANK (result);
2215         string_append (result, "bool");
2216         break;
2217       case 'c':
2218         (*mangled)++;
2219         APPEND_BLANK (result);
2220         string_append (result, "char");
2221         break;
2222       case 'w':
2223         (*mangled)++;
2224         APPEND_BLANK (result);
2225         string_append (result, "wchar_t");
2226         break;
2227       case 'r':
2228         (*mangled)++;
2229         APPEND_BLANK (result);
2230         string_append (result, "long double");
2231         break;
2232       case 'd':
2233         (*mangled)++;
2234         APPEND_BLANK (result);
2235         string_append (result, "double");
2236         break;
2237       case 'f':
2238         (*mangled)++;
2239         APPEND_BLANK (result);
2240         string_append (result, "float");
2241         break;
2242       case 'G':
2243         (*mangled)++;
2244         if (!isdigit (**mangled))
2245           {
2246             success = 0;
2247             break;
2248           }
2249         /* fall through */
2250       /* An explicit type, such as "6mytype" or "7integer" */
2251       case '0':
2252       case '1':
2253       case '2':
2254       case '3':
2255       case '4':
2256       case '5':
2257       case '6':
2258       case '7':
2259       case '8':
2260       case '9':
2261         APPEND_BLANK (result);
2262         if (!demangle_class_name (work, mangled, result)) {
2263           --result->p;
2264           success = 0;
2265         }
2266         break;
2267       case 't':
2268         success = demangle_template(work,mangled, result, 0);
2269         break;
2270       default:
2271         success = 0;
2272         break;
2273       }
2274
2275   return (success);
2276 }
2277
2278 /* `result' will be initialized in do_type; it will be freed on failure */
2279
2280 static int
2281 do_arg (work, mangled, result)
2282      struct work_stuff *work;
2283      const char **mangled;
2284      string *result;
2285 {
2286   const char *start = *mangled;
2287
2288   if (!do_type (work, mangled, result))
2289     {
2290       return (0);
2291     }
2292   else
2293     {
2294       remember_type (work, start, *mangled - start);
2295       return (1);
2296     }
2297 }
2298
2299 static void
2300 remember_type (work, start, len)
2301      struct work_stuff *work;
2302      const char *start;
2303      int len;
2304 {
2305   char *tem;
2306
2307   if (work -> ntypes >= work -> typevec_size)
2308     {
2309       if (work -> typevec_size == 0)
2310         {
2311           work -> typevec_size = 3;
2312           work -> typevec =
2313             (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2314         }
2315       else
2316         {
2317           work -> typevec_size *= 2;
2318           work -> typevec =
2319             (char **) xrealloc ((char *)work -> typevec,
2320                                 sizeof (char *) * work -> typevec_size);
2321         }
2322     }
2323   tem = xmalloc (len + 1);
2324   memcpy (tem, start, len);
2325   tem[len] = '\0';
2326   work -> typevec[work -> ntypes++] = tem;
2327 }
2328
2329 /* Forget the remembered types, but not the type vector itself.  */
2330
2331 static void
2332 forget_types (work)
2333      struct work_stuff *work;
2334 {
2335   int i;
2336
2337   while (work -> ntypes > 0)
2338     {
2339       i = --(work -> ntypes);
2340       if (work -> typevec[i] != NULL)
2341         {
2342           free (work -> typevec[i]);
2343           work -> typevec[i] = NULL;
2344         }
2345     }
2346 }
2347
2348 /* Process the argument list part of the signature, after any class spec
2349    has been consumed, as well as the first 'F' character (if any).  For
2350    example:
2351
2352    "__als__3fooRT0"             =>      process "RT0"
2353    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
2354
2355    DECLP must be already initialised, usually non-empty.  It won't be freed
2356    on failure.
2357
2358    Note that g++ differs significantly from ARM and lucid style mangling
2359    with regards to references to previously seen types.  For example, given
2360    the source fragment:
2361
2362      class foo {
2363        public:
2364        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2365      };
2366
2367      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2368      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2369
2370    g++ produces the names:
2371
2372      __3fooiRT0iT2iT2
2373      foo__FiR3fooiT1iT1
2374
2375    while lcc (and presumably other ARM style compilers as well) produces:
2376
2377      foo__FiR3fooT1T2T1T2
2378      __ct__3fooFiR3fooT1T2T1T2
2379
2380    Note that g++ bases it's type numbers starting at zero and counts all
2381    previously seen types, while lucid/ARM bases it's type numbers starting
2382    at one and only considers types after it has seen the 'F' character
2383    indicating the start of the function args.  For lucid/ARM style, we
2384    account for this difference by discarding any previously seen types when
2385    we see the 'F' character, and subtracting one from the type number
2386    reference.
2387
2388  */
2389
2390 static int
2391 demangle_args (work, mangled, declp)
2392      struct work_stuff *work;
2393      const char **mangled;
2394      string *declp;
2395 {
2396   string arg;
2397   int need_comma = 0;
2398   int r;
2399   int t;
2400   const char *tem;
2401   char temptype;
2402
2403   if (PRINT_ARG_TYPES)
2404     {
2405       string_append (declp, "(");
2406       if (**mangled == '\0')
2407         {
2408           string_append (declp, "void");
2409         }
2410     }
2411
2412   while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2413     {
2414       if ((**mangled == 'N') || (**mangled == 'T'))
2415         {
2416           temptype = *(*mangled)++;
2417           
2418           if (temptype == 'N')
2419             {
2420               if (!get_count (mangled, &r))
2421                 {
2422                   return (0);
2423                 }
2424             }
2425           else
2426             {
2427               r = 1;
2428             }
2429           if (ARM_DEMANGLING && work -> ntypes >= 10)
2430             {
2431               /* If we have 10 or more types we might have more than a 1 digit
2432                  index so we'll have to consume the whole count here. This
2433                  will lose if the next thing is a type name preceded by a
2434                  count but it's impossible to demangle that case properly
2435                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2436                  Pc, ...)"  or "(..., type12, char *, ...)" */
2437               if ((t = consume_count(mangled)) == 0)
2438                 {
2439                   return (0);
2440                 }
2441             }
2442           else
2443             {
2444               if (!get_count (mangled, &t))
2445                 {
2446                   return (0);
2447                 }
2448             }
2449           if (LUCID_DEMANGLING || ARM_DEMANGLING)
2450             {
2451               t--;
2452             }
2453           /* Validate the type index.  Protect against illegal indices from
2454              malformed type strings.  */
2455           if ((t < 0) || (t >= work -> ntypes))
2456             {
2457               return (0);
2458             }
2459           while (--r >= 0)
2460             {
2461               tem = work -> typevec[t];
2462               if (need_comma && PRINT_ARG_TYPES)
2463                 {
2464                   string_append (declp, ", ");
2465                 }
2466               if (!do_arg (work, &tem, &arg))
2467                 {
2468                   return (0);
2469                 }
2470               if (PRINT_ARG_TYPES)
2471                 {
2472                   string_appends (declp, &arg);
2473                 }
2474               string_delete (&arg);
2475               need_comma = 1;
2476             }
2477         }
2478       else
2479         {
2480           if (need_comma & PRINT_ARG_TYPES)
2481             {
2482               string_append (declp, ", ");
2483             }
2484           if (!do_arg (work, mangled, &arg))
2485             {
2486               return (0);
2487             }
2488           if (PRINT_ARG_TYPES)
2489             {
2490               string_appends (declp, &arg);
2491             }
2492           string_delete (&arg);
2493           need_comma = 1;
2494         }
2495     }
2496
2497   if (**mangled == 'e')
2498     {
2499       (*mangled)++;
2500       if (PRINT_ARG_TYPES)
2501         {
2502           if (need_comma)
2503             {
2504               string_append (declp, ",");
2505             }
2506           string_append (declp, "...");
2507         }
2508     }
2509
2510   if (PRINT_ARG_TYPES)
2511     {
2512       string_append (declp, ")");
2513     }
2514   return (1);
2515 }
2516
2517 static void
2518 demangle_function_name (work, mangled, declp, scan)
2519      struct work_stuff *work;
2520      const char **mangled;
2521      string *declp;
2522      const char *scan;
2523 {
2524   int i;
2525   int len;
2526   string type;
2527   const char *tem;
2528
2529   string_appendn (declp, (*mangled), scan - (*mangled));
2530   string_need (declp, 1);
2531   *(declp -> p) = '\0';
2532
2533   /* Consume the function name, including the "__" separating the name
2534      from the signature.  We are guaranteed that SCAN points to the
2535      separator.  */
2536
2537   (*mangled) = scan + 2;
2538
2539   if (LUCID_DEMANGLING || ARM_DEMANGLING)
2540     {
2541
2542       /* See if we have an ARM style constructor or destructor operator.
2543          If so, then just record it, clear the decl, and return.
2544          We can't build the actual constructor/destructor decl until later,
2545          when we recover the class name from the signature.  */
2546
2547       if (strcmp (declp -> b, "__ct") == 0)
2548         {
2549           work -> constructor += 1;
2550           string_clear (declp);
2551           return;
2552         }
2553       else if (strcmp (declp -> b, "__dt") == 0)
2554         {
2555           work -> destructor += 1;
2556           string_clear (declp);
2557           return;
2558         }
2559     }
2560
2561   if (declp->p - declp->b >= 3 
2562       && declp->b[0] == 'o'
2563       && declp->b[1] == 'p'
2564       && strchr (cplus_markers, declp->b[2]) != NULL)
2565     {
2566       /* see if it's an assignment expression */
2567       if (declp->p - declp->b >= 10 /* op$assign_ */
2568           && memcmp (declp->b + 3, "assign_", 7) == 0)
2569         {
2570           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2571             {
2572               len = declp->p - declp->b - 10;
2573               if (strlen (optable[i].in) == len
2574                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
2575                 {
2576                   string_clear (declp);
2577                   string_append (declp, "operator");
2578                   string_append (declp, optable[i].out);
2579                   string_append (declp, "=");
2580                   break;
2581                 }
2582             }
2583         }
2584       else
2585         {
2586           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2587             {
2588               int len = declp->p - declp->b - 3;
2589               if (strlen (optable[i].in) == len 
2590                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
2591                 {
2592                   string_clear (declp);
2593                   string_append (declp, "operator");
2594                   string_append (declp, optable[i].out);
2595                   break;
2596                 }
2597             }
2598         }
2599     }
2600   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2601            && strchr (cplus_markers, declp->b[4]) != NULL)
2602     {
2603       /* type conversion operator */
2604       tem = declp->b + 5;
2605       if (do_type (work, &tem, &type))
2606         {
2607           string_clear (declp);
2608           string_append (declp, "operator ");
2609           string_appends (declp, &type);
2610           string_delete (&type);
2611         }
2612     }
2613   else if (declp->b[0] == '_' && declp->b[1] == '_'
2614           && declp->b[2] == 'o' && declp->b[3] == 'p')
2615     {
2616       /* ANSI.  */
2617       /* type conversion operator.  */
2618       tem = declp->b + 4;
2619       if (do_type (work, &tem, &type))
2620         {
2621           string_clear (declp);
2622           string_append (declp, "operator ");
2623           string_appends (declp, &type);
2624           string_delete (&type);
2625         }
2626     }
2627   else if (declp->b[0] == '_' && declp->b[1] == '_'
2628            && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2629            && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2630     {
2631       if (declp->b[4] == '\0')
2632         {
2633           /* Operator.  */
2634           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2635             {
2636               if (strlen (optable[i].in) == 2
2637                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2638                 {
2639                   string_clear (declp);
2640                   string_append (declp, "operator");
2641                   string_append (declp, optable[i].out);
2642                   break;
2643                 }
2644             }
2645         }
2646       else
2647         {
2648           if (declp->b[2] == 'a' && declp->b[5] == '\0')
2649             {
2650               /* Assignment.  */
2651               for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2652                 {
2653                   if (strlen (optable[i].in) == 3
2654                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2655                     {
2656                       string_clear (declp);
2657                       string_append (declp, "operator");
2658                       string_append (declp, optable[i].out);
2659                       break;
2660                     }                 
2661                 }
2662             }
2663         }
2664     }
2665 }
2666
2667 /* a mini string-handling package */
2668
2669 static void
2670 string_need (s, n)
2671      string *s;
2672      int n;
2673 {
2674   int tem;
2675
2676   if (s->b == NULL)
2677     {
2678       if (n < 32)
2679         {
2680           n = 32;
2681         }
2682       s->p = s->b = xmalloc (n);
2683       s->e = s->b + n;
2684     }
2685   else if (s->e - s->p < n)
2686     {
2687       tem = s->p - s->b;
2688       n += tem;
2689       n *= 2;
2690       s->b = xrealloc (s->b, n);
2691       s->p = s->b + tem;
2692       s->e = s->b + n;
2693     }
2694 }
2695
2696 static void
2697 string_delete (s)
2698      string *s;
2699 {
2700   if (s->b != NULL)
2701     {
2702       free (s->b);
2703       s->b = s->e = s->p = NULL;
2704     }
2705 }
2706
2707 static void
2708 string_init (s)
2709      string *s;
2710 {
2711   s->b = s->p = s->e = NULL;
2712 }
2713
2714 static void 
2715 string_clear (s)
2716      string *s;
2717 {
2718   s->p = s->b;
2719 }
2720
2721 #if 0
2722
2723 static int
2724 string_empty (s)
2725      string *s;
2726 {
2727   return (s->b == s->p);
2728 }
2729
2730 #endif
2731
2732 static void
2733 string_append (p, s)
2734      string *p;
2735      const char *s;
2736 {
2737   int n;
2738   if (s == NULL || *s == '\0')
2739     return;
2740   n = strlen (s);
2741   string_need (p, n);
2742   memcpy (p->p, s, n);
2743   p->p += n;
2744 }
2745
2746 static void
2747 string_appends (p, s)
2748      string *p, *s;
2749 {
2750   int n;
2751
2752   if (s->b != s->p)
2753     {
2754       n = s->p - s->b;
2755       string_need (p, n);
2756       memcpy (p->p, s->b, n);
2757       p->p += n;
2758     }
2759 }
2760
2761 static void
2762 string_appendn (p, s, n)
2763      string *p;
2764      const char *s;
2765      int n;
2766 {
2767   if (n != 0)
2768     {
2769       string_need (p, n);
2770       memcpy (p->p, s, n);
2771       p->p += n;
2772     }
2773 }
2774
2775 static void
2776 string_prepend (p, s)
2777      string *p;
2778      const char *s;
2779 {
2780   if (s != NULL && *s != '\0')
2781     {
2782       string_prependn (p, s, strlen (s));
2783     }
2784 }
2785
2786 static void
2787 string_prepends (p, s)
2788      string *p, *s;
2789 {
2790   if (s->b != s->p)
2791     {
2792       string_prependn (p, s->b, s->p - s->b);
2793     }
2794 }
2795
2796 static void
2797 string_prependn (p, s, n)
2798      string *p;
2799      const char *s;
2800      int n;
2801 {
2802   char *q;
2803
2804   if (n != 0)
2805     {
2806       string_need (p, n);
2807       for (q = p->p - 1; q >= p->b; q--)
2808         {
2809           q[n] = q[0];
2810         }
2811       memcpy (p->b, s, n);
2812       p->p += n;
2813     }
2814 }
2815
2816 /* To generate a standalone demangler program for testing purposes,
2817    just compile and link this file with -DMAIN and libiberty.a.  When
2818    run, it demangles each command line arg, or each stdin string, and
2819    prints the result on stdout.  */
2820
2821 #ifdef MAIN
2822
2823 static void
2824 demangle_it (mangled_name)
2825   char *mangled_name;
2826 {
2827   char *result;
2828
2829   result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2830   if (result == NULL)
2831     {
2832       printf ("%s\n", mangled_name);
2833     }
2834   else
2835     {
2836       printf ("%s\n", result);
2837       free (result);
2838     }
2839 }
2840
2841 #include "getopt.h"
2842
2843 static char *program_name;
2844 static char *program_version = VERSION;
2845
2846 static void
2847 usage (stream, status)
2848      FILE *stream;
2849      int status;
2850 {    
2851   fprintf (stream, "\
2852 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2853        [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2854        [--help] [--version] [arg...]\n",
2855            program_name);
2856   exit (status);
2857 }
2858
2859 #define MBUF_SIZE 512
2860 char mbuffer[MBUF_SIZE];
2861
2862 /* Defined in the automatically-generated underscore.c.  */
2863 extern int prepends_underscore;
2864
2865 int strip_underscore = 0;
2866
2867 static struct option long_options[] = {
2868   {"strip-underscores", no_argument, 0, '_'},
2869   {"format", required_argument, 0, 's'},
2870   {"help", no_argument, 0, 'h'},
2871   {"no-strip-underscores", no_argument, 0, 'n'},
2872   {"version", no_argument, 0, 'v'},
2873   {0, no_argument, 0, 0}
2874 };
2875
2876 int
2877 main (argc, argv)
2878      int argc;
2879      char **argv;
2880 {
2881   char *result;
2882   int c;
2883
2884   program_name = argv[0];
2885
2886   strip_underscore = prepends_underscore;
2887
2888   while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2889     {
2890       switch (c)
2891         {
2892           case '?':
2893             usage (stderr, 1);
2894             break;
2895           case 'h':
2896             usage (stdout, 0);
2897           case 'n':
2898             strip_underscore = 0;
2899             break;
2900           case 'v':
2901             printf ("GNU %s version %s\n", program_name, program_version);
2902             exit (0);
2903           case '_':
2904             strip_underscore = 1;
2905             break;
2906           case 's':
2907             if (strcmp (optarg, "gnu") == 0)
2908               {
2909                 current_demangling_style = gnu_demangling;
2910               }
2911             else if (strcmp (optarg, "lucid") == 0)
2912               {
2913                 current_demangling_style = lucid_demangling;
2914               }
2915             else if (strcmp (optarg, "arm") == 0)
2916               {
2917                 current_demangling_style = arm_demangling;
2918               }
2919             else
2920               {
2921                 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2922                          program_name, optarg);
2923                 exit (1);
2924               }
2925             break;
2926         }
2927     }
2928
2929   if (optind < argc)
2930     {
2931       for ( ; optind < argc; optind++)
2932         {
2933           demangle_it (argv[optind]);
2934         }
2935     }
2936   else
2937     {
2938       for (;;)
2939         {
2940           int i = 0;
2941           c = getchar ();
2942           /* Try to read a label.  */
2943           while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2944             {
2945               if (i >= MBUF_SIZE-1)
2946                 break;
2947               mbuffer[i++] = c;
2948               c = getchar ();
2949             }
2950           if (i > 0)
2951             {
2952               int skip_first = 0;
2953
2954               if (mbuffer[0] == '.')
2955                 ++skip_first;
2956               if (strip_underscore && mbuffer[skip_first] == '_')
2957                 ++skip_first;
2958
2959               if (skip_first > i)
2960                 skip_first = i;
2961
2962               mbuffer[i] = 0;
2963               
2964               result = cplus_demangle (mbuffer + skip_first,
2965                                        DMGL_PARAMS | DMGL_ANSI);
2966               if (result)
2967                 {
2968                   if (mbuffer[0] == '.')
2969                     putc ('.', stdout);
2970                   fputs (result, stdout);
2971                   free (result);
2972                 }
2973               else
2974                 fputs (mbuffer, stdout);
2975
2976               fflush (stdout);
2977             }
2978           if (c == EOF)
2979             break;
2980           putchar (c);
2981         }
2982     }
2983
2984   exit (0);
2985 }
2986
2987 static void
2988 fatal (str)
2989      char *str;
2990 {
2991   fprintf (stderr, "%s: %s\n", program_name, str);
2992   exit (1);
2993 }
2994
2995 char * malloc ();
2996 char * realloc ();
2997
2998 char *
2999 xmalloc (size)
3000      unsigned size;
3001 {
3002   register char *value = (char *) malloc (size);
3003   if (value == 0)
3004     fatal ("virtual memory exhausted");
3005   return value;
3006 }
3007
3008 char *
3009 xrealloc (ptr, size)
3010      char *ptr;
3011      unsigned size;
3012 {
3013   register char *value = (char *) realloc (ptr, size);
3014   if (value == 0)
3015     fatal ("virtual memory exhausted");
3016   return value;
3017 }
3018 #endif  /* main */