OSDN Git Service

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