OSDN Git Service

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