OSDN Git Service

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