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