OSDN Git Service

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