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