OSDN Git Service

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