OSDN Git Service

0f1dcc54a54a38b9c222201db5a8b347a45b8140
[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             if (!STRING_EMPTY (&decl)
2495                 && (decl.b[0] == '*' || decl.b[0] == '&'))
2496               {
2497                 string_prepend (&decl, "(");
2498                 string_append (&decl, ")");
2499               }
2500             string_append (&decl, "[");
2501             if (**mangled != '_')
2502               success = demangle_template_value_parm (work, mangled, &decl,
2503                                                       tk_integral);
2504             if (**mangled == '_')
2505               ++(*mangled);
2506             string_append (&decl, "]");
2507             break;
2508           }
2509
2510         /* A back reference to a previously seen type */
2511         case 'T':
2512           (*mangled)++;
2513           if (!get_count (mangled, &n) || n >= work -> ntypes)
2514             {
2515               success = 0;
2516             }
2517           else
2518             {
2519               remembered_type = work -> typevec[n];
2520               mangled = &remembered_type;
2521             }
2522           break;
2523
2524           /* A function */
2525         case 'F':
2526           (*mangled)++;
2527             if (!STRING_EMPTY (&decl)
2528                 && (decl.b[0] == '*' || decl.b[0] == '&'))
2529             {
2530               string_prepend (&decl, "(");
2531               string_append (&decl, ")");
2532             }
2533           /* After picking off the function args, we expect to either find the
2534              function return type (preceded by an '_') or the end of the
2535              string.  */
2536           if (!demangle_nested_args (work, mangled, &decl)
2537               || (**mangled != '_' && **mangled != '\0'))
2538             {
2539               success = 0;
2540               break;
2541             }
2542           if (success && (**mangled == '_'))
2543             (*mangled)++;
2544           break;
2545
2546         case 'M':
2547         case 'O':
2548           {
2549             constp = 0;
2550             volatilep = 0;
2551
2552             member = **mangled == 'M';
2553             (*mangled)++;
2554             if (!isdigit (**mangled) && **mangled != 't')
2555               {
2556                 success = 0;
2557                 break;
2558               }
2559
2560             string_append (&decl, ")");
2561             string_prepend (&decl, SCOPE_STRING (work));
2562             if (isdigit (**mangled)) 
2563               {
2564                 n = consume_count (mangled);
2565                 if (strlen (*mangled) < n)
2566                   {
2567                     success = 0;
2568                     break;
2569                   }
2570                 string_prependn (&decl, *mangled, n);
2571                 *mangled += n;
2572               }
2573             else
2574               {
2575                 string temp;
2576                 string_init (&temp);
2577                 success = demangle_template (work, mangled, &temp,
2578                                              NULL, 1, 1);
2579                 if (success)
2580                   {
2581                     string_prependn (&decl, temp.b, temp.p - temp.b);
2582                     string_clear (&temp);
2583                   }
2584                 else
2585                   break;
2586               }
2587             string_prepend (&decl, "(");
2588             if (member)
2589               {
2590                 if (**mangled == 'C')
2591                   {
2592                     (*mangled)++;
2593                     constp = 1;
2594                   }
2595                 if (**mangled == 'V')
2596                   {
2597                     (*mangled)++;
2598                     volatilep = 1;
2599                   }
2600                 if (*(*mangled)++ != 'F')
2601                   {
2602                     success = 0;
2603                     break;
2604                   }
2605               }
2606             if ((member && !demangle_nested_args (work, mangled, &decl))
2607                 || **mangled != '_')
2608               {
2609                 success = 0;
2610                 break;
2611               }
2612             (*mangled)++;
2613             if (! PRINT_ANSI_QUALIFIERS)
2614               {
2615                 break;
2616               }
2617             if (constp)
2618               {
2619                 APPEND_BLANK (&decl);
2620                 string_append (&decl, "const");
2621               }
2622             if (volatilep)
2623               {
2624                 APPEND_BLANK (&decl);
2625                 string_append (&decl, "volatile");
2626               }
2627             break;
2628           }
2629         case 'G':
2630           (*mangled)++;
2631           break;
2632
2633         case 'C':
2634         case 'V':
2635           /*
2636             if ((*mangled)[1] == 'P')
2637             {
2638             */
2639           if (PRINT_ANSI_QUALIFIERS)
2640             {
2641               if (!STRING_EMPTY (&decl))
2642                 {
2643                   string_prepend (&decl, " ");
2644                 }
2645               string_prepend (&decl, 
2646                               (**mangled) == 'C' ? "const" : "volatile");
2647             }
2648           (*mangled)++;
2649           break;
2650           /*
2651             }
2652             */
2653
2654           /* fall through */
2655         default:
2656           done = 1;
2657           break;
2658         }
2659     }
2660
2661   if (success) switch (**mangled)
2662     {
2663       /* A qualified name, such as "Outer::Inner".  */
2664     case 'Q':
2665     case 'K':
2666       {
2667         success = demangle_qualified (work, mangled, result, 0, 1);
2668         break;
2669       }
2670
2671     /* A back reference to a previously seen squangled type */
2672     case 'B':
2673       (*mangled)++;
2674       if (!get_count (mangled, &n) || n >= work -> numb)
2675         success = 0;
2676       else
2677         string_append (result, work->btypevec[n]);
2678       break;
2679
2680     case 'X':
2681     case 'Y':
2682       /* A template parm.  We substitute the corresponding argument. */
2683       {
2684         int idx;
2685
2686         (*mangled)++;
2687         idx = consume_count_with_underscores (mangled);
2688
2689         if (idx == -1 
2690             || (work->tmpl_argvec && idx >= work->ntmpl_args)
2691             || consume_count_with_underscores (mangled) == -1)
2692           {
2693             success = 0;
2694             break;
2695           }
2696
2697         if (work->tmpl_argvec)
2698           string_append (result, work->tmpl_argvec[idx]);
2699         else
2700           {
2701             char buf[10];
2702             sprintf(buf, "T%d", idx);
2703             string_append (result, buf);
2704           }
2705
2706         success = 1;
2707       }
2708     break;
2709
2710     default:
2711       success = demangle_fund_type (work, mangled, result);
2712       if (tk == tk_none)
2713         tk = (type_kind_t) success;
2714       break;
2715     }
2716
2717   if (success)
2718     {
2719       if (!STRING_EMPTY (&decl))
2720         {
2721           string_append (result, " ");
2722           string_appends (result, &decl);
2723         }
2724     }
2725   else
2726     string_delete (result);
2727   string_delete (&decl);
2728
2729   if (success)
2730     /* Assume an integral type, if we're not sure.  */
2731     return (int) ((tk == tk_none) ? tk_integral : tk);
2732   else
2733     return 0;
2734 }
2735
2736 /* Given a pointer to a type string that represents a fundamental type
2737    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2738    string in which the demangled output is being built in RESULT, and
2739    the WORK structure, decode the types and add them to the result.
2740
2741    For example:
2742
2743         "Ci"    =>      "const int"
2744         "Sl"    =>      "signed long"
2745         "CUs"   =>      "const unsigned short"
2746
2747    The value returned is really a type_kind_t.  */
2748
2749 static int
2750 demangle_fund_type (work, mangled, result)
2751      struct work_stuff *work;
2752      const char **mangled;
2753      string *result;
2754 {
2755   int done = 0;
2756   int success = 1;
2757   string btype;
2758   type_kind_t tk = tk_integral;
2759
2760   string_init (&btype);
2761
2762   /* First pick off any type qualifiers.  There can be more than one.  */
2763
2764   while (!done)
2765     {
2766       switch (**mangled)
2767         {
2768         case 'C':
2769           (*mangled)++;
2770           if (PRINT_ANSI_QUALIFIERS)
2771             {
2772               APPEND_BLANK (result);
2773               string_append (result, "const");
2774             }
2775           break;
2776         case 'U':
2777           (*mangled)++;
2778           APPEND_BLANK (result);
2779           string_append (result, "unsigned");
2780           break;
2781         case 'S': /* signed char only */
2782           (*mangled)++;
2783           APPEND_BLANK (result);
2784           string_append (result, "signed");
2785           break;
2786         case 'V':
2787           (*mangled)++;
2788           if (PRINT_ANSI_QUALIFIERS)
2789             {
2790               APPEND_BLANK (result);
2791               string_append (result, "volatile");
2792             }
2793           break;
2794         case 'J':
2795           (*mangled)++;
2796           APPEND_BLANK (result);
2797           string_append (result, "__complex");
2798           break;
2799         default:
2800           done = 1;
2801           break;
2802         }
2803     }
2804
2805   /* Now pick off the fundamental type.  There can be only one.  */
2806
2807   switch (**mangled)
2808     {
2809     case '\0':
2810     case '_':
2811       break;
2812     case 'v':
2813       (*mangled)++;
2814       APPEND_BLANK (result);
2815       string_append (result, "void");
2816       break;
2817     case 'x':
2818       (*mangled)++;
2819       APPEND_BLANK (result);
2820       string_append (result, "long long");
2821       break;
2822     case 'l':
2823       (*mangled)++;
2824       APPEND_BLANK (result);
2825       string_append (result, "long");
2826       break;
2827     case 'i':
2828       (*mangled)++;
2829       APPEND_BLANK (result);
2830       string_append (result, "int");
2831       break;
2832     case 's':
2833       (*mangled)++;
2834       APPEND_BLANK (result);
2835       string_append (result, "short");
2836       break;
2837     case 'b':
2838       (*mangled)++;
2839       APPEND_BLANK (result);
2840       string_append (result, "bool");
2841       tk = tk_bool;
2842       break;
2843     case 'c':
2844       (*mangled)++;
2845       APPEND_BLANK (result);
2846       string_append (result, "char");
2847       tk = tk_char;
2848       break;
2849     case 'w':
2850       (*mangled)++;
2851       APPEND_BLANK (result);
2852       string_append (result, "wchar_t");
2853       tk = tk_char;
2854       break;
2855     case 'r':
2856       (*mangled)++;
2857       APPEND_BLANK (result);
2858       string_append (result, "long double");
2859       tk = tk_real;
2860       break;
2861     case 'd':
2862       (*mangled)++;
2863       APPEND_BLANK (result);
2864       string_append (result, "double");
2865       tk = tk_real;
2866       break;
2867     case 'f':
2868       (*mangled)++;
2869       APPEND_BLANK (result);
2870       string_append (result, "float");
2871       tk = tk_real;
2872       break;
2873     case 'G':
2874       (*mangled)++;
2875       if (!isdigit (**mangled))
2876         {
2877           success = 0;
2878           break;
2879         }
2880       /* fall through */
2881       /* An explicit type, such as "6mytype" or "7integer" */
2882     case '0':
2883     case '1':
2884     case '2':
2885     case '3':
2886     case '4':
2887     case '5':
2888     case '6':
2889     case '7':
2890     case '8':
2891     case '9':
2892       {
2893         int bindex = register_Btype (work);
2894         string btype;
2895         string_init (&btype);
2896         if (demangle_class_name (work, mangled, &btype)) {
2897           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2898           APPEND_BLANK (result);
2899           string_appends (result, &btype);
2900         }
2901         else 
2902           success = 0;
2903         string_delete (&btype);
2904         break;
2905       }
2906     case 't':
2907       {
2908         success = demangle_template (work, mangled, &btype, 0, 1, 1);
2909         string_appends (result, &btype);
2910         break;
2911       }
2912     default:
2913       success = 0;
2914       break;
2915     }
2916
2917   return success ? ((int) tk) : 0;
2918 }
2919
2920 /* Demangle the next argument, given by MANGLED into RESULT, which
2921    *should be an uninitialized* string.  It will be initialized here,
2922    and free'd should anything go wrong.  */
2923
2924 static int
2925 do_arg (work, mangled, result)
2926      struct work_stuff *work;
2927      const char **mangled;
2928      string *result;
2929 {
2930   /* Remember where we started so that we can record the type, for
2931      non-squangling type remembering.  */
2932   const char *start = *mangled;
2933
2934   string_init (result);
2935
2936   if (work->nrepeats > 0)
2937     {
2938       --work->nrepeats;
2939
2940       if (work->previous_argument == 0)
2941         return 0;
2942
2943       /* We want to reissue the previous type in this argument list.  */ 
2944       string_appends (result, work->previous_argument);
2945       return 1;
2946     }
2947
2948   if (**mangled == 'n')
2949     {
2950       /* A squangling-style repeat.  */
2951       (*mangled)++;
2952       work->nrepeats = consume_count(mangled);
2953
2954       if (work->nrepeats == 0)
2955         /* This was not a repeat count after all.  */
2956         return 0;
2957
2958       if (work->nrepeats > 9)
2959         {
2960           if (**mangled != '_')
2961             /* The repeat count should be followed by an '_' in this
2962                case.  */
2963             return 0;
2964           else
2965             (*mangled)++;
2966         }
2967       
2968       /* Now, the repeat is all set up.  */
2969       return do_arg (work, mangled, result);
2970     }
2971
2972   /* Save the result in WORK->previous_argument so that we can find it
2973      if it's repeated.  Note that saving START is not good enough: we
2974      do not want to add additional types to the back-referenceable
2975      type vector when processing a repeated type.  */
2976   if (work->previous_argument)
2977     string_clear (work->previous_argument);
2978   else
2979     {
2980       work->previous_argument = (string*) xmalloc (sizeof (string));
2981       string_init (work->previous_argument);
2982     }
2983
2984   if (!do_type (work, mangled, work->previous_argument))
2985     return 0;
2986
2987   string_appends (result, work->previous_argument);
2988
2989   remember_type (work, start, *mangled - start);
2990   return 1;
2991 }
2992
2993 static void
2994 remember_type (work, start, len)
2995      struct work_stuff *work;
2996      const char *start;
2997      int len;
2998 {
2999   char *tem;
3000
3001   if (work->forgetting_types)
3002     return;
3003
3004   if (work -> ntypes >= work -> typevec_size)
3005     {
3006       if (work -> typevec_size == 0)
3007         {
3008           work -> typevec_size = 3;
3009           work -> typevec
3010             = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3011         }
3012       else
3013         {
3014           work -> typevec_size *= 2;
3015           work -> typevec
3016             = (char **) xrealloc ((char *)work -> typevec,
3017                                   sizeof (char *) * work -> typevec_size);
3018         }
3019     }
3020   tem = xmalloc (len + 1);
3021   memcpy (tem, start, len);
3022   tem[len] = '\0';
3023   work -> typevec[work -> ntypes++] = tem;
3024 }
3025
3026
3027 /* Remember a K type class qualifier. */
3028 static void
3029 remember_Ktype (work, start, len)
3030      struct work_stuff *work;
3031      const char *start;
3032      int len;
3033 {
3034   char *tem;
3035
3036   if (work -> numk >= work -> ksize)
3037     {
3038       if (work -> ksize == 0)
3039         {
3040           work -> ksize = 5;
3041           work -> ktypevec
3042             = (char **) xmalloc (sizeof (char *) * work -> ksize);
3043         }
3044       else
3045         {
3046           work -> ksize *= 2;
3047           work -> ktypevec
3048             = (char **) xrealloc ((char *)work -> ktypevec,
3049                                   sizeof (char *) * work -> ksize);
3050         }
3051     }
3052   tem = xmalloc (len + 1);
3053   memcpy (tem, start, len);
3054   tem[len] = '\0';
3055   work -> ktypevec[work -> numk++] = tem;
3056 }
3057
3058 /* Register a B code, and get an index for it. B codes are registered
3059    as they are seen, rather than as they are completed, so map<temp<char> >  
3060    registers map<temp<char> > as B0, and temp<char> as B1 */
3061
3062 static int
3063 register_Btype (work)
3064      struct work_stuff *work;
3065 {
3066   int ret;
3067  
3068   if (work -> numb >= work -> bsize)
3069     {
3070       if (work -> bsize == 0)
3071         {
3072           work -> bsize = 5;
3073           work -> btypevec
3074             = (char **) xmalloc (sizeof (char *) * work -> bsize);
3075         }
3076       else
3077         {
3078           work -> bsize *= 2;
3079           work -> btypevec
3080             = (char **) xrealloc ((char *)work -> btypevec,
3081                                   sizeof (char *) * work -> bsize);
3082         }
3083     }
3084   ret = work -> numb++;
3085   work -> btypevec[ret] = NULL;
3086   return(ret);
3087 }
3088
3089 /* Store a value into a previously registered B code type. */
3090
3091 static void
3092 remember_Btype (work, start, len, index)
3093      struct work_stuff *work;
3094      const char *start;
3095      int len, index;
3096 {
3097   char *tem;
3098
3099   tem = xmalloc (len + 1);
3100   memcpy (tem, start, len);
3101   tem[len] = '\0';
3102   work -> btypevec[index] = tem;
3103 }
3104
3105 /* Lose all the info related to B and K type codes. */
3106 static void
3107 forget_B_and_K_types (work)
3108      struct work_stuff *work;
3109 {
3110   int i;
3111
3112   while (work -> numk > 0)
3113     {
3114       i = --(work -> numk);
3115       if (work -> ktypevec[i] != NULL)
3116         {
3117           free (work -> ktypevec[i]);
3118           work -> ktypevec[i] = NULL;
3119         }
3120     }
3121
3122   while (work -> numb > 0)
3123     {
3124       i = --(work -> numb);
3125       if (work -> btypevec[i] != NULL)
3126         {
3127           free (work -> btypevec[i]);
3128           work -> btypevec[i] = NULL;
3129         }
3130     }
3131 }
3132 /* Forget the remembered types, but not the type vector itself.  */
3133
3134 static void
3135 forget_types (work)
3136      struct work_stuff *work;
3137 {
3138   int i;
3139
3140   while (work -> ntypes > 0)
3141     {
3142       i = --(work -> ntypes);
3143       if (work -> typevec[i] != NULL)
3144         {
3145           free (work -> typevec[i]);
3146           work -> typevec[i] = NULL;
3147         }
3148     }
3149 }
3150
3151 /* Process the argument list part of the signature, after any class spec
3152    has been consumed, as well as the first 'F' character (if any).  For
3153    example:
3154
3155    "__als__3fooRT0"             =>      process "RT0"
3156    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
3157
3158    DECLP must be already initialised, usually non-empty.  It won't be freed
3159    on failure.
3160
3161    Note that g++ differs significantly from ARM and lucid style mangling
3162    with regards to references to previously seen types.  For example, given
3163    the source fragment:
3164
3165      class foo {
3166        public:
3167        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3168      };
3169
3170      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3171      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3172
3173    g++ produces the names:
3174
3175      __3fooiRT0iT2iT2
3176      foo__FiR3fooiT1iT1
3177
3178    while lcc (and presumably other ARM style compilers as well) produces:
3179
3180      foo__FiR3fooT1T2T1T2
3181      __ct__3fooFiR3fooT1T2T1T2
3182
3183    Note that g++ bases its type numbers starting at zero and counts all
3184    previously seen types, while lucid/ARM bases its type numbers starting
3185    at one and only considers types after it has seen the 'F' character
3186    indicating the start of the function args.  For lucid/ARM style, we
3187    account for this difference by discarding any previously seen types when
3188    we see the 'F' character, and subtracting one from the type number
3189    reference.
3190
3191  */
3192
3193 static int
3194 demangle_args (work, mangled, declp)
3195      struct work_stuff *work;
3196      const char **mangled;
3197      string *declp;
3198 {
3199   string arg;
3200   int need_comma = 0;
3201   int r;
3202   int t;
3203   const char *tem;
3204   char temptype;
3205
3206   if (PRINT_ARG_TYPES)
3207     {
3208       string_append (declp, "(");
3209       if (**mangled == '\0')
3210         {
3211           string_append (declp, "void");
3212         }
3213     }
3214
3215   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3216          || work->nrepeats > 0)
3217     {
3218       if ((**mangled == 'N') || (**mangled == 'T'))
3219         {
3220           temptype = *(*mangled)++;
3221           
3222           if (temptype == 'N')
3223             {
3224               if (!get_count (mangled, &r))
3225                 {
3226                   return (0);
3227                 }
3228             }
3229           else
3230             {
3231               r = 1;
3232             }
3233           if (ARM_DEMANGLING && work -> ntypes >= 10)
3234             {
3235               /* If we have 10 or more types we might have more than a 1 digit
3236                  index so we'll have to consume the whole count here. This
3237                  will lose if the next thing is a type name preceded by a
3238                  count but it's impossible to demangle that case properly
3239                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3240                  Pc, ...)"  or "(..., type12, char *, ...)" */
3241               if ((t = consume_count(mangled)) == 0)
3242                 {
3243                   return (0);
3244                 }
3245             }
3246           else
3247             {
3248               if (!get_count (mangled, &t))
3249                 {
3250                   return (0);
3251                 }
3252             }
3253           if (LUCID_DEMANGLING || ARM_DEMANGLING)
3254             {
3255               t--;
3256             }
3257           /* Validate the type index.  Protect against illegal indices from
3258              malformed type strings.  */
3259           if ((t < 0) || (t >= work -> ntypes))
3260             {
3261               return (0);
3262             }
3263           while (work->nrepeats > 0 || --r >= 0)
3264             {
3265               tem = work -> typevec[t];
3266               if (need_comma && PRINT_ARG_TYPES)
3267                 {
3268                   string_append (declp, ", ");
3269                 }
3270               if (!do_arg (work, &tem, &arg))
3271                 {
3272                   return (0);
3273                 }
3274               if (PRINT_ARG_TYPES)
3275                 {
3276                   string_appends (declp, &arg);
3277                 }
3278               string_delete (&arg);
3279               need_comma = 1;
3280             }
3281         }
3282       else
3283         {
3284           if (need_comma && PRINT_ARG_TYPES)
3285             string_append (declp, ", ");
3286           if (!do_arg (work, mangled, &arg))
3287             return (0);
3288           if (PRINT_ARG_TYPES)
3289             string_appends (declp, &arg);
3290           string_delete (&arg);
3291           need_comma = 1;
3292         }
3293     }
3294
3295   if (**mangled == 'e')
3296     {
3297       (*mangled)++;
3298       if (PRINT_ARG_TYPES)
3299         {
3300           if (need_comma)
3301             {
3302               string_append (declp, ",");
3303             }
3304           string_append (declp, "...");
3305         }
3306     }
3307
3308   if (PRINT_ARG_TYPES)
3309     {
3310       string_append (declp, ")");
3311     }
3312   return (1);
3313 }
3314
3315 /* Like demangle_args, but for demangling the argument lists of function
3316    and method pointers or references, not top-level declarations.  */
3317
3318 static int
3319 demangle_nested_args (work, mangled, declp)
3320      struct work_stuff *work;
3321      const char **mangled;
3322      string *declp;
3323 {
3324   string* saved_previous_argument;
3325   int result;
3326   int saved_nrepeats;
3327
3328   /* The G++ name-mangling algorithm does not remember types on nested
3329      argument lists, unless -fsquangling is used, and in that case the
3330      type vector updated by remember_type is not used.  So, we turn
3331      off remembering of types here.  */
3332   ++work->forgetting_types;
3333
3334   /* For the repeat codes used with -fsquangling, we must keep track of
3335      the last argument.  */
3336   saved_previous_argument = work->previous_argument;
3337   saved_nrepeats = work->nrepeats;
3338   work->previous_argument = 0;
3339   work->nrepeats = 0;
3340
3341   /* Actually demangle the arguments.  */
3342   result = demangle_args (work, mangled, declp);
3343   
3344   /* Restore the previous_argument field.  */
3345   if (work->previous_argument)
3346     string_delete (work->previous_argument);
3347   work->previous_argument = saved_previous_argument;
3348   work->nrepeats = saved_nrepeats;
3349
3350   return result;
3351 }
3352
3353 static void
3354 demangle_function_name (work, mangled, declp, scan)
3355      struct work_stuff *work;
3356      const char **mangled;
3357      string *declp;
3358      const char *scan;
3359 {
3360   size_t i;
3361   string type;
3362   const char *tem;
3363
3364   string_appendn (declp, (*mangled), scan - (*mangled));
3365   string_need (declp, 1);
3366   *(declp -> p) = '\0';
3367
3368   /* Consume the function name, including the "__" separating the name
3369      from the signature.  We are guaranteed that SCAN points to the
3370      separator.  */
3371
3372   (*mangled) = scan + 2;
3373
3374   if (LUCID_DEMANGLING || ARM_DEMANGLING)
3375     {
3376
3377       /* See if we have an ARM style constructor or destructor operator.
3378          If so, then just record it, clear the decl, and return.
3379          We can't build the actual constructor/destructor decl until later,
3380          when we recover the class name from the signature.  */
3381
3382       if (strcmp (declp -> b, "__ct") == 0)
3383         {
3384           work -> constructor += 1;
3385           string_clear (declp);
3386           return;
3387         }
3388       else if (strcmp (declp -> b, "__dt") == 0)
3389         {
3390           work -> destructor += 1;
3391           string_clear (declp);
3392           return;
3393         }
3394     }
3395
3396   if (declp->p - declp->b >= 3 
3397       && declp->b[0] == 'o'
3398       && declp->b[1] == 'p'
3399       && strchr (cplus_markers, declp->b[2]) != NULL)
3400     {
3401       /* see if it's an assignment expression */
3402       if (declp->p - declp->b >= 10 /* op$assign_ */
3403           && memcmp (declp->b + 3, "assign_", 7) == 0)
3404         {
3405           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3406             {
3407               int len = declp->p - declp->b - 10;
3408               if (strlen (optable[i].in) == len
3409                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
3410                 {
3411                   string_clear (declp);
3412                   string_append (declp, "operator");
3413                   string_append (declp, optable[i].out);
3414                   string_append (declp, "=");
3415                   break;
3416                 }
3417             }
3418         }
3419       else
3420         {
3421           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3422             {
3423               int len = declp->p - declp->b - 3;
3424               if (strlen (optable[i].in) == len 
3425                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
3426                 {
3427                   string_clear (declp);
3428                   string_append (declp, "operator");
3429                   string_append (declp, optable[i].out);
3430                   break;
3431                 }
3432             }
3433         }
3434     }
3435   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3436            && strchr (cplus_markers, declp->b[4]) != NULL)
3437     {
3438       /* type conversion operator */
3439       tem = declp->b + 5;
3440       if (do_type (work, &tem, &type))
3441         {
3442           string_clear (declp);
3443           string_append (declp, "operator ");
3444           string_appends (declp, &type);
3445           string_delete (&type);
3446         }
3447     }
3448   else if (declp->b[0] == '_' && declp->b[1] == '_'
3449            && declp->b[2] == 'o' && declp->b[3] == 'p')
3450     {
3451       /* ANSI.  */
3452       /* type conversion operator.  */
3453       tem = declp->b + 4;
3454       if (do_type (work, &tem, &type))
3455         {
3456           string_clear (declp);
3457           string_append (declp, "operator ");
3458           string_appends (declp, &type);
3459           string_delete (&type);
3460         }
3461     }
3462   else if (declp->b[0] == '_' && declp->b[1] == '_'
3463            && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3464            && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3465     {
3466       if (declp->b[4] == '\0')
3467         {
3468           /* Operator.  */
3469           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3470             {
3471               if (strlen (optable[i].in) == 2
3472                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3473                 {
3474                   string_clear (declp);
3475                   string_append (declp, "operator");
3476                   string_append (declp, optable[i].out);
3477                   break;
3478                 }
3479             }
3480         }
3481       else
3482         {
3483           if (declp->b[2] == 'a' && declp->b[5] == '\0')
3484             {
3485               /* Assignment.  */
3486               for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3487                 {
3488                   if (strlen (optable[i].in) == 3
3489                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3490                     {
3491                       string_clear (declp);
3492                       string_append (declp, "operator");
3493                       string_append (declp, optable[i].out);
3494                       break;
3495                     }                 
3496                 }
3497             }
3498         }
3499     }
3500 }
3501
3502 /* a mini string-handling package */
3503
3504 static void
3505 string_need (s, n)
3506      string *s;
3507      int n;
3508 {
3509   int tem;
3510
3511   if (s->b == NULL)
3512     {
3513       if (n < 32)
3514         {
3515           n = 32;
3516         }
3517       s->p = s->b = xmalloc (n);
3518       s->e = s->b + n;
3519     }
3520   else if (s->e - s->p < n)
3521     {
3522       tem = s->p - s->b;
3523       n += tem;
3524       n *= 2;
3525       s->b = xrealloc (s->b, n);
3526       s->p = s->b + tem;
3527       s->e = s->b + n;
3528     }
3529 }
3530
3531 static void
3532 string_delete (s)
3533      string *s;
3534 {
3535   if (s->b != NULL)
3536     {
3537       free (s->b);
3538       s->b = s->e = s->p = NULL;
3539     }
3540 }
3541
3542 static void
3543 string_init (s)
3544      string *s;
3545 {
3546   s->b = s->p = s->e = NULL;
3547 }
3548
3549 static void 
3550 string_clear (s)
3551      string *s;
3552 {
3553   s->p = s->b;
3554 }
3555
3556 #if 0
3557
3558 static int
3559 string_empty (s)
3560      string *s;
3561 {
3562   return (s->b == s->p);
3563 }
3564
3565 #endif
3566
3567 static void
3568 string_append (p, s)
3569      string *p;
3570      const char *s;
3571 {
3572   int n;
3573   if (s == NULL || *s == '\0')
3574     return;
3575   n = strlen (s);
3576   string_need (p, n);
3577   memcpy (p->p, s, n);
3578   p->p += n;
3579 }
3580
3581 static void
3582 string_appends (p, s)
3583      string *p, *s;
3584 {
3585   int n;
3586
3587   if (s->b != s->p)
3588     {
3589       n = s->p - s->b;
3590       string_need (p, n);
3591       memcpy (p->p, s->b, n);
3592       p->p += n;
3593     }
3594 }
3595
3596 static void
3597 string_appendn (p, s, n)
3598      string *p;
3599      const char *s;
3600      int n;
3601 {
3602   if (n != 0)
3603     {
3604       string_need (p, n);
3605       memcpy (p->p, s, n);
3606       p->p += n;
3607     }
3608 }
3609
3610 static void
3611 string_prepend (p, s)
3612      string *p;
3613      const char *s;
3614 {
3615   if (s != NULL && *s != '\0')
3616     {
3617       string_prependn (p, s, strlen (s));
3618     }
3619 }
3620
3621 static void
3622 string_prepends (p, s)
3623      string *p, *s;
3624 {
3625   if (s->b != s->p)
3626     {
3627       string_prependn (p, s->b, s->p - s->b);
3628     }
3629 }
3630
3631 static void
3632 string_prependn (p, s, n)
3633      string *p;
3634      const char *s;
3635      int n;
3636 {
3637   char *q;
3638
3639   if (n != 0)
3640     {
3641       string_need (p, n);
3642       for (q = p->p - 1; q >= p->b; q--)
3643         {
3644           q[n] = q[0];
3645         }
3646       memcpy (p->b, s, n);
3647       p->p += n;
3648     }
3649 }
3650
3651 /* To generate a standalone demangler program for testing purposes,
3652    just compile and link this file with -DMAIN and libiberty.a.  When
3653    run, it demangles each command line arg, or each stdin string, and
3654    prints the result on stdout.  */
3655
3656 #ifdef MAIN
3657
3658 #include "getopt.h"
3659
3660 static char *program_name;
3661 static char *program_version = VERSION;
3662 static int flags = DMGL_PARAMS | DMGL_ANSI;
3663
3664 static void demangle_it PARAMS ((char *));
3665 static void usage PARAMS ((FILE *, int));
3666 static void fatal PARAMS ((char *));
3667
3668 static void
3669 demangle_it (mangled_name)
3670      char *mangled_name;
3671 {
3672   char *result;
3673
3674   result = cplus_demangle (mangled_name, flags);
3675   if (result == NULL)
3676     {
3677       printf ("%s\n", mangled_name);
3678     }
3679   else
3680     {
3681       printf ("%s\n", result);
3682       free (result);
3683     }
3684 }
3685
3686 static void
3687 usage (stream, status)
3688      FILE *stream;
3689      int status;
3690 {    
3691   fprintf (stream, "\
3692 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3693       [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3694       [--help] [--version] [arg...]\n",
3695            program_name);
3696   exit (status);
3697 }
3698
3699 #define MBUF_SIZE 32767
3700 char mbuffer[MBUF_SIZE];
3701
3702 /* Defined in the automatically-generated underscore.c.  */
3703 extern int prepends_underscore;
3704
3705 int strip_underscore = 0;
3706
3707 static struct option long_options[] = {
3708   {"strip-underscores", no_argument, 0, '_'},
3709   {"format", required_argument, 0, 's'},
3710   {"help", no_argument, 0, 'h'},
3711   {"no-strip-underscores", no_argument, 0, 'n'},
3712   {"version", no_argument, 0, 'v'},
3713   {0, no_argument, 0, 0}
3714 };
3715
3716 /* More 'friendly' abort that prints the line and file.
3717    config.h can #define abort fancy_abort if you like that sort of thing.  */
3718
3719 void
3720 fancy_abort ()
3721 {
3722   fatal ("Internal gcc abort.");
3723 }
3724
3725 int
3726 main (argc, argv)
3727      int argc;
3728      char **argv;
3729 {
3730   char *result;
3731   int c;
3732
3733   program_name = argv[0];
3734
3735   strip_underscore = prepends_underscore;
3736
3737   while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3738     {
3739       switch (c)
3740         {
3741         case '?':
3742           usage (stderr, 1);
3743           break;
3744         case 'h':
3745           usage (stdout, 0);
3746         case 'n':
3747           strip_underscore = 0;
3748           break;
3749         case 'v':
3750           printf ("GNU %s version %s\n", program_name, program_version);
3751           exit (0);
3752         case '_':
3753           strip_underscore = 1;
3754           break;
3755         case 's':
3756           if (strcmp (optarg, "gnu") == 0)
3757             {
3758               current_demangling_style = gnu_demangling;
3759             }
3760           else if (strcmp (optarg, "lucid") == 0)
3761             {
3762               current_demangling_style = lucid_demangling;
3763             }
3764           else if (strcmp (optarg, "arm") == 0)
3765             {
3766               current_demangling_style = arm_demangling;
3767             }
3768           else
3769             {
3770               fprintf (stderr, "%s: unknown demangling style `%s'\n",
3771                        program_name, optarg);
3772               exit (1);
3773             }
3774           break;
3775         }
3776     }
3777
3778   if (optind < argc)
3779     {
3780       for ( ; optind < argc; optind++)
3781         {
3782           demangle_it (argv[optind]);
3783         }
3784     }
3785   else
3786     {
3787       for (;;)
3788         {
3789           int i = 0;
3790           c = getchar ();
3791           /* Try to read a label.  */
3792           while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3793             {
3794               if (i >= MBUF_SIZE-1)
3795                 break;
3796               mbuffer[i++] = c;
3797               c = getchar ();
3798             }
3799           if (i > 0)
3800             {
3801               int skip_first = 0;
3802
3803               if (mbuffer[0] == '.')
3804                 ++skip_first;
3805               if (strip_underscore && mbuffer[skip_first] == '_')
3806                 ++skip_first;
3807
3808               if (skip_first > i)
3809                 skip_first = i;
3810
3811               mbuffer[i] = 0;
3812               
3813               result = cplus_demangle (mbuffer + skip_first, flags);
3814               if (result)
3815                 {
3816                   if (mbuffer[0] == '.')
3817                     putc ('.', stdout);
3818                   fputs (result, stdout);
3819                   free (result);
3820                 }
3821               else
3822                 fputs (mbuffer, stdout);
3823
3824               fflush (stdout);
3825             }
3826           if (c == EOF)
3827             break;
3828           putchar (c);
3829         }
3830     }
3831
3832   exit (0);
3833 }
3834
3835 static void
3836 fatal (str)
3837      char *str;
3838 {
3839   fprintf (stderr, "%s: %s\n", program_name, str);
3840   exit (1);
3841 }
3842
3843 char *
3844 xmalloc (size)
3845      unsigned size;
3846 {
3847   register char *value = (char *) malloc (size);
3848   if (value == 0)
3849     fatal ("virtual memory exhausted");
3850   return value;
3851 }
3852
3853 char *
3854 xrealloc (ptr, size)
3855      char *ptr;
3856      unsigned size;
3857 {
3858   register char *value = (char *) realloc (ptr, size);
3859   if (value == 0)
3860     fatal ("virtual memory exhausted");
3861   return value;
3862 }
3863 #endif  /* main */