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