OSDN Git Service

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