OSDN Git Service

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