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