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