OSDN Git Service

Tue Oct 20 12:29:02 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
[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 ((unsigned char)**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 ((unsigned char)**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 ((int) 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 ((int) 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 ((int) 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 ((unsigned char)**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 ((unsigned char)**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 ((unsigned char)**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 ((unsigned char)**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 = 0;
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
1425               || (int) strlen (*mangled) < r)
1426             {
1427               return (0);
1428             }
1429           string_appendn (tname, *mangled, r);
1430           if (trawname)
1431             string_appendn (trawname, *mangled, r);
1432           *mangled += r;
1433         }
1434     }
1435   string_append (tname, "<");
1436   /* get size of template parameter list */
1437   if (!get_count (mangled, &r))
1438     {
1439       return (0);
1440     }
1441   if (!is_type)
1442     {
1443       /* Create an array for saving the template argument values. */
1444       work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1445       work->ntmpl_args = r;
1446       for (i = 0; i < r; i++)
1447         work->tmpl_argvec[i] = 0;
1448     }
1449   for (i = 0; i < r; i++)
1450     {
1451       if (need_comma)
1452         {
1453           string_append (tname, ", ");
1454         }
1455       /* Z for type parameters */
1456       if (**mangled == 'Z')
1457         {
1458           (*mangled)++;
1459           /* temp is initialized in do_type */
1460           success = do_type (work, mangled, &temp);
1461           if (success)
1462             {
1463               string_appends (tname, &temp);
1464
1465               if (!is_type)
1466                 {
1467                   /* Save the template argument. */
1468                   int len = temp.p - temp.b;
1469                   work->tmpl_argvec[i] = xmalloc (len + 1);
1470                   memcpy (work->tmpl_argvec[i], temp.b, len);
1471                   work->tmpl_argvec[i][len] = '\0';
1472                 }
1473             }
1474           string_delete(&temp);
1475           if (!success)
1476             {
1477               break;
1478             }
1479         }
1480       /* z for template parameters */
1481       else if (**mangled == 'z')
1482         {
1483           int r2;
1484           (*mangled)++;
1485           success = demangle_template_template_parm (work, mangled, tname);
1486           
1487           if (success
1488               && (r2 = consume_count (mangled)) > 0
1489               && (int) strlen (*mangled) >= r2)
1490             {
1491               string_append (tname, " ");
1492               string_appendn (tname, *mangled, r2);
1493               if (!is_type)
1494                 {
1495                   /* Save the template argument. */
1496                   int len = r2;
1497                   work->tmpl_argvec[i] = xmalloc (len + 1);
1498                   memcpy (work->tmpl_argvec[i], *mangled, len);
1499                   work->tmpl_argvec[i][len] = '\0';
1500                 }
1501               *mangled += r2;
1502             }
1503           if (!success)
1504             {
1505               break;
1506             }
1507         }
1508       else
1509         {
1510           string  param;
1511           string* s;
1512
1513           /* otherwise, value parameter */
1514
1515           /* temp is initialized in do_type */
1516           success = do_type (work, mangled, &temp);
1517           string_delete(&temp);
1518           if (!success)
1519             break;
1520
1521           if (!is_type)
1522             {
1523               s = &param;
1524               string_init (s);
1525             }
1526           else
1527             s = tname;
1528
1529           success = demangle_template_value_parm (work, mangled, s,
1530                                                   (type_kind_t) success);
1531
1532           if (!success)
1533             {
1534               if (!is_type)
1535                 string_delete (s);
1536               success = 0;
1537               break;
1538             }
1539
1540           if (!is_type)
1541             {
1542               int len = s->p - s->b;
1543               work->tmpl_argvec[i] = xmalloc (len + 1);
1544               memcpy (work->tmpl_argvec[i], s->b, len);
1545               work->tmpl_argvec[i][len] = '\0';
1546               
1547               string_appends (tname, s);
1548               string_delete (s);
1549             }
1550         }
1551       need_comma = 1;
1552     }
1553     {
1554   if (tname->p[-1] == '>')
1555     string_append (tname, " ");
1556   string_append (tname, ">");
1557     }
1558   
1559   if (is_type && remember)
1560     remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1561
1562   /*
1563     if (work -> static_type)
1564     {
1565     string_append (declp, *mangled + 1);
1566     *mangled += strlen (*mangled);
1567     success = 1;
1568     }
1569     else
1570     {
1571     success = demangle_args (work, mangled, declp);
1572     }
1573     }
1574     */
1575   return (success);
1576 }
1577
1578 static int
1579 arm_pt (work, mangled, n, anchor, args)
1580      struct work_stuff *work;
1581      const char *mangled;
1582      int n;
1583      const char **anchor, **args;
1584 {
1585   /* ARM template? */
1586   if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1587     {
1588       int len;
1589       *args = *anchor + 6;
1590       len = consume_count (args);
1591       if (*args + len == mangled + n && **args == '_')
1592         {
1593           ++*args;
1594           return 1;
1595         }
1596     }
1597   return 0;
1598 }
1599
1600 static void
1601 demangle_arm_pt (work, mangled, n, declp)
1602      struct work_stuff *work;
1603      const char **mangled;
1604      int n;
1605      string *declp;
1606 {
1607   const char *p;
1608   const char *args;
1609   const char *e = *mangled + n;
1610
1611   /* ARM template? */
1612   if (arm_pt (work, *mangled, n, &p, &args))
1613     {
1614       string arg;
1615       string_init (&arg);
1616       string_appendn (declp, *mangled, p - *mangled);
1617       string_append (declp, "<");
1618       /* should do error checking here */
1619       while (args < e) {
1620         string_clear (&arg);
1621         do_type (work, &args, &arg);
1622         string_appends (declp, &arg);
1623         string_append (declp, ",");
1624       }
1625       string_delete (&arg);
1626       --declp->p;
1627       string_append (declp, ">");
1628     }
1629   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1630            && (*mangled)[9] == 'N'
1631            && (*mangled)[8] == (*mangled)[10]
1632            && strchr (cplus_markers, (*mangled)[8]))
1633     {
1634       /* A member of the anonymous namespace.  */
1635       string_append (declp, "{anonymous}");
1636     }
1637   else
1638     {
1639       string_appendn (declp, *mangled, n);
1640     }
1641   *mangled += n;
1642 }
1643
1644 static int
1645 demangle_class_name (work, mangled, declp)
1646      struct work_stuff *work;
1647      const char **mangled;
1648      string *declp;
1649 {
1650   int n;
1651   int success = 0;
1652
1653   n = consume_count (mangled);
1654   if ((int) strlen (*mangled) >= n)
1655     {
1656       demangle_arm_pt (work, mangled, n, declp);
1657       success = 1;
1658     }
1659
1660   return (success);
1661 }
1662
1663 /*
1664
1665 LOCAL FUNCTION
1666
1667         demangle_class -- demangle a mangled class sequence
1668
1669 SYNOPSIS
1670
1671         static int
1672         demangle_class (struct work_stuff *work, const char **mangled,
1673                         strint *declp)
1674
1675 DESCRIPTION
1676
1677         DECLP points to the buffer into which demangling is being done.
1678
1679         *MANGLED points to the current token to be demangled.  On input,
1680         it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1681         On exit, it points to the next token after the mangled class on
1682         success, or the first unconsumed token on failure.
1683
1684         If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1685         we are demangling a constructor or destructor.  In this case
1686         we prepend "class::class" or "class::~class" to DECLP.
1687
1688         Otherwise, we prepend "class::" to the current DECLP.
1689
1690         Reset the constructor/destructor flags once they have been
1691         "consumed".  This allows demangle_class to be called later during
1692         the same demangling, to do normal class demangling.
1693
1694         Returns 1 if demangling is successful, 0 otherwise.
1695
1696 */
1697
1698 static int
1699 demangle_class (work, mangled, declp)
1700      struct work_stuff *work;
1701      const char **mangled;
1702      string *declp;
1703 {
1704   int success = 0;
1705   int btype;
1706   string class_name;
1707
1708   string_init (&class_name);
1709   btype = register_Btype (work);
1710   if (demangle_class_name (work, mangled, &class_name))
1711     {
1712       if ((work->constructor & 1) || (work->destructor & 1))
1713         {
1714           string_prepends (declp, &class_name);
1715           if (work -> destructor & 1)
1716             {
1717               string_prepend (declp, "~");
1718               work -> destructor -= 1;
1719             }
1720           else
1721             {
1722               work -> constructor -= 1; 
1723             }
1724         }
1725       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1726       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1727       string_prepend (declp, SCOPE_STRING (work));
1728       string_prepends (declp, &class_name);
1729       success = 1;
1730     }
1731   string_delete (&class_name);
1732   return (success);
1733 }
1734
1735 /*
1736
1737 LOCAL FUNCTION
1738
1739         demangle_prefix -- consume the mangled name prefix and find signature
1740
1741 SYNOPSIS
1742
1743         static int
1744         demangle_prefix (struct work_stuff *work, const char **mangled,
1745                          string *declp);
1746
1747 DESCRIPTION
1748
1749         Consume and demangle the prefix of the mangled name.
1750
1751         DECLP points to the string buffer into which demangled output is
1752         placed.  On entry, the buffer is empty.  On exit it contains
1753         the root function name, the demangled operator name, or in some
1754         special cases either nothing or the completely demangled result.
1755
1756         MANGLED points to the current pointer into the mangled name.  As each
1757         token of the mangled name is consumed, it is updated.  Upon entry
1758         the current mangled name pointer points to the first character of
1759         the mangled name.  Upon exit, it should point to the first character
1760         of the signature if demangling was successful, or to the first
1761         unconsumed character if demangling of the prefix was unsuccessful.
1762         
1763         Returns 1 on success, 0 otherwise.
1764  */
1765
1766 static int
1767 demangle_prefix (work, mangled, declp)
1768      struct work_stuff *work;
1769      const char **mangled;
1770      string *declp;
1771 {
1772   int success = 1;
1773   const char *scan;
1774   int i;
1775
1776   if (strlen(*mangled) > 6
1777       && (strncmp(*mangled, "_imp__", 6) == 0 
1778           || strncmp(*mangled, "__imp_", 6) == 0))
1779     {
1780       /* it's a symbol imported from a PE dynamic library. Check for both
1781          new style prefix _imp__ and legacy __imp_ used by older versions
1782          of dlltool. */
1783       (*mangled) += 6;
1784       work->dllimported = 1;
1785     }
1786   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1787     {
1788       char *marker = strchr (cplus_markers, (*mangled)[8]);
1789       if (marker != NULL && *marker == (*mangled)[10])
1790         {
1791           if ((*mangled)[9] == 'D')
1792             {
1793               /* it's a GNU global destructor to be executed at program exit */
1794               (*mangled) += 11;
1795               work->destructor = 2;
1796               if (gnu_special (work, mangled, declp))
1797                 return success;
1798             }
1799           else if ((*mangled)[9] == 'I')
1800             {
1801               /* it's a GNU global constructor to be executed at program init */
1802               (*mangled) += 11;
1803               work->constructor = 2;
1804               if (gnu_special (work, mangled, declp))
1805                 return success;
1806             }
1807         }
1808     }
1809   else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1810     {
1811       /* it's a ARM global destructor to be executed at program exit */
1812       (*mangled) += 7;
1813       work->destructor = 2;
1814     }
1815   else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1816     {
1817       /* it's a ARM global constructor to be executed at program initial */
1818       (*mangled) += 7;
1819       work->constructor = 2;
1820     }
1821
1822   /*  This block of code is a reduction in strength time optimization
1823       of:
1824       scan = mystrstr (*mangled, "__"); */
1825
1826   {
1827     scan = *mangled;
1828
1829     do {
1830       scan = strchr (scan, '_');
1831     } while (scan != NULL && *++scan != '_');
1832
1833     if (scan != NULL) --scan;
1834   }
1835
1836   if (scan != NULL)
1837     {
1838       /* We found a sequence of two or more '_', ensure that we start at
1839          the last pair in the sequence.  */
1840       i = strspn (scan, "_");
1841       if (i > 2)
1842         {
1843           scan += (i - 2); 
1844         }
1845     }
1846  
1847   if (scan == NULL)
1848     {
1849       success = 0;
1850     }
1851   else if (work -> static_type)
1852     {
1853       if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
1854         {
1855           success = 0;
1856         }
1857     }
1858   else if ((scan == *mangled)
1859            && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
1860                || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
1861     {
1862       /* The ARM says nothing about the mangling of local variables.
1863          But cfront mangles local variables by prepending __<nesting_level>
1864          to them. As an extension to ARM demangling we handle this case.  */
1865       if ((LUCID_DEMANGLING || ARM_DEMANGLING)
1866           && isdigit ((unsigned char)scan[2]))
1867         {
1868           *mangled = scan + 2;
1869           consume_count (mangled);
1870           string_append (declp, *mangled);
1871           *mangled += strlen (*mangled);
1872           success = 1; 
1873         }
1874       else
1875         {
1876           /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
1877              names like __Q2_3foo3bar for nested type names.  So don't accept
1878              this style of constructor for cfront demangling.  A GNU
1879              style member-template constructor starts with 'H'. */
1880           if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1881             work -> constructor += 1;
1882           *mangled = scan + 2;
1883         }
1884     }
1885   else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
1886            && (scan[2] != 't'))
1887     {
1888       /* Mangled name starts with "__".  Skip over any leading '_' characters,
1889          then find the next "__" that separates the prefix from the signature.
1890          */
1891       if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1892           || (arm_special (mangled, declp) == 0))
1893         {
1894           while (*scan == '_')
1895             {
1896               scan++;
1897             }
1898           if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1899             {
1900               /* No separator (I.E. "__not_mangled"), or empty signature
1901                  (I.E. "__not_mangled_either__") */
1902               success = 0;
1903             }
1904           else
1905             {
1906               demangle_function_name (work, mangled, declp, scan);
1907             }
1908         }
1909     }
1910   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1911     {
1912       /* Cfront-style parameterized type.  Handled later as a signature.  */
1913       success = 1;
1914
1915       /* ARM template? */
1916       demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1917     }
1918   else if (*(scan + 2) != '\0')
1919     {
1920       /* Mangled name does not start with "__" but does have one somewhere
1921          in there with non empty stuff after it.  Looks like a global
1922          function name.  */
1923       demangle_function_name (work, mangled, declp, scan);
1924     }
1925   else
1926     {
1927       /* Doesn't look like a mangled name */
1928       success = 0;
1929     }
1930
1931   if (!success && (work->constructor == 2 || work->destructor == 2))
1932     {
1933       string_append (declp, *mangled);
1934       *mangled += strlen (*mangled);
1935       success = 1;
1936     } 
1937   return (success);
1938 }
1939
1940 /*
1941
1942 LOCAL FUNCTION
1943
1944         gnu_special -- special handling of gnu mangled strings
1945
1946 SYNOPSIS
1947
1948         static int
1949         gnu_special (struct work_stuff *work, const char **mangled,
1950                      string *declp);
1951
1952
1953 DESCRIPTION
1954
1955         Process some special GNU style mangling forms that don't fit
1956         the normal pattern.  For example:
1957
1958                 _$_3foo         (destructor for class foo)
1959                 _vt$foo         (foo virtual table)
1960                 _vt$foo$bar     (foo::bar virtual table)
1961                 __vt_foo        (foo virtual table, new style with thunks)
1962                 _3foo$varname   (static data member)
1963                 _Q22rs2tu$vw    (static data member)
1964                 __t6vector1Zii  (constructor with template)
1965                 __thunk_4__$_7ostream (virtual function thunk)
1966  */
1967
1968 static int
1969 gnu_special (work, mangled, declp)
1970      struct work_stuff *work;
1971      const char **mangled;
1972      string *declp;
1973 {
1974   int n;
1975   int success = 1;
1976   const char *p;
1977
1978   if ((*mangled)[0] == '_'
1979       && strchr (cplus_markers, (*mangled)[1]) != NULL
1980       && (*mangled)[2] == '_')
1981     {
1982       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1983       (*mangled) += 3;
1984       work -> destructor += 1;
1985     }
1986   else if ((*mangled)[0] == '_'
1987            && (((*mangled)[1] == '_'
1988                 && (*mangled)[2] == 'v'
1989                 && (*mangled)[3] == 't'
1990                 && (*mangled)[4] == '_')
1991                || ((*mangled)[1] == 'v'
1992                    && (*mangled)[2] == 't'
1993                    && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1994     {
1995       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1996          and create the decl.  Note that we consume the entire mangled
1997          input string, which means that demangle_signature has no work
1998          to do.  */
1999       if ((*mangled)[2] == 'v')
2000         (*mangled) += 5; /* New style, with thunks: "__vt_" */
2001       else
2002         (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2003       while (**mangled != '\0')
2004         {
2005           p = strpbrk (*mangled, cplus_markers);
2006           switch (**mangled)
2007             {
2008             case 'Q':
2009             case 'K':
2010               success = demangle_qualified (work, mangled, declp, 0, 1);
2011               break;
2012             case 't':
2013               success = demangle_template (work, mangled, declp, 0, 1,
2014                                            1);
2015               break;
2016             default:
2017               if (isdigit((unsigned char)*mangled[0]))
2018                 {
2019                   n = consume_count(mangled);
2020                   /* We may be seeing a too-large size, or else a
2021                      ".<digits>" indicating a static local symbol.  In
2022                      any case, declare victory and move on; *don't* try
2023                      to use n to allocate.  */
2024                   if (n > (int) strlen (*mangled))
2025                     {
2026                       success = 1;
2027                       break;
2028                     }
2029                 }
2030               else
2031                 {
2032                   n = strcspn (*mangled, cplus_markers);
2033                 }
2034               string_appendn (declp, *mangled, n);
2035               (*mangled) += n;
2036             }
2037
2038           if (success && ((p == NULL) || (p == *mangled)))
2039             {
2040               if (p != NULL)
2041                 {
2042                   string_append (declp, SCOPE_STRING (work));
2043                   (*mangled)++;
2044                 }
2045             }
2046           else
2047             {
2048               success = 0;
2049               break;
2050             }
2051         }
2052       if (success)
2053         string_append (declp, " virtual table");
2054     }
2055   else if ((*mangled)[0] == '_'
2056            && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2057            && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2058     {
2059       /* static data member, "_3foo$varname" for example */
2060       (*mangled)++;
2061       switch (**mangled)
2062         {
2063         case 'Q':
2064         case 'K':
2065           success = demangle_qualified (work, mangled, declp, 0, 1);
2066           break;
2067         case 't':
2068           success = demangle_template (work, mangled, declp, 0, 1, 1);
2069           break;
2070         default:
2071           n = consume_count (mangled);
2072           string_appendn (declp, *mangled, n);
2073           (*mangled) += n;
2074         }
2075       if (success && (p == *mangled))
2076         {
2077           /* Consumed everything up to the cplus_marker, append the
2078              variable name.  */
2079           (*mangled)++;
2080           string_append (declp, SCOPE_STRING (work));
2081           n = strlen (*mangled);
2082           string_appendn (declp, *mangled, n);
2083           (*mangled) += n;
2084         }
2085       else
2086         {
2087           success = 0;
2088         }
2089     }
2090   else if (strncmp (*mangled, "__thunk_", 8) == 0)
2091     {
2092       int delta = ((*mangled) += 8, consume_count (mangled));
2093       char *method = internal_cplus_demangle (work, ++*mangled);
2094       if (method)
2095         {
2096           char buf[50];
2097           sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2098           string_append (declp, buf);
2099           string_append (declp, method);
2100           free (method);
2101           n = strlen (*mangled);
2102           (*mangled) += n;
2103         }
2104       else
2105         {
2106           success = 0;
2107         }
2108     }
2109   else if (strncmp (*mangled, "__t", 3) == 0
2110            && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2111     {
2112       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2113       (*mangled) += 4;
2114       switch (**mangled)
2115         {
2116         case 'Q':
2117         case 'K':
2118           success = demangle_qualified (work, mangled, declp, 0, 1);
2119           break;
2120         case 't':
2121           success = demangle_template (work, mangled, declp, 0, 1, 1);
2122           break;
2123         default:
2124           success = demangle_fund_type (work, mangled, declp);
2125           break;
2126         }
2127       if (success && **mangled != '\0')
2128         success = 0;
2129       if (success)
2130         string_append (declp, p);
2131     }
2132   else
2133     {
2134       success = 0;
2135     }
2136   return (success);
2137 }
2138
2139 /*
2140
2141 LOCAL FUNCTION
2142
2143         arm_special -- special handling of ARM/lucid mangled strings
2144
2145 SYNOPSIS
2146
2147         static int
2148         arm_special (const char **mangled,
2149                      string *declp);
2150
2151
2152 DESCRIPTION
2153
2154         Process some special ARM style mangling forms that don't fit
2155         the normal pattern.  For example:
2156
2157                 __vtbl__3foo            (foo virtual table)
2158                 __vtbl__3foo__3bar      (bar::foo virtual table)
2159
2160  */
2161
2162 static int
2163 arm_special (mangled, declp)
2164      const char **mangled;
2165      string *declp;
2166 {
2167   int n;
2168   int success = 1;
2169   const char *scan;
2170
2171   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2172     {
2173       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2174          and create the decl.  Note that we consume the entire mangled
2175          input string, which means that demangle_signature has no work
2176          to do.  */
2177       scan = *mangled + ARM_VTABLE_STRLEN;
2178       while (*scan != '\0')        /* first check it can be demangled */
2179         {
2180           n = consume_count (&scan);
2181           if (n==0)
2182             {
2183               return (0);           /* no good */
2184             }
2185           scan += n;
2186           if (scan[0] == '_' && scan[1] == '_')
2187             {
2188               scan += 2;
2189             }
2190         }
2191       (*mangled) += ARM_VTABLE_STRLEN;
2192       while (**mangled != '\0')
2193         {
2194           n = consume_count (mangled);
2195           string_prependn (declp, *mangled, n);
2196           (*mangled) += n;
2197           if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2198             {
2199               string_prepend (declp, "::");
2200               (*mangled) += 2;
2201             }
2202         }
2203       string_append (declp, " virtual table");
2204     }
2205   else
2206     {
2207       success = 0;
2208     }
2209   return (success);
2210 }
2211
2212 /*
2213
2214 LOCAL FUNCTION
2215
2216         demangle_qualified -- demangle 'Q' qualified name strings
2217
2218 SYNOPSIS
2219
2220         static int
2221         demangle_qualified (struct work_stuff *, const char *mangled,
2222                             string *result, int isfuncname, int append);
2223
2224 DESCRIPTION
2225
2226         Demangle a qualified name, such as "Q25Outer5Inner" which is
2227         the mangled form of "Outer::Inner".  The demangled output is
2228         prepended or appended to the result string according to the
2229         state of the append flag.
2230
2231         If isfuncname is nonzero, then the qualified name we are building
2232         is going to be used as a member function name, so if it is a
2233         constructor or destructor function, append an appropriate
2234         constructor or destructor name.  I.E. for the above example,
2235         the result for use as a constructor is "Outer::Inner::Inner"
2236         and the result for use as a destructor is "Outer::Inner::~Inner".
2237
2238 BUGS
2239
2240         Numeric conversion is ASCII dependent (FIXME).
2241
2242  */
2243
2244 static int
2245 demangle_qualified (work, mangled, result, isfuncname, append)
2246      struct work_stuff *work;
2247      const char **mangled;
2248      string *result;
2249      int isfuncname;
2250      int append;
2251 {
2252   int qualifiers = 0;
2253   int success = 1;
2254   const char *p;
2255   char num[2];
2256   string temp;
2257   string last_name;
2258   int bindex = register_Btype (work);
2259
2260   /* We only make use of ISFUNCNAME if the entity is a constructor or
2261      destructor.  */
2262   isfuncname = (isfuncname 
2263                 && ((work->constructor & 1) || (work->destructor & 1)));
2264
2265   string_init (&temp);
2266   string_init (&last_name);
2267
2268   if ((*mangled)[0] == 'K')
2269     {
2270     /* Squangling qualified name reuse */
2271       int idx;
2272       (*mangled)++;
2273       idx = consume_count_with_underscores (mangled);
2274       if (idx == -1 || idx >= work -> numk)
2275         success = 0;
2276       else
2277         string_append (&temp, work -> ktypevec[idx]);
2278     }
2279   else
2280     switch ((*mangled)[1])
2281     {
2282     case '_':
2283       /* GNU mangled name with more than 9 classes.  The count is preceded
2284          by an underscore (to distinguish it from the <= 9 case) and followed
2285          by an underscore.  */
2286       p = *mangled + 2;
2287       qualifiers = atoi (p);
2288       if (!isdigit ((unsigned char)*p) || *p == '0')
2289         success = 0;
2290
2291       /* Skip the digits.  */
2292       while (isdigit ((unsigned char)*p))
2293         ++p;
2294
2295       if (*p != '_')
2296         success = 0;
2297
2298       *mangled = p + 1;
2299       break;
2300
2301     case '1':
2302     case '2':
2303     case '3':
2304     case '4':
2305     case '5':
2306     case '6':
2307     case '7':
2308     case '8':
2309     case '9':
2310       /* The count is in a single digit.  */
2311       num[0] = (*mangled)[1];
2312       num[1] = '\0';
2313       qualifiers = atoi (num);
2314
2315       /* If there is an underscore after the digit, skip it.  This is
2316          said to be for ARM-qualified names, but the ARM makes no
2317          mention of such an underscore.  Perhaps cfront uses one.  */
2318       if ((*mangled)[2] == '_')
2319         {
2320           (*mangled)++;
2321         }
2322       (*mangled) += 2;
2323       break;
2324
2325     case '0':
2326     default:
2327       success = 0;
2328     }
2329
2330   if (!success)
2331     return success;
2332
2333   /* Pick off the names and collect them in the temp buffer in the order
2334      in which they are found, separated by '::'.  */
2335
2336   while (qualifiers-- > 0)
2337     {
2338       int remember_K = 1;
2339       string_clear (&last_name);
2340
2341       if (*mangled[0] == '_') 
2342         (*mangled)++;
2343
2344       if (*mangled[0] == 't')
2345         {
2346           /* Here we always append to TEMP since we will want to use
2347              the template name without the template parameters as a
2348              constructor or destructor name.  The appropriate
2349              (parameter-less) value is returned by demangle_template
2350              in LAST_NAME.  We do not remember the template type here,
2351              in order to match the G++ mangling algorithm.  */
2352           success = demangle_template(work, mangled, &temp, 
2353                                       &last_name, 1, 0);
2354           if (!success) 
2355             break;
2356         } 
2357       else if (*mangled[0] == 'K')
2358         {
2359           int idx;
2360           (*mangled)++;
2361           idx = consume_count_with_underscores (mangled);
2362           if (idx == -1 || idx >= work->numk)
2363             success = 0;
2364           else
2365             string_append (&temp, work->ktypevec[idx]);
2366           remember_K = 0;
2367
2368           if (!success) break;
2369         }
2370       else
2371         {
2372           success = do_type (work, mangled, &last_name);
2373           if (!success)
2374             break;
2375           string_appends (&temp, &last_name);
2376         }
2377
2378       if (remember_K)
2379         remember_Ktype (work, temp.b, LEN_STRING (&temp));
2380
2381       if (qualifiers > 0)
2382         string_append (&temp, SCOPE_STRING (work));
2383     }
2384
2385   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2386
2387   /* If we are using the result as a function name, we need to append
2388      the appropriate '::' separated constructor or destructor name.
2389      We do this here because this is the most convenient place, where
2390      we already have a pointer to the name and the length of the name.  */
2391
2392   if (isfuncname) 
2393     {
2394       string_append (&temp, SCOPE_STRING (work));
2395       if (work -> destructor & 1)
2396         string_append (&temp, "~");
2397       string_appends (&temp, &last_name);
2398     }
2399
2400   /* Now either prepend the temp buffer to the result, or append it, 
2401      depending upon the state of the append flag.  */
2402
2403   if (append)
2404     string_appends (result, &temp);
2405   else
2406     {
2407       if (!STRING_EMPTY (result))
2408         string_append (&temp, SCOPE_STRING (work));
2409       string_prepends (result, &temp);
2410     }
2411
2412   string_delete (&last_name);
2413   string_delete (&temp);
2414   return (success);
2415 }
2416
2417 /*
2418
2419 LOCAL FUNCTION
2420
2421         get_count -- convert an ascii count to integer, consuming tokens
2422
2423 SYNOPSIS
2424
2425         static int
2426         get_count (const char **type, int *count)
2427
2428 DESCRIPTION
2429
2430         Return 0 if no conversion is performed, 1 if a string is converted.
2431 */
2432
2433 static int
2434 get_count (type, count)
2435      const char **type;
2436      int *count;
2437 {
2438   const char *p;
2439   int n;
2440
2441   if (!isdigit ((unsigned char)**type))
2442     {
2443       return (0);
2444     }
2445   else
2446     {
2447       *count = **type - '0';
2448       (*type)++;
2449       if (isdigit ((unsigned char)**type))
2450         {
2451           p = *type;
2452           n = *count;
2453           do 
2454             {
2455               n *= 10;
2456               n += *p - '0';
2457               p++;
2458             } 
2459           while (isdigit ((unsigned char)*p));
2460           if (*p == '_')
2461             {
2462               *type = p + 1;
2463               *count = n;
2464             }
2465         }
2466     }
2467   return (1);
2468 }
2469
2470 /* RESULT will be initialised here; it will be freed on failure.  The
2471    value returned is really a type_kind_t.  */
2472
2473 static int
2474 do_type (work, mangled, result)
2475      struct work_stuff *work;
2476      const char **mangled;
2477      string *result;
2478 {
2479   int n;
2480   int done;
2481   int success;
2482   string decl;
2483   const char *remembered_type;
2484   int constp;
2485   int volatilep;
2486   string btype;
2487   type_kind_t tk = tk_none;
2488
2489   string_init (&btype);
2490   string_init (&decl);
2491   string_init (result);
2492
2493   done = 0;
2494   success = 1;
2495   while (success && !done)
2496     {
2497       int member;
2498       switch (**mangled)
2499         {
2500
2501           /* A pointer type */
2502         case 'P':
2503         case 'p':
2504           (*mangled)++;
2505           string_prepend (&decl, "*");
2506           if (tk == tk_none)
2507             tk = tk_pointer;
2508           break;
2509
2510           /* A reference type */
2511         case 'R':
2512           (*mangled)++;
2513           string_prepend (&decl, "&");
2514           if (tk == tk_none)
2515             tk = tk_pointer;
2516           break;
2517
2518           /* An array */
2519         case 'A':
2520           {
2521             ++(*mangled);
2522             if (!STRING_EMPTY (&decl)
2523                 && (decl.b[0] == '*' || decl.b[0] == '&'))
2524               {
2525                 string_prepend (&decl, "(");
2526                 string_append (&decl, ")");
2527               }
2528             string_append (&decl, "[");
2529             if (**mangled != '_')
2530               success = demangle_template_value_parm (work, mangled, &decl,
2531                                                       tk_integral);
2532             if (**mangled == '_')
2533               ++(*mangled);
2534             string_append (&decl, "]");
2535             break;
2536           }
2537
2538         /* A back reference to a previously seen type */
2539         case 'T':
2540           (*mangled)++;
2541           if (!get_count (mangled, &n) || n >= work -> ntypes)
2542             {
2543               success = 0;
2544             }
2545           else
2546             {
2547               remembered_type = work -> typevec[n];
2548               mangled = &remembered_type;
2549             }
2550           break;
2551
2552           /* A function */
2553         case 'F':
2554           (*mangled)++;
2555             if (!STRING_EMPTY (&decl)
2556                 && (decl.b[0] == '*' || decl.b[0] == '&'))
2557             {
2558               string_prepend (&decl, "(");
2559               string_append (&decl, ")");
2560             }
2561           /* After picking off the function args, we expect to either find the
2562              function return type (preceded by an '_') or the end of the
2563              string.  */
2564           if (!demangle_nested_args (work, mangled, &decl)
2565               || (**mangled != '_' && **mangled != '\0'))
2566             {
2567               success = 0;
2568               break;
2569             }
2570           if (success && (**mangled == '_'))
2571             (*mangled)++;
2572           break;
2573
2574         case 'M':
2575         case 'O':
2576           {
2577             constp = 0;
2578             volatilep = 0;
2579
2580             member = **mangled == 'M';
2581             (*mangled)++;
2582             if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2583               {
2584                 success = 0;
2585                 break;
2586               }
2587
2588             string_append (&decl, ")");
2589             string_prepend (&decl, SCOPE_STRING (work));
2590             if (isdigit ((unsigned char)**mangled))
2591               {
2592                 n = consume_count (mangled);
2593                 if ((int) strlen (*mangled) < n)
2594                   {
2595                     success = 0;
2596                     break;
2597                   }
2598                 string_prependn (&decl, *mangled, n);
2599                 *mangled += n;
2600               }
2601             else
2602               {
2603                 string temp;
2604                 string_init (&temp);
2605                 success = demangle_template (work, mangled, &temp,
2606                                              NULL, 1, 1);
2607                 if (success)
2608                   {
2609                     string_prependn (&decl, temp.b, temp.p - temp.b);
2610                     string_clear (&temp);
2611                   }
2612                 else
2613                   break;
2614               }
2615             string_prepend (&decl, "(");
2616             if (member)
2617               {
2618                 if (**mangled == 'C')
2619                   {
2620                     (*mangled)++;
2621                     constp = 1;
2622                   }
2623                 if (**mangled == 'V')
2624                   {
2625                     (*mangled)++;
2626                     volatilep = 1;
2627                   }
2628                 if (*(*mangled)++ != 'F')
2629                   {
2630                     success = 0;
2631                     break;
2632                   }
2633               }
2634             if ((member && !demangle_nested_args (work, mangled, &decl))
2635                 || **mangled != '_')
2636               {
2637                 success = 0;
2638                 break;
2639               }
2640             (*mangled)++;
2641             if (! PRINT_ANSI_QUALIFIERS)
2642               {
2643                 break;
2644               }
2645             if (constp)
2646               {
2647                 APPEND_BLANK (&decl);
2648                 string_append (&decl, "const");
2649               }
2650             if (volatilep)
2651               {
2652                 APPEND_BLANK (&decl);
2653                 string_append (&decl, "volatile");
2654               }
2655             break;
2656           }
2657         case 'G':
2658           (*mangled)++;
2659           break;
2660
2661         case 'C':
2662         case 'V':
2663           /*
2664             if ((*mangled)[1] == 'P')
2665             {
2666             */
2667           if (PRINT_ANSI_QUALIFIERS)
2668             {
2669               if (!STRING_EMPTY (&decl))
2670                 {
2671                   string_prepend (&decl, " ");
2672                 }
2673               string_prepend (&decl, 
2674                               (**mangled) == 'C' ? "const" : "volatile");
2675             }
2676           (*mangled)++;
2677           break;
2678           /*
2679             }
2680             */
2681
2682           /* fall through */
2683         default:
2684           done = 1;
2685           break;
2686         }
2687     }
2688
2689   if (success) switch (**mangled)
2690     {
2691       /* A qualified name, such as "Outer::Inner".  */
2692     case 'Q':
2693     case 'K':
2694       {
2695         success = demangle_qualified (work, mangled, result, 0, 1);
2696         break;
2697       }
2698
2699     /* A back reference to a previously seen squangled type */
2700     case 'B':
2701       (*mangled)++;
2702       if (!get_count (mangled, &n) || n >= work -> numb)
2703         success = 0;
2704       else
2705         string_append (result, work->btypevec[n]);
2706       break;
2707
2708     case 'X':
2709     case 'Y':
2710       /* A template parm.  We substitute the corresponding argument. */
2711       {
2712         int idx;
2713
2714         (*mangled)++;
2715         idx = consume_count_with_underscores (mangled);
2716
2717         if (idx == -1 
2718             || (work->tmpl_argvec && idx >= work->ntmpl_args)
2719             || consume_count_with_underscores (mangled) == -1)
2720           {
2721             success = 0;
2722             break;
2723           }
2724
2725         if (work->tmpl_argvec)
2726           string_append (result, work->tmpl_argvec[idx]);
2727         else
2728           {
2729             char buf[10];
2730             sprintf(buf, "T%d", idx);
2731             string_append (result, buf);
2732           }
2733
2734         success = 1;
2735       }
2736     break;
2737
2738     default:
2739       success = demangle_fund_type (work, mangled, result);
2740       if (tk == tk_none)
2741         tk = (type_kind_t) success;
2742       break;
2743     }
2744
2745   if (success)
2746     {
2747       if (!STRING_EMPTY (&decl))
2748         {
2749           string_append (result, " ");
2750           string_appends (result, &decl);
2751         }
2752     }
2753   else
2754     string_delete (result);
2755   string_delete (&decl);
2756
2757   if (success)
2758     /* Assume an integral type, if we're not sure.  */
2759     return (int) ((tk == tk_none) ? tk_integral : tk);
2760   else
2761     return 0;
2762 }
2763
2764 /* Given a pointer to a type string that represents a fundamental type
2765    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2766    string in which the demangled output is being built in RESULT, and
2767    the WORK structure, decode the types and add them to the result.
2768
2769    For example:
2770
2771         "Ci"    =>      "const int"
2772         "Sl"    =>      "signed long"
2773         "CUs"   =>      "const unsigned short"
2774
2775    The value returned is really a type_kind_t.  */
2776
2777 static int
2778 demangle_fund_type (work, mangled, result)
2779      struct work_stuff *work;
2780      const char **mangled;
2781      string *result;
2782 {
2783   int done = 0;
2784   int success = 1;
2785   string btype;
2786   type_kind_t tk = tk_integral;
2787
2788   string_init (&btype);
2789
2790   /* First pick off any type qualifiers.  There can be more than one.  */
2791
2792   while (!done)
2793     {
2794       switch (**mangled)
2795         {
2796         case 'C':
2797           (*mangled)++;
2798           if (PRINT_ANSI_QUALIFIERS)
2799             {
2800               APPEND_BLANK (result);
2801               string_append (result, "const");
2802             }
2803           break;
2804         case 'U':
2805           (*mangled)++;
2806           APPEND_BLANK (result);
2807           string_append (result, "unsigned");
2808           break;
2809         case 'S': /* signed char only */
2810           (*mangled)++;
2811           APPEND_BLANK (result);
2812           string_append (result, "signed");
2813           break;
2814         case 'V':
2815           (*mangled)++;
2816           if (PRINT_ANSI_QUALIFIERS)
2817             {
2818               APPEND_BLANK (result);
2819               string_append (result, "volatile");
2820             }
2821           break;
2822         case 'J':
2823           (*mangled)++;
2824           APPEND_BLANK (result);
2825           string_append (result, "__complex");
2826           break;
2827         default:
2828           done = 1;
2829           break;
2830         }
2831     }
2832
2833   /* Now pick off the fundamental type.  There can be only one.  */
2834
2835   switch (**mangled)
2836     {
2837     case '\0':
2838     case '_':
2839       break;
2840     case 'v':
2841       (*mangled)++;
2842       APPEND_BLANK (result);
2843       string_append (result, "void");
2844       break;
2845     case 'x':
2846       (*mangled)++;
2847       APPEND_BLANK (result);
2848       string_append (result, "long long");
2849       break;
2850     case 'l':
2851       (*mangled)++;
2852       APPEND_BLANK (result);
2853       string_append (result, "long");
2854       break;
2855     case 'i':
2856       (*mangled)++;
2857       APPEND_BLANK (result);
2858       string_append (result, "int");
2859       break;
2860     case 's':
2861       (*mangled)++;
2862       APPEND_BLANK (result);
2863       string_append (result, "short");
2864       break;
2865     case 'b':
2866       (*mangled)++;
2867       APPEND_BLANK (result);
2868       string_append (result, "bool");
2869       tk = tk_bool;
2870       break;
2871     case 'c':
2872       (*mangled)++;
2873       APPEND_BLANK (result);
2874       string_append (result, "char");
2875       tk = tk_char;
2876       break;
2877     case 'w':
2878       (*mangled)++;
2879       APPEND_BLANK (result);
2880       string_append (result, "wchar_t");
2881       tk = tk_char;
2882       break;
2883     case 'r':
2884       (*mangled)++;
2885       APPEND_BLANK (result);
2886       string_append (result, "long double");
2887       tk = tk_real;
2888       break;
2889     case 'd':
2890       (*mangled)++;
2891       APPEND_BLANK (result);
2892       string_append (result, "double");
2893       tk = tk_real;
2894       break;
2895     case 'f':
2896       (*mangled)++;
2897       APPEND_BLANK (result);
2898       string_append (result, "float");
2899       tk = tk_real;
2900       break;
2901     case 'G':
2902       (*mangled)++;
2903       if (!isdigit ((unsigned char)**mangled))
2904         {
2905           success = 0;
2906           break;
2907         }
2908       /* fall through */
2909       /* An explicit type, such as "6mytype" or "7integer" */
2910     case '0':
2911     case '1':
2912     case '2':
2913     case '3':
2914     case '4':
2915     case '5':
2916     case '6':
2917     case '7':
2918     case '8':
2919     case '9':
2920       {
2921         int bindex = register_Btype (work);
2922         string btype;
2923         string_init (&btype);
2924         if (demangle_class_name (work, mangled, &btype)) {
2925           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2926           APPEND_BLANK (result);
2927           string_appends (result, &btype);
2928         }
2929         else 
2930           success = 0;
2931         string_delete (&btype);
2932         break;
2933       }
2934     case 't':
2935       {
2936         success = demangle_template (work, mangled, &btype, 0, 1, 1);
2937         string_appends (result, &btype);
2938         break;
2939       }
2940     default:
2941       success = 0;
2942       break;
2943     }
2944
2945   return success ? ((int) tk) : 0;
2946 }
2947
2948 /* Demangle the next argument, given by MANGLED into RESULT, which
2949    *should be an uninitialized* string.  It will be initialized here,
2950    and free'd should anything go wrong.  */
2951
2952 static int
2953 do_arg (work, mangled, result)
2954      struct work_stuff *work;
2955      const char **mangled;
2956      string *result;
2957 {
2958   /* Remember where we started so that we can record the type, for
2959      non-squangling type remembering.  */
2960   const char *start = *mangled;
2961
2962   string_init (result);
2963
2964   if (work->nrepeats > 0)
2965     {
2966       --work->nrepeats;
2967
2968       if (work->previous_argument == 0)
2969         return 0;
2970
2971       /* We want to reissue the previous type in this argument list.  */ 
2972       string_appends (result, work->previous_argument);
2973       return 1;
2974     }
2975
2976   if (**mangled == 'n')
2977     {
2978       /* A squangling-style repeat.  */
2979       (*mangled)++;
2980       work->nrepeats = consume_count(mangled);
2981
2982       if (work->nrepeats == 0)
2983         /* This was not a repeat count after all.  */
2984         return 0;
2985
2986       if (work->nrepeats > 9)
2987         {
2988           if (**mangled != '_')
2989             /* The repeat count should be followed by an '_' in this
2990                case.  */
2991             return 0;
2992           else
2993             (*mangled)++;
2994         }
2995       
2996       /* Now, the repeat is all set up.  */
2997       return do_arg (work, mangled, result);
2998     }
2999
3000   /* Save the result in WORK->previous_argument so that we can find it
3001      if it's repeated.  Note that saving START is not good enough: we
3002      do not want to add additional types to the back-referenceable
3003      type vector when processing a repeated type.  */
3004   if (work->previous_argument)
3005     string_clear (work->previous_argument);
3006   else
3007     {
3008       work->previous_argument = (string*) xmalloc (sizeof (string));
3009       string_init (work->previous_argument);
3010     }
3011
3012   if (!do_type (work, mangled, work->previous_argument))
3013     return 0;
3014
3015   string_appends (result, work->previous_argument);
3016
3017   remember_type (work, start, *mangled - start);
3018   return 1;
3019 }
3020
3021 static void
3022 remember_type (work, start, len)
3023      struct work_stuff *work;
3024      const char *start;
3025      int len;
3026 {
3027   char *tem;
3028
3029   if (work->forgetting_types)
3030     return;
3031
3032   if (work -> ntypes >= work -> typevec_size)
3033     {
3034       if (work -> typevec_size == 0)
3035         {
3036           work -> typevec_size = 3;
3037           work -> typevec
3038             = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3039         }
3040       else
3041         {
3042           work -> typevec_size *= 2;
3043           work -> typevec
3044             = (char **) xrealloc ((char *)work -> typevec,
3045                                   sizeof (char *) * work -> typevec_size);
3046         }
3047     }
3048   tem = xmalloc (len + 1);
3049   memcpy (tem, start, len);
3050   tem[len] = '\0';
3051   work -> typevec[work -> ntypes++] = tem;
3052 }
3053
3054
3055 /* Remember a K type class qualifier. */
3056 static void
3057 remember_Ktype (work, start, len)
3058      struct work_stuff *work;
3059      const char *start;
3060      int len;
3061 {
3062   char *tem;
3063
3064   if (work -> numk >= work -> ksize)
3065     {
3066       if (work -> ksize == 0)
3067         {
3068           work -> ksize = 5;
3069           work -> ktypevec
3070             = (char **) xmalloc (sizeof (char *) * work -> ksize);
3071         }
3072       else
3073         {
3074           work -> ksize *= 2;
3075           work -> ktypevec
3076             = (char **) xrealloc ((char *)work -> ktypevec,
3077                                   sizeof (char *) * work -> ksize);
3078         }
3079     }
3080   tem = xmalloc (len + 1);
3081   memcpy (tem, start, len);
3082   tem[len] = '\0';
3083   work -> ktypevec[work -> numk++] = tem;
3084 }
3085
3086 /* Register a B code, and get an index for it. B codes are registered
3087    as they are seen, rather than as they are completed, so map<temp<char> >  
3088    registers map<temp<char> > as B0, and temp<char> as B1 */
3089
3090 static int
3091 register_Btype (work)
3092      struct work_stuff *work;
3093 {
3094   int ret;
3095  
3096   if (work -> numb >= work -> bsize)
3097     {
3098       if (work -> bsize == 0)
3099         {
3100           work -> bsize = 5;
3101           work -> btypevec
3102             = (char **) xmalloc (sizeof (char *) * work -> bsize);
3103         }
3104       else
3105         {
3106           work -> bsize *= 2;
3107           work -> btypevec
3108             = (char **) xrealloc ((char *)work -> btypevec,
3109                                   sizeof (char *) * work -> bsize);
3110         }
3111     }
3112   ret = work -> numb++;
3113   work -> btypevec[ret] = NULL;
3114   return(ret);
3115 }
3116
3117 /* Store a value into a previously registered B code type. */
3118
3119 static void
3120 remember_Btype (work, start, len, index)
3121      struct work_stuff *work;
3122      const char *start;
3123      int len, index;
3124 {
3125   char *tem;
3126
3127   tem = xmalloc (len + 1);
3128   memcpy (tem, start, len);
3129   tem[len] = '\0';
3130   work -> btypevec[index] = tem;
3131 }
3132
3133 /* Lose all the info related to B and K type codes. */
3134 static void
3135 forget_B_and_K_types (work)
3136      struct work_stuff *work;
3137 {
3138   int i;
3139
3140   while (work -> numk > 0)
3141     {
3142       i = --(work -> numk);
3143       if (work -> ktypevec[i] != NULL)
3144         {
3145           free (work -> ktypevec[i]);
3146           work -> ktypevec[i] = NULL;
3147         }
3148     }
3149
3150   while (work -> numb > 0)
3151     {
3152       i = --(work -> numb);
3153       if (work -> btypevec[i] != NULL)
3154         {
3155           free (work -> btypevec[i]);
3156           work -> btypevec[i] = NULL;
3157         }
3158     }
3159 }
3160 /* Forget the remembered types, but not the type vector itself.  */
3161
3162 static void
3163 forget_types (work)
3164      struct work_stuff *work;
3165 {
3166   int i;
3167
3168   while (work -> ntypes > 0)
3169     {
3170       i = --(work -> ntypes);
3171       if (work -> typevec[i] != NULL)
3172         {
3173           free (work -> typevec[i]);
3174           work -> typevec[i] = NULL;
3175         }
3176     }
3177 }
3178
3179 /* Process the argument list part of the signature, after any class spec
3180    has been consumed, as well as the first 'F' character (if any).  For
3181    example:
3182
3183    "__als__3fooRT0"             =>      process "RT0"
3184    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
3185
3186    DECLP must be already initialised, usually non-empty.  It won't be freed
3187    on failure.
3188
3189    Note that g++ differs significantly from ARM and lucid style mangling
3190    with regards to references to previously seen types.  For example, given
3191    the source fragment:
3192
3193      class foo {
3194        public:
3195        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3196      };
3197
3198      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3199      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3200
3201    g++ produces the names:
3202
3203      __3fooiRT0iT2iT2
3204      foo__FiR3fooiT1iT1
3205
3206    while lcc (and presumably other ARM style compilers as well) produces:
3207
3208      foo__FiR3fooT1T2T1T2
3209      __ct__3fooFiR3fooT1T2T1T2
3210
3211    Note that g++ bases its type numbers starting at zero and counts all
3212    previously seen types, while lucid/ARM bases its type numbers starting
3213    at one and only considers types after it has seen the 'F' character
3214    indicating the start of the function args.  For lucid/ARM style, we
3215    account for this difference by discarding any previously seen types when
3216    we see the 'F' character, and subtracting one from the type number
3217    reference.
3218
3219  */
3220
3221 static int
3222 demangle_args (work, mangled, declp)
3223      struct work_stuff *work;
3224      const char **mangled;
3225      string *declp;
3226 {
3227   string arg;
3228   int need_comma = 0;
3229   int r;
3230   int t;
3231   const char *tem;
3232   char temptype;
3233
3234   if (PRINT_ARG_TYPES)
3235     {
3236       string_append (declp, "(");
3237       if (**mangled == '\0')
3238         {
3239           string_append (declp, "void");
3240         }
3241     }
3242
3243   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3244          || work->nrepeats > 0)
3245     {
3246       if ((**mangled == 'N') || (**mangled == 'T'))
3247         {
3248           temptype = *(*mangled)++;
3249           
3250           if (temptype == 'N')
3251             {
3252               if (!get_count (mangled, &r))
3253                 {
3254                   return (0);
3255                 }
3256             }
3257           else
3258             {
3259               r = 1;
3260             }
3261           if (ARM_DEMANGLING && work -> ntypes >= 10)
3262             {
3263               /* If we have 10 or more types we might have more than a 1 digit
3264                  index so we'll have to consume the whole count here. This
3265                  will lose if the next thing is a type name preceded by a
3266                  count but it's impossible to demangle that case properly
3267                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3268                  Pc, ...)"  or "(..., type12, char *, ...)" */
3269               if ((t = consume_count(mangled)) == 0)
3270                 {
3271                   return (0);
3272                 }
3273             }
3274           else
3275             {
3276               if (!get_count (mangled, &t))
3277                 {
3278                   return (0);
3279                 }
3280             }
3281           if (LUCID_DEMANGLING || ARM_DEMANGLING)
3282             {
3283               t--;
3284             }
3285           /* Validate the type index.  Protect against illegal indices from
3286              malformed type strings.  */
3287           if ((t < 0) || (t >= work -> ntypes))
3288             {
3289               return (0);
3290             }
3291           while (work->nrepeats > 0 || --r >= 0)
3292             {
3293               tem = work -> typevec[t];
3294               if (need_comma && PRINT_ARG_TYPES)
3295                 {
3296                   string_append (declp, ", ");
3297                 }
3298               if (!do_arg (work, &tem, &arg))
3299                 {
3300                   return (0);
3301                 }
3302               if (PRINT_ARG_TYPES)
3303                 {
3304                   string_appends (declp, &arg);
3305                 }
3306               string_delete (&arg);
3307               need_comma = 1;
3308             }
3309         }
3310       else
3311         {
3312           if (need_comma && PRINT_ARG_TYPES)
3313             string_append (declp, ", ");
3314           if (!do_arg (work, mangled, &arg))
3315             return (0);
3316           if (PRINT_ARG_TYPES)
3317             string_appends (declp, &arg);
3318           string_delete (&arg);
3319           need_comma = 1;
3320         }
3321     }
3322
3323   if (**mangled == 'e')
3324     {
3325       (*mangled)++;
3326       if (PRINT_ARG_TYPES)
3327         {
3328           if (need_comma)
3329             {
3330               string_append (declp, ",");
3331             }
3332           string_append (declp, "...");
3333         }
3334     }
3335
3336   if (PRINT_ARG_TYPES)
3337     {
3338       string_append (declp, ")");
3339     }
3340   return (1);
3341 }
3342
3343 /* Like demangle_args, but for demangling the argument lists of function
3344    and method pointers or references, not top-level declarations.  */
3345
3346 static int
3347 demangle_nested_args (work, mangled, declp)
3348      struct work_stuff *work;
3349      const char **mangled;
3350      string *declp;
3351 {
3352   string* saved_previous_argument;
3353   int result;
3354   int saved_nrepeats;
3355
3356   /* The G++ name-mangling algorithm does not remember types on nested
3357      argument lists, unless -fsquangling is used, and in that case the
3358      type vector updated by remember_type is not used.  So, we turn
3359      off remembering of types here.  */
3360   ++work->forgetting_types;
3361
3362   /* For the repeat codes used with -fsquangling, we must keep track of
3363      the last argument.  */
3364   saved_previous_argument = work->previous_argument;
3365   saved_nrepeats = work->nrepeats;
3366   work->previous_argument = 0;
3367   work->nrepeats = 0;
3368
3369   /* Actually demangle the arguments.  */
3370   result = demangle_args (work, mangled, declp);
3371   
3372   /* Restore the previous_argument field.  */
3373   if (work->previous_argument)
3374     string_delete (work->previous_argument);
3375   work->previous_argument = saved_previous_argument;
3376   work->nrepeats = saved_nrepeats;
3377
3378   return result;
3379 }
3380
3381 static void
3382 demangle_function_name (work, mangled, declp, scan)
3383      struct work_stuff *work;
3384      const char **mangled;
3385      string *declp;
3386      const char *scan;
3387 {
3388   size_t i;
3389   string type;
3390   const char *tem;
3391
3392   string_appendn (declp, (*mangled), scan - (*mangled));
3393   string_need (declp, 1);
3394   *(declp -> p) = '\0';
3395
3396   /* Consume the function name, including the "__" separating the name
3397      from the signature.  We are guaranteed that SCAN points to the
3398      separator.  */
3399
3400   (*mangled) = scan + 2;
3401
3402   if (LUCID_DEMANGLING || ARM_DEMANGLING)
3403     {
3404
3405       /* See if we have an ARM style constructor or destructor operator.
3406          If so, then just record it, clear the decl, and return.
3407          We can't build the actual constructor/destructor decl until later,
3408          when we recover the class name from the signature.  */
3409
3410       if (strcmp (declp -> b, "__ct") == 0)
3411         {
3412           work -> constructor += 1;
3413           string_clear (declp);
3414           return;
3415         }
3416       else if (strcmp (declp -> b, "__dt") == 0)
3417         {
3418           work -> destructor += 1;
3419           string_clear (declp);
3420           return;
3421         }
3422     }
3423
3424   if (declp->p - declp->b >= 3 
3425       && declp->b[0] == 'o'
3426       && declp->b[1] == 'p'
3427       && strchr (cplus_markers, declp->b[2]) != NULL)
3428     {
3429       /* see if it's an assignment expression */
3430       if (declp->p - declp->b >= 10 /* op$assign_ */
3431           && memcmp (declp->b + 3, "assign_", 7) == 0)
3432         {
3433           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3434             {
3435               int len = declp->p - declp->b - 10;
3436               if ((int) strlen (optable[i].in) == len
3437                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
3438                 {
3439                   string_clear (declp);
3440                   string_append (declp, "operator");
3441                   string_append (declp, optable[i].out);
3442                   string_append (declp, "=");
3443                   break;
3444                 }
3445             }
3446         }
3447       else
3448         {
3449           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3450             {
3451               int len = declp->p - declp->b - 3;
3452               if ((int) strlen (optable[i].in) == len 
3453                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
3454                 {
3455                   string_clear (declp);
3456                   string_append (declp, "operator");
3457                   string_append (declp, optable[i].out);
3458                   break;
3459                 }
3460             }
3461         }
3462     }
3463   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3464            && strchr (cplus_markers, declp->b[4]) != NULL)
3465     {
3466       /* type conversion operator */
3467       tem = declp->b + 5;
3468       if (do_type (work, &tem, &type))
3469         {
3470           string_clear (declp);
3471           string_append (declp, "operator ");
3472           string_appends (declp, &type);
3473           string_delete (&type);
3474         }
3475     }
3476   else if (declp->b[0] == '_' && declp->b[1] == '_'
3477            && declp->b[2] == 'o' && declp->b[3] == 'p')
3478     {
3479       /* ANSI.  */
3480       /* type conversion operator.  */
3481       tem = declp->b + 4;
3482       if (do_type (work, &tem, &type))
3483         {
3484           string_clear (declp);
3485           string_append (declp, "operator ");
3486           string_appends (declp, &type);
3487           string_delete (&type);
3488         }
3489     }
3490   else if (declp->b[0] == '_' && declp->b[1] == '_'
3491            && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3492            && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3493     {
3494       if (declp->b[4] == '\0')
3495         {
3496           /* Operator.  */
3497           for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3498             {
3499               if (strlen (optable[i].in) == 2
3500                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3501                 {
3502                   string_clear (declp);
3503                   string_append (declp, "operator");
3504                   string_append (declp, optable[i].out);
3505                   break;
3506                 }
3507             }
3508         }
3509       else
3510         {
3511           if (declp->b[2] == 'a' && declp->b[5] == '\0')
3512             {
3513               /* Assignment.  */
3514               for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3515                 {
3516                   if (strlen (optable[i].in) == 3
3517                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3518                     {
3519                       string_clear (declp);
3520                       string_append (declp, "operator");
3521                       string_append (declp, optable[i].out);
3522                       break;
3523                     }                 
3524                 }
3525             }
3526         }
3527     }
3528 }
3529
3530 /* a mini string-handling package */
3531
3532 static void
3533 string_need (s, n)
3534      string *s;
3535      int n;
3536 {
3537   int tem;
3538
3539   if (s->b == NULL)
3540     {
3541       if (n < 32)
3542         {
3543           n = 32;
3544         }
3545       s->p = s->b = xmalloc (n);
3546       s->e = s->b + n;
3547     }
3548   else if (s->e - s->p < n)
3549     {
3550       tem = s->p - s->b;
3551       n += tem;
3552       n *= 2;
3553       s->b = xrealloc (s->b, n);
3554       s->p = s->b + tem;
3555       s->e = s->b + n;
3556     }
3557 }
3558
3559 static void
3560 string_delete (s)
3561      string *s;
3562 {
3563   if (s->b != NULL)
3564     {
3565       free (s->b);
3566       s->b = s->e = s->p = NULL;
3567     }
3568 }
3569
3570 static void
3571 string_init (s)
3572      string *s;
3573 {
3574   s->b = s->p = s->e = NULL;
3575 }
3576
3577 static void 
3578 string_clear (s)
3579      string *s;
3580 {
3581   s->p = s->b;
3582 }
3583
3584 #if 0
3585
3586 static int
3587 string_empty (s)
3588      string *s;
3589 {
3590   return (s->b == s->p);
3591 }
3592
3593 #endif
3594
3595 static void
3596 string_append (p, s)
3597      string *p;
3598      const char *s;
3599 {
3600   int n;
3601   if (s == NULL || *s == '\0')
3602     return;
3603   n = strlen (s);
3604   string_need (p, n);
3605   memcpy (p->p, s, n);
3606   p->p += n;
3607 }
3608
3609 static void
3610 string_appends (p, s)
3611      string *p, *s;
3612 {
3613   int n;
3614
3615   if (s->b != s->p)
3616     {
3617       n = s->p - s->b;
3618       string_need (p, n);
3619       memcpy (p->p, s->b, n);
3620       p->p += n;
3621     }
3622 }
3623
3624 static void
3625 string_appendn (p, s, n)
3626      string *p;
3627      const char *s;
3628      int n;
3629 {
3630   if (n != 0)
3631     {
3632       string_need (p, n);
3633       memcpy (p->p, s, n);
3634       p->p += n;
3635     }
3636 }
3637
3638 static void
3639 string_prepend (p, s)
3640      string *p;
3641      const char *s;
3642 {
3643   if (s != NULL && *s != '\0')
3644     {
3645       string_prependn (p, s, strlen (s));
3646     }
3647 }
3648
3649 static void
3650 string_prepends (p, s)
3651      string *p, *s;
3652 {
3653   if (s->b != s->p)
3654     {
3655       string_prependn (p, s->b, s->p - s->b);
3656     }
3657 }
3658
3659 static void
3660 string_prependn (p, s, n)
3661      string *p;
3662      const char *s;
3663      int n;
3664 {
3665   char *q;
3666
3667   if (n != 0)
3668     {
3669       string_need (p, n);
3670       for (q = p->p - 1; q >= p->b; q--)
3671         {
3672           q[n] = q[0];
3673         }
3674       memcpy (p->b, s, n);
3675       p->p += n;
3676     }
3677 }
3678
3679 /* To generate a standalone demangler program for testing purposes,
3680    just compile and link this file with -DMAIN and libiberty.a.  When
3681    run, it demangles each command line arg, or each stdin string, and
3682    prints the result on stdout.  */
3683
3684 #ifdef MAIN
3685
3686 #include "getopt.h"
3687
3688 static char *program_name;
3689 static char *program_version = VERSION;
3690 static int flags = DMGL_PARAMS | DMGL_ANSI;
3691
3692 static void demangle_it PARAMS ((char *));
3693 static void usage PARAMS ((FILE *, int));
3694 static void fatal PARAMS ((char *));
3695
3696 static void
3697 demangle_it (mangled_name)
3698      char *mangled_name;
3699 {
3700   char *result;
3701
3702   result = cplus_demangle (mangled_name, flags);
3703   if (result == NULL)
3704     {
3705       printf ("%s\n", mangled_name);
3706     }
3707   else
3708     {
3709       printf ("%s\n", result);
3710       free (result);
3711     }
3712 }
3713
3714 static void
3715 usage (stream, status)
3716      FILE *stream;
3717      int status;
3718 {    
3719   fprintf (stream, "\
3720 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3721       [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3722       [--help] [--version] [arg...]\n",
3723            program_name);
3724   exit (status);
3725 }
3726
3727 #define MBUF_SIZE 32767
3728 char mbuffer[MBUF_SIZE];
3729
3730 /* Defined in the automatically-generated underscore.c.  */
3731 extern int prepends_underscore;
3732
3733 int strip_underscore = 0;
3734
3735 static struct option long_options[] = {
3736   {"strip-underscores", no_argument, 0, '_'},
3737   {"format", required_argument, 0, 's'},
3738   {"help", no_argument, 0, 'h'},
3739   {"no-strip-underscores", no_argument, 0, 'n'},
3740   {"version", no_argument, 0, 'v'},
3741   {0, no_argument, 0, 0}
3742 };
3743
3744 /* More 'friendly' abort that prints the line and file.
3745    config.h can #define abort fancy_abort if you like that sort of thing.  */
3746
3747 void
3748 fancy_abort ()
3749 {
3750   fatal ("Internal gcc abort.");
3751 }
3752
3753 int
3754 main (argc, argv)
3755      int argc;
3756      char **argv;
3757 {
3758   char *result;
3759   int c;
3760
3761   program_name = argv[0];
3762
3763   strip_underscore = prepends_underscore;
3764
3765   while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3766     {
3767       switch (c)
3768         {
3769         case '?':
3770           usage (stderr, 1);
3771           break;
3772         case 'h':
3773           usage (stdout, 0);
3774         case 'n':
3775           strip_underscore = 0;
3776           break;
3777         case 'v':
3778           printf ("GNU %s version %s\n", program_name, program_version);
3779           exit (0);
3780         case '_':
3781           strip_underscore = 1;
3782           break;
3783         case 's':
3784           if (strcmp (optarg, "gnu") == 0)
3785             {
3786               current_demangling_style = gnu_demangling;
3787             }
3788           else if (strcmp (optarg, "lucid") == 0)
3789             {
3790               current_demangling_style = lucid_demangling;
3791             }
3792           else if (strcmp (optarg, "arm") == 0)
3793             {
3794               current_demangling_style = arm_demangling;
3795             }
3796           else
3797             {
3798               fprintf (stderr, "%s: unknown demangling style `%s'\n",
3799                        program_name, optarg);
3800               exit (1);
3801             }
3802           break;
3803         }
3804     }
3805
3806   if (optind < argc)
3807     {
3808       for ( ; optind < argc; optind++)
3809         {
3810           demangle_it (argv[optind]);
3811         }
3812     }
3813   else
3814     {
3815       for (;;)
3816         {
3817           int i = 0;
3818           c = getchar ();
3819           /* Try to read a label.  */
3820           while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3821             {
3822               if (i >= MBUF_SIZE-1)
3823                 break;
3824               mbuffer[i++] = c;
3825               c = getchar ();
3826             }
3827           if (i > 0)
3828             {
3829               int skip_first = 0;
3830
3831               if (mbuffer[0] == '.')
3832                 ++skip_first;
3833               if (strip_underscore && mbuffer[skip_first] == '_')
3834                 ++skip_first;
3835
3836               if (skip_first > i)
3837                 skip_first = i;
3838
3839               mbuffer[i] = 0;
3840               
3841               result = cplus_demangle (mbuffer + skip_first, flags);
3842               if (result)
3843                 {
3844                   if (mbuffer[0] == '.')
3845                     putc ('.', stdout);
3846                   fputs (result, stdout);
3847                   free (result);
3848                 }
3849               else
3850                 fputs (mbuffer, stdout);
3851
3852               fflush (stdout);
3853             }
3854           if (c == EOF)
3855             break;
3856           putchar (c);
3857         }
3858     }
3859
3860   exit (0);
3861 }
3862
3863 static void
3864 fatal (str)
3865      char *str;
3866 {
3867   fprintf (stderr, "%s: %s\n", program_name, str);
3868   exit (1);
3869 }
3870
3871 char *
3872 xmalloc (size)
3873      unsigned size;
3874 {
3875   register char *value = (char *) malloc (size);
3876   if (value == 0)
3877     fatal ("virtual memory exhausted");
3878   return value;
3879 }
3880
3881 char *
3882 xrealloc (ptr, size)
3883      char *ptr;
3884      unsigned size;
3885 {
3886   register char *value = (char *) realloc (ptr, size);
3887   if (value == 0)
3888     fatal ("virtual memory exhausted");
3889   return value;
3890 }
3891 #endif  /* main */