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