cplus-dem.c revision ad4e979f408239dabbaae955d8ffcb84a51a5c85
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	  if (!success)
1196	    {
1197	      delete_work_stuff (work);
1198	      string_delete (&decl);
1199	    }
1200	}
1201      if (!success)
1202	{
1203	  success = demangle_prefix (work, &mangled, &decl);
1204	}
1205      if (success && (*mangled != '\0'))
1206	{
1207	  success = demangle_signature (work, &mangled, &decl);
1208	}
1209      if (work->constructor == 2)
1210        {
1211          string_prepend (&decl, "global constructors keyed to ");
1212          work->constructor = 0;
1213        }
1214      else if (work->destructor == 2)
1215        {
1216          string_prepend (&decl, "global destructors keyed to ");
1217          work->destructor = 0;
1218        }
1219      else if (work->dllimported == 1)
1220        {
1221          string_prepend (&decl, "import stub for ");
1222          work->dllimported = 0;
1223        }
1224      demangled = mop_up (work, &decl, success);
1225    }
1226  work->constructor = s1;
1227  work->destructor = s2;
1228  work->static_type = s3;
1229  work->type_quals = s4;
1230  return demangled;
1231}
1232
1233
1234/* Clear out and squangling related storage */
1235static void
1236squangle_mop_up (struct work_stuff *work)
1237{
1238  /* clean up the B and K type mangling types. */
1239  forget_B_and_K_types (work);
1240  if (work -> btypevec != NULL)
1241    {
1242      free ((char *) work -> btypevec);
1243      work->btypevec = NULL;
1244    }
1245  if (work -> ktypevec != NULL)
1246    {
1247      free ((char *) work -> ktypevec);
1248      work->ktypevec = NULL;
1249    }
1250}
1251
1252
1253/* Copy the work state and storage.  */
1254
1255static void
1256work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
1257{
1258  int i;
1259
1260  delete_work_stuff (to);
1261
1262  /* Shallow-copy scalars.  */
1263  memcpy (to, from, sizeof (*to));
1264
1265  /* Deep-copy dynamic storage.  */
1266  if (from->typevec_size)
1267    to->typevec = XNEWVEC (char *, from->typevec_size);
1268
1269  for (i = 0; i < from->ntypes; i++)
1270    {
1271      int len = strlen (from->typevec[i]) + 1;
1272
1273      to->typevec[i] = XNEWVEC (char, len);
1274      memcpy (to->typevec[i], from->typevec[i], len);
1275    }
1276
1277  if (from->ksize)
1278    to->ktypevec = XNEWVEC (char *, from->ksize);
1279
1280  for (i = 0; i < from->numk; i++)
1281    {
1282      int len = strlen (from->ktypevec[i]) + 1;
1283
1284      to->ktypevec[i] = XNEWVEC (char, len);
1285      memcpy (to->ktypevec[i], from->ktypevec[i], len);
1286    }
1287
1288  if (from->bsize)
1289    to->btypevec = XNEWVEC (char *, from->bsize);
1290
1291  for (i = 0; i < from->numb; i++)
1292    {
1293      int len = strlen (from->btypevec[i]) + 1;
1294
1295      to->btypevec[i] = XNEWVEC (char , len);
1296      memcpy (to->btypevec[i], from->btypevec[i], len);
1297    }
1298
1299  if (from->ntmpl_args)
1300    to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
1301
1302  for (i = 0; i < from->ntmpl_args; i++)
1303    {
1304      int len = strlen (from->tmpl_argvec[i]) + 1;
1305
1306      to->tmpl_argvec[i] = XNEWVEC (char, len);
1307      memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1308    }
1309
1310  if (from->previous_argument)
1311    {
1312      to->previous_argument = XNEW (string);
1313      string_init (to->previous_argument);
1314      string_appends (to->previous_argument, from->previous_argument);
1315    }
1316}
1317
1318
1319/* Delete dynamic stuff in work_stuff that is not to be re-used.  */
1320
1321static void
1322delete_non_B_K_work_stuff (struct work_stuff *work)
1323{
1324  /* Discard the remembered types, if any.  */
1325
1326  forget_types (work);
1327  if (work -> typevec != NULL)
1328    {
1329      free ((char *) work -> typevec);
1330      work -> typevec = NULL;
1331      work -> typevec_size = 0;
1332    }
1333  if (work->tmpl_argvec)
1334    {
1335      int i;
1336
1337      for (i = 0; i < work->ntmpl_args; i++)
1338	free ((char*) work->tmpl_argvec[i]);
1339
1340      free ((char*) work->tmpl_argvec);
1341      work->tmpl_argvec = NULL;
1342    }
1343  if (work->previous_argument)
1344    {
1345      string_delete (work->previous_argument);
1346      free ((char*) work->previous_argument);
1347      work->previous_argument = NULL;
1348    }
1349}
1350
1351
1352/* Delete all dynamic storage in work_stuff.  */
1353static void
1354delete_work_stuff (struct work_stuff *work)
1355{
1356  delete_non_B_K_work_stuff (work);
1357  squangle_mop_up (work);
1358}
1359
1360
1361/* Clear out any mangled storage */
1362
1363static char *
1364mop_up (struct work_stuff *work, string *declp, int success)
1365{
1366  char *demangled = NULL;
1367
1368  delete_non_B_K_work_stuff (work);
1369
1370  /* If demangling was successful, ensure that the demangled string is null
1371     terminated and return it.  Otherwise, free the demangling decl.  */
1372
1373  if (!success)
1374    {
1375      string_delete (declp);
1376    }
1377  else
1378    {
1379      string_appendn (declp, "", 1);
1380      demangled = declp->b;
1381    }
1382  return (demangled);
1383}
1384
1385/*
1386
1387LOCAL FUNCTION
1388
1389	demangle_signature -- demangle the signature part of a mangled name
1390
1391SYNOPSIS
1392
1393	static int
1394	demangle_signature (struct work_stuff *work, const char **mangled,
1395			    string *declp);
1396
1397DESCRIPTION
1398
1399	Consume and demangle the signature portion of the mangled name.
1400
1401	DECLP is the string where demangled output is being built.  At
1402	entry it contains the demangled root name from the mangled name
1403	prefix.  I.E. either a demangled operator name or the root function
1404	name.  In some special cases, it may contain nothing.
1405
1406	*MANGLED points to the current unconsumed location in the mangled
1407	name.  As tokens are consumed and demangling is performed, the
1408	pointer is updated to continuously point at the next token to
1409	be consumed.
1410
1411	Demangling GNU style mangled names is nasty because there is no
1412	explicit token that marks the start of the outermost function
1413	argument list.  */
1414
1415static int
1416demangle_signature (struct work_stuff *work,
1417                    const char **mangled, string *declp)
1418{
1419  int success = 1;
1420  int func_done = 0;
1421  int expect_func = 0;
1422  int expect_return_type = 0;
1423  const char *oldmangled = NULL;
1424  string trawname;
1425  string tname;
1426
1427  while (success && (**mangled != '\0'))
1428    {
1429      switch (**mangled)
1430	{
1431	case 'Q':
1432	  oldmangled = *mangled;
1433	  success = demangle_qualified (work, mangled, declp, 1, 0);
1434	  if (success)
1435	    remember_type (work, oldmangled, *mangled - oldmangled);
1436	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1437	    expect_func = 1;
1438	  oldmangled = NULL;
1439	  break;
1440
1441        case 'K':
1442	  //oldmangled = *mangled;
1443	  success = demangle_qualified (work, mangled, declp, 1, 0);
1444	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1445	    {
1446	      expect_func = 1;
1447	    }
1448	  oldmangled = NULL;
1449	  break;
1450
1451	case 'S':
1452	  /* Static member function */
1453	  if (oldmangled == NULL)
1454	    {
1455	      oldmangled = *mangled;
1456	    }
1457	  (*mangled)++;
1458	  work -> static_type = 1;
1459	  break;
1460
1461	case 'C':
1462	case 'V':
1463	case 'u':
1464	  work->type_quals |= code_for_qualifier (**mangled);
1465
1466	  /* a qualified member function */
1467	  if (oldmangled == NULL)
1468	    oldmangled = *mangled;
1469	  (*mangled)++;
1470	  break;
1471
1472	case 'L':
1473	  /* Local class name follows after "Lnnn_" */
1474	  if (HP_DEMANGLING)
1475	    {
1476	      while (**mangled && (**mangled != '_'))
1477		(*mangled)++;
1478	      if (!**mangled)
1479		success = 0;
1480	      else
1481		(*mangled)++;
1482	    }
1483	  else
1484	    success = 0;
1485	  break;
1486
1487	case '0': case '1': case '2': case '3': case '4':
1488	case '5': case '6': case '7': case '8': case '9':
1489	  if (oldmangled == NULL)
1490	    {
1491	      oldmangled = *mangled;
1492	    }
1493          work->temp_start = -1; /* uppermost call to demangle_class */
1494	  success = demangle_class (work, mangled, declp);
1495	  if (success)
1496	    {
1497	      remember_type (work, oldmangled, *mangled - oldmangled);
1498	    }
1499	  if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1500	    {
1501              /* EDG and others will have the "F", so we let the loop cycle
1502                 if we are looking at one. */
1503              if (**mangled != 'F')
1504                 expect_func = 1;
1505	    }
1506	  oldmangled = NULL;
1507	  break;
1508
1509	case 'B':
1510	  {
1511	    string s;
1512	    success = do_type (work, mangled, &s);
1513	    if (success)
1514	      {
1515		string_append (&s, SCOPE_STRING (work));
1516		string_prepends (declp, &s);
1517		string_delete (&s);
1518	      }
1519	    oldmangled = NULL;
1520	    expect_func = 1;
1521	  }
1522	  break;
1523
1524	case 'F':
1525	  /* Function */
1526	  /* ARM/HP style demangling includes a specific 'F' character after
1527	     the class name.  For GNU style, it is just implied.  So we can
1528	     safely just consume any 'F' at this point and be compatible
1529	     with either style.  */
1530
1531	  oldmangled = NULL;
1532	  func_done = 1;
1533	  (*mangled)++;
1534
1535	  /* For lucid/ARM/HP style we have to forget any types we might
1536	     have remembered up to this point, since they were not argument
1537	     types.  GNU style considers all types seen as available for
1538	     back references.  See comment in demangle_args() */
1539
1540	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1541	    {
1542	      forget_types (work);
1543	    }
1544	  success = demangle_args (work, mangled, declp);
1545	  /* After picking off the function args, we expect to either
1546	     find the function return type (preceded by an '_') or the
1547	     end of the string. */
1548	  if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1549	    {
1550	      ++(*mangled);
1551              /* At this level, we do not care about the return type. */
1552              success = do_type (work, mangled, &tname);
1553              string_delete (&tname);
1554            }
1555
1556	  break;
1557
1558	case 't':
1559	  /* G++ Template */
1560	  string_init(&trawname);
1561	  string_init(&tname);
1562	  if (oldmangled == NULL)
1563	    {
1564	      oldmangled = *mangled;
1565	    }
1566	  success = demangle_template (work, mangled, &tname,
1567				       &trawname, 1, 1);
1568	  if (success)
1569	    {
1570	      remember_type (work, oldmangled, *mangled - oldmangled);
1571	    }
1572	  string_append (&tname, SCOPE_STRING (work));
1573
1574	  string_prepends(declp, &tname);
1575	  if (work -> destructor & 1)
1576	    {
1577	      string_prepend (&trawname, "~");
1578	      string_appends (declp, &trawname);
1579	      work->destructor -= 1;
1580	    }
1581	  if ((work->constructor & 1) || (work->destructor & 1))
1582	    {
1583	      string_appends (declp, &trawname);
1584	      work->constructor -= 1;
1585	    }
1586	  string_delete(&trawname);
1587	  string_delete(&tname);
1588	  oldmangled = NULL;
1589	  expect_func = 1;
1590	  break;
1591
1592	case '_':
1593	  if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1594	    {
1595	      /* Read the return type. */
1596	      string return_type;
1597
1598	      (*mangled)++;
1599	      success = do_type (work, mangled, &return_type);
1600	      APPEND_BLANK (&return_type);
1601
1602	      string_prepends (declp, &return_type);
1603	      string_delete (&return_type);
1604	      break;
1605	    }
1606	  else
1607	    /* At the outermost level, we cannot have a return type specified,
1608	       so if we run into another '_' at this point we are dealing with
1609	       a mangled name that is either bogus, or has been mangled by
1610	       some algorithm we don't know how to deal with.  So just
1611	       reject the entire demangling.  */
1612            /* However, "_nnn" is an expected suffix for alternate entry point
1613               numbered nnn for a function, with HP aCC, so skip over that
1614               without reporting failure. pai/1997-09-04 */
1615            if (HP_DEMANGLING)
1616              {
1617                (*mangled)++;
1618                while (**mangled && ISDIGIT ((unsigned char)**mangled))
1619                  (*mangled)++;
1620              }
1621            else
1622	      success = 0;
1623	  break;
1624
1625	case 'H':
1626	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1627	    {
1628	      /* A G++ template function.  Read the template arguments. */
1629	      success = demangle_template (work, mangled, declp, 0, 0,
1630					   0);
1631	      if (!(work->constructor & 1))
1632		expect_return_type = 1;
1633	      (*mangled)++;
1634	      break;
1635	    }
1636	  else
1637	    /* fall through */
1638	    {;}
1639
1640	default:
1641	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1642	    {
1643	      /* Assume we have stumbled onto the first outermost function
1644		 argument token, and start processing args.  */
1645	      func_done = 1;
1646	      success = demangle_args (work, mangled, declp);
1647	    }
1648	  else
1649	    {
1650	      /* Non-GNU demanglers use a specific token to mark the start
1651		 of the outermost function argument tokens.  Typically 'F',
1652		 for ARM/HP-demangling, for example.  So if we find something
1653		 we are not prepared for, it must be an error.  */
1654	      success = 0;
1655	    }
1656	  break;
1657	}
1658      /*
1659	if (AUTO_DEMANGLING || GNU_DEMANGLING)
1660	*/
1661      {
1662	if (success && expect_func)
1663	  {
1664	    func_done = 1;
1665              if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1666                {
1667                  forget_types (work);
1668                }
1669	    success = demangle_args (work, mangled, declp);
1670	    /* Since template include the mangling of their return types,
1671	       we must set expect_func to 0 so that we don't try do
1672	       demangle more arguments the next time we get here.  */
1673	    expect_func = 0;
1674	  }
1675      }
1676    }
1677  if (success && !func_done)
1678    {
1679      if (AUTO_DEMANGLING || GNU_DEMANGLING)
1680	{
1681	  /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1682	     bar__3fooi is 'foo::bar(int)'.  We get here when we find the
1683	     first case, and need to ensure that the '(void)' gets added to
1684	     the current declp.  Note that with ARM/HP, the first case
1685	     represents the name of a static data member 'foo::bar',
1686	     which is in the current declp, so we leave it alone.  */
1687	  success = demangle_args (work, mangled, declp);
1688	}
1689    }
1690  if (success && PRINT_ARG_TYPES)
1691    {
1692      if (work->static_type)
1693	string_append (declp, " static");
1694      if (work->type_quals != TYPE_UNQUALIFIED)
1695	{
1696	  APPEND_BLANK (declp);
1697	  string_append (declp, qualifier_string (work->type_quals));
1698	}
1699    }
1700
1701  return (success);
1702}
1703
1704#if 0
1705
1706static int
1707demangle_method_args (struct work_stuff *work, const char **mangled,
1708                      string *declp)
1709{
1710  int success = 0;
1711
1712  if (work -> static_type)
1713    {
1714      string_append (declp, *mangled + 1);
1715      *mangled += strlen (*mangled);
1716      success = 1;
1717    }
1718  else
1719    {
1720      success = demangle_args (work, mangled, declp);
1721    }
1722  return (success);
1723}
1724
1725#endif
1726
1727static int
1728demangle_template_template_parm (struct work_stuff *work,
1729                                 const char **mangled, string *tname)
1730{
1731  int i;
1732  int r;
1733  int need_comma = 0;
1734  int success = 1;
1735  string temp;
1736
1737  string_append (tname, "template <");
1738  /* get size of template parameter list */
1739  if (get_count (mangled, &r))
1740    {
1741      for (i = 0; i < r; i++)
1742	{
1743	  if (need_comma)
1744	    {
1745	      string_append (tname, ", ");
1746	    }
1747
1748	    /* Z for type parameters */
1749	    if (**mangled == 'Z')
1750	      {
1751		(*mangled)++;
1752		string_append (tname, "class");
1753	      }
1754	      /* z for template parameters */
1755	    else if (**mangled == 'z')
1756	      {
1757		(*mangled)++;
1758		success =
1759		  demangle_template_template_parm (work, mangled, tname);
1760		if (!success)
1761		  {
1762		    break;
1763		  }
1764	      }
1765	    else
1766	      {
1767		/* temp is initialized in do_type */
1768		success = do_type (work, mangled, &temp);
1769		if (success)
1770		  {
1771		    string_appends (tname, &temp);
1772		  }
1773		string_delete(&temp);
1774		if (!success)
1775		  {
1776		    break;
1777		  }
1778	      }
1779	  need_comma = 1;
1780	}
1781
1782    }
1783  if (tname->p[-1] == '>')
1784    string_append (tname, " ");
1785  string_append (tname, "> class");
1786  return (success);
1787}
1788
1789static int
1790demangle_expression (struct work_stuff *work, const char **mangled,
1791                     string *s, type_kind_t tk)
1792{
1793  int need_operator = 0;
1794  int success;
1795
1796  success = 1;
1797  string_appendn (s, "(", 1);
1798  (*mangled)++;
1799  while (success && **mangled != 'W' && **mangled != '\0')
1800    {
1801      if (need_operator)
1802	{
1803	  size_t i;
1804	  size_t len;
1805
1806	  success = 0;
1807
1808	  len = strlen (*mangled);
1809
1810	  for (i = 0; i < ARRAY_SIZE (optable); ++i)
1811	    {
1812	      size_t l = strlen (optable[i].in);
1813
1814	      if (l <= len
1815		  && memcmp (optable[i].in, *mangled, l) == 0)
1816		{
1817		  string_appendn (s, " ", 1);
1818		  string_append (s, optable[i].out);
1819		  string_appendn (s, " ", 1);
1820		  success = 1;
1821		  (*mangled) += l;
1822		  break;
1823		}
1824	    }
1825
1826	  if (!success)
1827	    break;
1828	}
1829      else
1830	need_operator = 1;
1831
1832      success = demangle_template_value_parm (work, mangled, s, tk);
1833    }
1834
1835  if (**mangled != 'W')
1836    success = 0;
1837  else
1838    {
1839      string_appendn (s, ")", 1);
1840      (*mangled)++;
1841    }
1842
1843  return success;
1844}
1845
1846static int
1847demangle_integral_value (struct work_stuff *work,
1848                         const char **mangled, string *s)
1849{
1850  int success;
1851
1852  if (**mangled == 'E')
1853    success = demangle_expression (work, mangled, s, tk_integral);
1854  else if (**mangled == 'Q' || **mangled == 'K')
1855    success = demangle_qualified (work, mangled, s, 0, 1);
1856  else
1857    {
1858      int value;
1859
1860      /* By default, we let the number decide whether we shall consume an
1861	 underscore.  */
1862      int multidigit_without_leading_underscore = 0;
1863      int leave_following_underscore = 0;
1864
1865      success = 0;
1866
1867      if (**mangled == '_')
1868        {
1869	  if (mangled[0][1] == 'm')
1870	    {
1871	      /* Since consume_count_with_underscores does not handle the
1872		 `m'-prefix we must do it here, using consume_count and
1873		 adjusting underscores: we have to consume the underscore
1874		 matching the prepended one.  */
1875	      multidigit_without_leading_underscore = 1;
1876	      string_appendn (s, "-", 1);
1877	      (*mangled) += 2;
1878	    }
1879	  else
1880	    {
1881	      /* Do not consume a following underscore;
1882	         consume_count_with_underscores will consume what
1883	         should be consumed.  */
1884	      leave_following_underscore = 1;
1885	    }
1886	}
1887      else
1888	{
1889	  /* Negative numbers are indicated with a leading `m'.  */
1890	  if (**mangled == 'm')
1891	  {
1892	    string_appendn (s, "-", 1);
1893	    (*mangled)++;
1894	  }
1895	  /* Since consume_count_with_underscores does not handle
1896	     multi-digit numbers that do not start with an underscore,
1897	     and this number can be an integer template parameter,
1898	     we have to call consume_count. */
1899	  multidigit_without_leading_underscore = 1;
1900	  /* These multi-digit numbers never end on an underscore,
1901	     so if there is one then don't eat it. */
1902	  leave_following_underscore = 1;
1903	}
1904
1905      /* We must call consume_count if we expect to remove a trailing
1906	 underscore, since consume_count_with_underscores expects
1907	 the leading underscore (that we consumed) if it is to handle
1908	 multi-digit numbers.  */
1909      if (multidigit_without_leading_underscore)
1910	value = consume_count (mangled);
1911      else
1912	value = consume_count_with_underscores (mangled);
1913
1914      if (value != -1)
1915	{
1916	  char buf[INTBUF_SIZE];
1917	  sprintf (buf, "%d", value);
1918	  string_append (s, buf);
1919
1920	  /* Numbers not otherwise delimited, might have an underscore
1921	     appended as a delimeter, which we should skip.
1922
1923	     ??? This used to always remove a following underscore, which
1924	     is wrong.  If other (arbitrary) cases are followed by an
1925	     underscore, we need to do something more radical.  */
1926
1927	  if ((value > 9 || multidigit_without_leading_underscore)
1928	      && ! leave_following_underscore
1929	      && **mangled == '_')
1930	    (*mangled)++;
1931
1932	  /* All is well.  */
1933	  success = 1;
1934	}
1935      }
1936
1937  return success;
1938}
1939
1940/* Demangle the real value in MANGLED.  */
1941
1942static int
1943demangle_real_value (struct work_stuff *work,
1944                     const char **mangled, string *s)
1945{
1946  if (**mangled == 'E')
1947    return demangle_expression (work, mangled, s, tk_real);
1948
1949  if (**mangled == 'm')
1950    {
1951      string_appendn (s, "-", 1);
1952      (*mangled)++;
1953    }
1954  while (ISDIGIT ((unsigned char)**mangled))
1955    {
1956      string_appendn (s, *mangled, 1);
1957      (*mangled)++;
1958    }
1959  if (**mangled == '.') /* fraction */
1960    {
1961      string_appendn (s, ".", 1);
1962      (*mangled)++;
1963      while (ISDIGIT ((unsigned char)**mangled))
1964	{
1965	  string_appendn (s, *mangled, 1);
1966	  (*mangled)++;
1967	}
1968    }
1969  if (**mangled == 'e') /* exponent */
1970    {
1971      string_appendn (s, "e", 1);
1972      (*mangled)++;
1973      while (ISDIGIT ((unsigned char)**mangled))
1974	{
1975	  string_appendn (s, *mangled, 1);
1976	  (*mangled)++;
1977	}
1978    }
1979
1980  return 1;
1981}
1982
1983static int
1984demangle_template_value_parm (struct work_stuff *work, const char **mangled,
1985                              string *s, type_kind_t tk)
1986{
1987  int success = 1;
1988
1989  if (**mangled == 'Y')
1990    {
1991      /* The next argument is a template parameter. */
1992      int idx;
1993
1994      (*mangled)++;
1995      idx = consume_count_with_underscores (mangled);
1996      if (idx == -1
1997	  || (work->tmpl_argvec && idx >= work->ntmpl_args)
1998	  || consume_count_with_underscores (mangled) == -1)
1999	return -1;
2000      if (work->tmpl_argvec)
2001	string_append (s, work->tmpl_argvec[idx]);
2002      else
2003	string_append_template_idx (s, idx);
2004    }
2005  else if (tk == tk_integral)
2006    success = demangle_integral_value (work, mangled, s);
2007  else if (tk == tk_char)
2008    {
2009      char tmp[2];
2010      int val;
2011      if (**mangled == 'm')
2012	{
2013	  string_appendn (s, "-", 1);
2014	  (*mangled)++;
2015	}
2016      string_appendn (s, "'", 1);
2017      val = consume_count(mangled);
2018      if (val <= 0)
2019	success = 0;
2020      else
2021	{
2022	  tmp[0] = (char)val;
2023	  tmp[1] = '\0';
2024	  string_appendn (s, &tmp[0], 1);
2025	  string_appendn (s, "'", 1);
2026	}
2027    }
2028  else if (tk == tk_bool)
2029    {
2030      int val = consume_count (mangled);
2031      if (val == 0)
2032	string_appendn (s, "false", 5);
2033      else if (val == 1)
2034	string_appendn (s, "true", 4);
2035      else
2036	success = 0;
2037    }
2038  else if (tk == tk_real)
2039    success = demangle_real_value (work, mangled, s);
2040  else if (tk == tk_pointer || tk == tk_reference)
2041    {
2042      if (**mangled == 'Q')
2043	success = demangle_qualified (work, mangled, s,
2044				      /*isfuncname=*/0,
2045				      /*append=*/1);
2046      else
2047	{
2048	  int symbol_len  = consume_count (mangled);
2049	  if (symbol_len == -1)
2050	    return -1;
2051	  if (symbol_len == 0)
2052	    string_appendn (s, "0", 1);
2053	  else
2054	    {
2055	      char *p = XNEWVEC (char, symbol_len + 1), *q;
2056	      strncpy (p, *mangled, symbol_len);
2057	      p [symbol_len] = '\0';
2058	      /* We use cplus_demangle here, rather than
2059		 internal_cplus_demangle, because the name of the entity
2060		 mangled here does not make use of any of the squangling
2061		 or type-code information we have built up thus far; it is
2062		 mangled independently.  */
2063	      q = ML_(cplus_demangle) (p, work->options);
2064	      if (tk == tk_pointer)
2065		string_appendn (s, "&", 1);
2066	      /* FIXME: Pointer-to-member constants should get a
2067		 qualifying class name here.  */
2068	      if (q)
2069		{
2070		  string_append (s, q);
2071		  free (q);
2072		}
2073	      else
2074		string_append (s, p);
2075	      free (p);
2076	    }
2077	  *mangled += symbol_len;
2078	}
2079    }
2080
2081  return success;
2082}
2083
2084/* Demangle the template name in MANGLED.  The full name of the
2085   template (e.g., S<int>) is placed in TNAME.  The name without the
2086   template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2087   non-NULL.  If IS_TYPE is nonzero, this template is a type template,
2088   not a function template.  If both IS_TYPE and REMEMBER are nonzero,
2089   the template is remembered in the list of back-referenceable
2090   types.  */
2091
2092static int
2093demangle_template (struct work_stuff *work, const char **mangled,
2094                   string *tname, string *trawname,
2095                   int is_type, int remember)
2096{
2097  int i;
2098  int r;
2099  int need_comma = 0;
2100  int success = 0;
2101  int is_java_array = 0;
2102  string temp;
2103
2104  (*mangled)++;
2105  if (is_type)
2106    {
2107      /* get template name */
2108      if (**mangled == 'z')
2109	{
2110	  int idx;
2111	  (*mangled)++;
2112	  (*mangled)++;
2113
2114	  idx = consume_count_with_underscores (mangled);
2115	  if (idx == -1
2116	      || (work->tmpl_argvec && idx >= work->ntmpl_args)
2117	      || consume_count_with_underscores (mangled) == -1)
2118	    return (0);
2119
2120	  if (work->tmpl_argvec)
2121	    {
2122	      string_append (tname, work->tmpl_argvec[idx]);
2123	      if (trawname)
2124		string_append (trawname, work->tmpl_argvec[idx]);
2125	    }
2126	  else
2127	    {
2128	      string_append_template_idx (tname, idx);
2129	      if (trawname)
2130		string_append_template_idx (trawname, idx);
2131	    }
2132	}
2133      else
2134	{
2135	  if ((r = consume_count (mangled)) <= 0
2136	      || (int) strlen (*mangled) < r)
2137	    {
2138	      return (0);
2139	    }
2140	  is_java_array = (work -> options & DMGL_JAVA)
2141	    && strncmp (*mangled, "JArray1Z", 8) == 0;
2142	  if (! is_java_array)
2143	    {
2144	      string_appendn (tname, *mangled, r);
2145	    }
2146	  if (trawname)
2147	    string_appendn (trawname, *mangled, r);
2148	  *mangled += r;
2149	}
2150    }
2151  if (!is_java_array)
2152    string_append (tname, "<");
2153  /* get size of template parameter list */
2154  if (!get_count (mangled, &r))
2155    {
2156      return (0);
2157    }
2158  if (!is_type)
2159    {
2160      /* Create an array for saving the template argument values. */
2161      work->tmpl_argvec = XNEWVEC (char *, r);
2162      work->ntmpl_args = r;
2163      for (i = 0; i < r; i++)
2164	work->tmpl_argvec[i] = 0;
2165    }
2166  for (i = 0; i < r; i++)
2167    {
2168      if (need_comma)
2169	{
2170	  string_append (tname, ", ");
2171	}
2172      /* Z for type parameters */
2173      if (**mangled == 'Z')
2174	{
2175	  (*mangled)++;
2176	  /* temp is initialized in do_type */
2177	  success = do_type (work, mangled, &temp);
2178	  if (success)
2179	    {
2180	      string_appends (tname, &temp);
2181
2182	      if (!is_type)
2183		{
2184		  /* Save the template argument. */
2185		  int len = temp.p - temp.b;
2186		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2187		  memcpy (work->tmpl_argvec[i], temp.b, len);
2188		  work->tmpl_argvec[i][len] = '\0';
2189		}
2190	    }
2191	  string_delete(&temp);
2192	  if (!success)
2193	    {
2194	      break;
2195	    }
2196	}
2197      /* z for template parameters */
2198      else if (**mangled == 'z')
2199	{
2200	  int r2;
2201	  (*mangled)++;
2202	  success = demangle_template_template_parm (work, mangled, tname);
2203
2204	  if (success
2205	      && (r2 = consume_count (mangled)) > 0
2206	      && (int) strlen (*mangled) >= r2)
2207	    {
2208	      string_append (tname, " ");
2209	      string_appendn (tname, *mangled, r2);
2210	      if (!is_type)
2211		{
2212		  /* Save the template argument. */
2213		  int len = r2;
2214		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2215		  memcpy (work->tmpl_argvec[i], *mangled, len);
2216		  work->tmpl_argvec[i][len] = '\0';
2217		}
2218	      *mangled += r2;
2219	    }
2220	  if (!success)
2221	    {
2222	      break;
2223	    }
2224	}
2225      else
2226	{
2227	  string  param;
2228	  string* s;
2229
2230	  /* otherwise, value parameter */
2231
2232	  /* temp is initialized in do_type */
2233	  success = do_type (work, mangled, &temp);
2234	  string_delete(&temp);
2235	  if (!success)
2236	    break;
2237
2238	  if (!is_type)
2239	    {
2240	      s = &param;
2241	      string_init (s);
2242	    }
2243	  else
2244	    s = tname;
2245
2246	  success = demangle_template_value_parm (work, mangled, s,
2247						  (type_kind_t) success);
2248
2249	  if (!success)
2250	    {
2251	      if (!is_type)
2252		string_delete (s);
2253	      success = 0;
2254	      break;
2255	    }
2256
2257	  if (!is_type)
2258	    {
2259	      int len = s->p - s->b;
2260	      work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2261	      memcpy (work->tmpl_argvec[i], s->b, len);
2262	      work->tmpl_argvec[i][len] = '\0';
2263
2264	      string_appends (tname, s);
2265	      string_delete (s);
2266	    }
2267	}
2268      need_comma = 1;
2269    }
2270  if (is_java_array)
2271    {
2272      string_append (tname, "[]");
2273    }
2274  else
2275    {
2276      if (tname->p[-1] == '>')
2277	string_append (tname, " ");
2278      string_append (tname, ">");
2279    }
2280
2281  if (is_type && remember)
2282    {
2283      const int bindex = register_Btype (work);
2284      remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2285    }
2286
2287  /*
2288    if (work -> static_type)
2289    {
2290    string_append (declp, *mangled + 1);
2291    *mangled += strlen (*mangled);
2292    success = 1;
2293    }
2294    else
2295    {
2296    success = demangle_args (work, mangled, declp);
2297    }
2298    }
2299    */
2300  return (success);
2301}
2302
2303static int
2304arm_pt (const char *mangled,
2305        int n, const char **anchor, const char **args)
2306{
2307  /* Check if ARM template with "__pt__" in it ("parameterized type") */
2308  /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2309  if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2310    {
2311      int len;
2312      *args = *anchor + 6;
2313      len = consume_count (args);
2314      if (len == -1)
2315	return 0;
2316      if (*args + len == mangled + n && **args == '_')
2317	{
2318	  ++*args;
2319	  return 1;
2320	}
2321    }
2322  if (AUTO_DEMANGLING || EDG_DEMANGLING)
2323    {
2324      if ((*anchor = strstr (mangled, "__tm__"))
2325          || (*anchor = strstr (mangled, "__ps__"))
2326          || (*anchor = strstr (mangled, "__pt__")))
2327        {
2328          int len;
2329          *args = *anchor + 6;
2330          len = consume_count (args);
2331	  if (len == -1)
2332	    return 0;
2333          if (*args + len == mangled + n && **args == '_')
2334            {
2335              ++*args;
2336              return 1;
2337            }
2338        }
2339      else if ((*anchor = strstr (mangled, "__S")))
2340        {
2341 	  int len;
2342 	  *args = *anchor + 3;
2343 	  len = consume_count (args);
2344	  if (len == -1)
2345	    return 0;
2346 	  if (*args + len == mangled + n && **args == '_')
2347            {
2348              ++*args;
2349 	      return 1;
2350            }
2351        }
2352    }
2353
2354  return 0;
2355}
2356
2357static void
2358demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
2359                          int n, string *declp)
2360{
2361  const char *p;
2362  const char *args;
2363  const char *e = *mangled + n;
2364  string arg;
2365
2366  /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2367     template args */
2368  if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2369    {
2370      char *start_spec_args = NULL;
2371      int hold_options;
2372
2373      /* First check for and omit template specialization pseudo-arguments,
2374         such as in "Spec<#1,#1.*>" */
2375      start_spec_args = strchr (*mangled, '<');
2376      if (start_spec_args && (start_spec_args - *mangled < n))
2377        string_appendn (declp, *mangled, start_spec_args - *mangled);
2378      else
2379        string_appendn (declp, *mangled, n);
2380      (*mangled) += n + 1;
2381      string_init (&arg);
2382      if (work->temp_start == -1) /* non-recursive call */
2383        work->temp_start = declp->p - declp->b;
2384
2385      /* We want to unconditionally demangle parameter types in
2386	 template parameters.  */
2387      hold_options = work->options;
2388      work->options |= DMGL_PARAMS;
2389
2390      string_append (declp, "<");
2391      while (1)
2392        {
2393          string_delete (&arg);
2394          switch (**mangled)
2395            {
2396              case 'T':
2397                /* 'T' signals a type parameter */
2398                (*mangled)++;
2399                if (!do_type (work, mangled, &arg))
2400                  goto hpacc_template_args_done;
2401                break;
2402
2403              case 'U':
2404              case 'S':
2405                /* 'U' or 'S' signals an integral value */
2406                if (!do_hpacc_template_const_value (work, mangled, &arg))
2407                  goto hpacc_template_args_done;
2408                break;
2409
2410              case 'A':
2411                /* 'A' signals a named constant expression (literal) */
2412                if (!do_hpacc_template_literal (work, mangled, &arg))
2413                  goto hpacc_template_args_done;
2414                break;
2415
2416              default:
2417                /* Today, 1997-09-03, we have only the above types
2418                   of template parameters */
2419                /* FIXME: maybe this should fail and return null */
2420                goto hpacc_template_args_done;
2421            }
2422          string_appends (declp, &arg);
2423         /* Check if we're at the end of template args.
2424             0 if at end of static member of template class,
2425             _ if done with template args for a function */
2426          if ((**mangled == '\000') || (**mangled == '_'))
2427            break;
2428          else
2429            string_append (declp, ",");
2430        }
2431    hpacc_template_args_done:
2432      string_append (declp, ">");
2433      string_delete (&arg);
2434      if (**mangled == '_')
2435        (*mangled)++;
2436      work->options = hold_options;
2437      return;
2438    }
2439  /* ARM template? (Also handles HP cfront extensions) */
2440  else if (arm_pt (*mangled, n, &p, &args))
2441    {
2442      int hold_options;
2443      string type_str;
2444
2445      string_init (&arg);
2446      string_appendn (declp, *mangled, p - *mangled);
2447      if (work->temp_start == -1)  /* non-recursive call */
2448	work->temp_start = declp->p - declp->b;
2449
2450      /* We want to unconditionally demangle parameter types in
2451	 template parameters.  */
2452      hold_options = work->options;
2453      work->options |= DMGL_PARAMS;
2454
2455      string_append (declp, "<");
2456      /* should do error checking here */
2457      while (args < e) {
2458	string_delete (&arg);
2459
2460	/* Check for type or literal here */
2461	switch (*args)
2462	  {
2463	    /* HP cfront extensions to ARM for template args */
2464	    /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2465	    /* FIXME: We handle only numeric literals for HP cfront */
2466          case 'X':
2467            /* A typed constant value follows */
2468            args++;
2469            if (!do_type (work, &args, &type_str))
2470	      goto cfront_template_args_done;
2471            string_append (&arg, "(");
2472            string_appends (&arg, &type_str);
2473            string_delete (&type_str);
2474            string_append (&arg, ")");
2475            if (*args != 'L')
2476              goto cfront_template_args_done;
2477            args++;
2478            /* Now snarf a literal value following 'L' */
2479            if (!snarf_numeric_literal (&args, &arg))
2480	      goto cfront_template_args_done;
2481            break;
2482
2483          case 'L':
2484            /* Snarf a literal following 'L' */
2485            args++;
2486            if (!snarf_numeric_literal (&args, &arg))
2487	      goto cfront_template_args_done;
2488            break;
2489          default:
2490            /* Not handling other HP cfront stuff */
2491            {
2492              const char* old_args = args;
2493              if (!do_type (work, &args, &arg))
2494                goto cfront_template_args_done;
2495
2496              /* Fail if we didn't make any progress: prevent infinite loop. */
2497              if (args == old_args)
2498		{
2499		  work->options = hold_options;
2500		  return;
2501		}
2502            }
2503	  }
2504	string_appends (declp, &arg);
2505	string_append (declp, ",");
2506      }
2507    cfront_template_args_done:
2508      string_delete (&arg);
2509      if (args >= e)
2510	--declp->p; /* remove extra comma */
2511      string_append (declp, ">");
2512      work->options = hold_options;
2513    }
2514  else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2515	   && (*mangled)[9] == 'N'
2516	   && (*mangled)[8] == (*mangled)[10]
2517	   && strchr (cplus_markers, (*mangled)[8]))
2518    {
2519      /* A member of the anonymous namespace.  */
2520      string_append (declp, "{anonymous}");
2521    }
2522  else
2523    {
2524      if (work->temp_start == -1) /* non-recursive call only */
2525	work->temp_start = 0;     /* disable in recursive calls */
2526      string_appendn (declp, *mangled, n);
2527    }
2528  *mangled += n;
2529}
2530
2531/* Extract a class name, possibly a template with arguments, from the
2532   mangled string; qualifiers, local class indicators, etc. have
2533   already been dealt with */
2534
2535static int
2536demangle_class_name (struct work_stuff *work, const char **mangled,
2537                     string *declp)
2538{
2539  int n;
2540  int success = 0;
2541
2542  n = consume_count (mangled);
2543  if (n == -1)
2544    return 0;
2545  if ((int) strlen (*mangled) >= n)
2546    {
2547      demangle_arm_hp_template (work, mangled, n, declp);
2548      success = 1;
2549    }
2550
2551  return (success);
2552}
2553
2554/*
2555
2556LOCAL FUNCTION
2557
2558	demangle_class -- demangle a mangled class sequence
2559
2560SYNOPSIS
2561
2562	static int
2563	demangle_class (struct work_stuff *work, const char **mangled,
2564			strint *declp)
2565
2566DESCRIPTION
2567
2568	DECLP points to the buffer into which demangling is being done.
2569
2570	*MANGLED points to the current token to be demangled.  On input,
2571	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2572	On exit, it points to the next token after the mangled class on
2573	success, or the first unconsumed token on failure.
2574
2575	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2576	we are demangling a constructor or destructor.  In this case
2577	we prepend "class::class" or "class::~class" to DECLP.
2578
2579	Otherwise, we prepend "class::" to the current DECLP.
2580
2581	Reset the constructor/destructor flags once they have been
2582	"consumed".  This allows demangle_class to be called later during
2583	the same demangling, to do normal class demangling.
2584
2585	Returns 1 if demangling is successful, 0 otherwise.
2586
2587*/
2588
2589static int
2590demangle_class (struct work_stuff *work, const char **mangled, string *declp)
2591{
2592  int success = 0;
2593  int btype;
2594  string class_name;
2595  char *save_class_name_end = 0;
2596
2597  string_init (&class_name);
2598  btype = register_Btype (work);
2599  if (demangle_class_name (work, mangled, &class_name))
2600    {
2601      save_class_name_end = class_name.p;
2602      if ((work->constructor & 1) || (work->destructor & 1))
2603	{
2604          /* adjust so we don't include template args */
2605          if (work->temp_start && (work->temp_start != -1))
2606            {
2607              class_name.p = class_name.b + work->temp_start;
2608            }
2609	  string_prepends (declp, &class_name);
2610	  if (work -> destructor & 1)
2611	    {
2612	      string_prepend (declp, "~");
2613              work -> destructor -= 1;
2614	    }
2615	  else
2616	    {
2617	      work -> constructor -= 1;
2618	    }
2619	}
2620      class_name.p = save_class_name_end;
2621      remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2622      remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2623      string_prepend (declp, SCOPE_STRING (work));
2624      string_prepends (declp, &class_name);
2625      success = 1;
2626    }
2627  string_delete (&class_name);
2628  return (success);
2629}
2630
2631
2632/* Called when there's a "__" in the mangled name, with `scan' pointing to
2633   the rightmost guess.
2634
2635   Find the correct "__"-sequence where the function name ends and the
2636   signature starts, which is ambiguous with GNU mangling.
2637   Call demangle_signature here, so we can make sure we found the right
2638   one; *mangled will be consumed so caller will not make further calls to
2639   demangle_signature.  */
2640
2641static int
2642iterate_demangle_function (struct work_stuff *work, const char **mangled,
2643                           string *declp, const char *scan)
2644{
2645  const char *mangle_init = *mangled;
2646  int success = 0;
2647  string decl_init;
2648  struct work_stuff work_init;
2649
2650  if (*(scan + 2) == '\0')
2651    return 0;
2652
2653  /* Do not iterate for some demangling modes, or if there's only one
2654     "__"-sequence.  This is the normal case.  */
2655  if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2656      || strstr (scan + 2, "__") == NULL)
2657    return demangle_function_name (work, mangled, declp, scan);
2658
2659  /* Save state so we can restart if the guess at the correct "__" was
2660     wrong.  */
2661  string_init (&decl_init);
2662  string_appends (&decl_init, declp);
2663  memset (&work_init, 0, sizeof work_init);
2664  work_stuff_copy_to_from (&work_init, work);
2665
2666  /* Iterate over occurrences of __, allowing names and types to have a
2667     "__" sequence in them.  We must start with the first (not the last)
2668     occurrence, since "__" most often occur between independent mangled
2669     parts, hence starting at the last occurrence inside a signature
2670     might get us a "successful" demangling of the signature.  */
2671
2672  while (scan[2])
2673    {
2674      if (demangle_function_name (work, mangled, declp, scan))
2675	{
2676	  success = demangle_signature (work, mangled, declp);
2677	  if (success)
2678	    break;
2679	}
2680
2681      /* Reset demangle state for the next round.  */
2682      *mangled = mangle_init;
2683      string_clear (declp);
2684      string_appends (declp, &decl_init);
2685      work_stuff_copy_to_from (work, &work_init);
2686
2687      /* Leave this underscore-sequence.  */
2688      scan += 2;
2689
2690      /* Scan for the next "__" sequence.  */
2691      while (*scan && (scan[0] != '_' || scan[1] != '_'))
2692	scan++;
2693
2694      /* Move to last "__" in this sequence.  */
2695      while (*scan && *scan == '_')
2696	scan++;
2697      scan -= 2;
2698    }
2699
2700  /* Delete saved state.  */
2701  delete_work_stuff (&work_init);
2702  string_delete (&decl_init);
2703
2704  return success;
2705}
2706
2707/*
2708
2709LOCAL FUNCTION
2710
2711	demangle_prefix -- consume the mangled name prefix and find signature
2712
2713SYNOPSIS
2714
2715	static int
2716	demangle_prefix (struct work_stuff *work, const char **mangled,
2717			 string *declp);
2718
2719DESCRIPTION
2720
2721	Consume and demangle the prefix of the mangled name.
2722	While processing the function name root, arrange to call
2723	demangle_signature if the root is ambiguous.
2724
2725	DECLP points to the string buffer into which demangled output is
2726	placed.  On entry, the buffer is empty.  On exit it contains
2727	the root function name, the demangled operator name, or in some
2728	special cases either nothing or the completely demangled result.
2729
2730	MANGLED points to the current pointer into the mangled name.  As each
2731	token of the mangled name is consumed, it is updated.  Upon entry
2732	the current mangled name pointer points to the first character of
2733	the mangled name.  Upon exit, it should point to the first character
2734	of the signature if demangling was successful, or to the first
2735	unconsumed character if demangling of the prefix was unsuccessful.
2736
2737	Returns 1 on success, 0 otherwise.
2738 */
2739
2740static int
2741demangle_prefix (struct work_stuff *work, const char **mangled,
2742                 string *declp)
2743{
2744  int success = 1;
2745  const char *scan;
2746  int i;
2747
2748  if (strlen(*mangled) > 6
2749      && (strncmp(*mangled, "_imp__", 6) == 0
2750          || strncmp(*mangled, "__imp_", 6) == 0))
2751    {
2752      /* it's a symbol imported from a PE dynamic library. Check for both
2753         new style prefix _imp__ and legacy __imp_ used by older versions
2754	 of dlltool. */
2755      (*mangled) += 6;
2756      work->dllimported = 1;
2757    }
2758  else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2759    {
2760      char *marker = strchr (cplus_markers, (*mangled)[8]);
2761      if (marker != NULL && *marker == (*mangled)[10])
2762	{
2763	  if ((*mangled)[9] == 'D')
2764	    {
2765	      /* it's a GNU global destructor to be executed at program exit */
2766	      (*mangled) += 11;
2767	      work->destructor = 2;
2768	      if (gnu_special (work, mangled, declp))
2769		return success;
2770	    }
2771	  else if ((*mangled)[9] == 'I')
2772	    {
2773	      /* it's a GNU global constructor to be executed at program init */
2774	      (*mangled) += 11;
2775	      work->constructor = 2;
2776	      if (gnu_special (work, mangled, declp))
2777		return success;
2778	    }
2779	}
2780    }
2781  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2782    {
2783      /* it's a ARM global destructor to be executed at program exit */
2784      (*mangled) += 7;
2785      work->destructor = 2;
2786    }
2787  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2788    {
2789      /* it's a ARM global constructor to be executed at program initial */
2790      (*mangled) += 7;
2791      work->constructor = 2;
2792    }
2793
2794  /*  This block of code is a reduction in strength time optimization
2795      of:
2796      scan = strstr (*mangled, "__"); */
2797
2798  {
2799    scan = *mangled;
2800
2801    do {
2802      scan = strchr (scan, '_');
2803    } while (scan != NULL && *++scan != '_');
2804
2805    if (scan != NULL) --scan;
2806  }
2807
2808  if (scan != NULL)
2809    {
2810      /* We found a sequence of two or more '_', ensure that we start at
2811	 the last pair in the sequence.  */
2812      i = strspn (scan, "_");
2813      if (i > 2)
2814	{
2815	  scan += (i - 2);
2816	}
2817    }
2818
2819  if (scan == NULL)
2820    {
2821      success = 0;
2822    }
2823  else if (work -> static_type)
2824    {
2825      if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2826	{
2827	  success = 0;
2828	}
2829    }
2830  else if ((scan == *mangled)
2831	   && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2832	       || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2833    {
2834      /* The ARM says nothing about the mangling of local variables.
2835	 But cfront mangles local variables by prepending __<nesting_level>
2836	 to them. As an extension to ARM demangling we handle this case.  */
2837      if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2838	  && ISDIGIT ((unsigned char)scan[2]))
2839	{
2840	  *mangled = scan + 2;
2841	  consume_count (mangled);
2842	  string_append (declp, *mangled);
2843	  *mangled += strlen (*mangled);
2844	  success = 1;
2845	}
2846      else
2847	{
2848	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2849	     names like __Q2_3foo3bar for nested type names.  So don't accept
2850	     this style of constructor for cfront demangling.  A GNU
2851	     style member-template constructor starts with 'H'. */
2852	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2853	    work -> constructor += 1;
2854	  *mangled = scan + 2;
2855	}
2856    }
2857  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2858    {
2859      /* Cfront-style parameterized type.  Handled later as a signature. */
2860      success = 1;
2861
2862      /* ARM template? */
2863      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2864    }
2865  else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2866                              || (scan[2] == 'p' && scan[3] == 's')
2867                              || (scan[2] == 'p' && scan[3] == 't')))
2868    {
2869      /* EDG-style parameterized type.  Handled later as a signature. */
2870      success = 1;
2871
2872      /* EDG template? */
2873      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2874    }
2875  else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2876	   && (scan[2] != 't'))
2877    {
2878      /* Mangled name starts with "__".  Skip over any leading '_' characters,
2879	 then find the next "__" that separates the prefix from the signature.
2880	 */
2881      if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2882	  || (arm_special (mangled, declp) == 0))
2883	{
2884	  while (*scan == '_')
2885	    {
2886	      scan++;
2887	    }
2888	  if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2889	    {
2890	      /* No separator (I.E. "__not_mangled"), or empty signature
2891		 (I.E. "__not_mangled_either__") */
2892	      success = 0;
2893	    }
2894	  else
2895	    return iterate_demangle_function (work, mangled, declp, scan);
2896	}
2897    }
2898  else if (*(scan + 2) != '\0')
2899    {
2900      /* Mangled name does not start with "__" but does have one somewhere
2901	 in there with non empty stuff after it.  Looks like a global
2902	 function name.  Iterate over all "__":s until the right
2903	 one is found.  */
2904      return iterate_demangle_function (work, mangled, declp, scan);
2905    }
2906  else
2907    {
2908      /* Doesn't look like a mangled name */
2909      success = 0;
2910    }
2911
2912  if (!success && (work->constructor == 2 || work->destructor == 2))
2913    {
2914      string_append (declp, *mangled);
2915      *mangled += strlen (*mangled);
2916      success = 1;
2917    }
2918  return (success);
2919}
2920
2921/*
2922
2923LOCAL FUNCTION
2924
2925	gnu_special -- special handling of gnu mangled strings
2926
2927SYNOPSIS
2928
2929	static int
2930	gnu_special (struct work_stuff *work, const char **mangled,
2931		     string *declp);
2932
2933
2934DESCRIPTION
2935
2936	Process some special GNU style mangling forms that don't fit
2937	the normal pattern.  For example:
2938
2939		_$_3foo		(destructor for class foo)
2940		_vt$foo		(foo virtual table)
2941		_vt$foo$bar	(foo::bar virtual table)
2942		__vt_foo	(foo virtual table, new style with thunks)
2943		_3foo$varname	(static data member)
2944		_Q22rs2tu$vw	(static data member)
2945		__t6vector1Zii	(constructor with template)
2946		__thunk_4__$_7ostream (virtual function thunk)
2947 */
2948
2949static int
2950gnu_special (struct work_stuff *work, const char **mangled, string *declp)
2951{
2952  int n;
2953  int success = 1;
2954  const char *p;
2955
2956  if ((*mangled)[0] == '_'
2957      && strchr (cplus_markers, (*mangled)[1]) != NULL
2958      && (*mangled)[2] == '_')
2959    {
2960      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2961      (*mangled) += 3;
2962      work -> destructor += 1;
2963    }
2964  else if ((*mangled)[0] == '_'
2965	   && (((*mangled)[1] == '_'
2966		&& (*mangled)[2] == 'v'
2967		&& (*mangled)[3] == 't'
2968		&& (*mangled)[4] == '_')
2969	       || ((*mangled)[1] == 'v'
2970		   && (*mangled)[2] == 't'
2971		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2972    {
2973      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2974         and create the decl.  Note that we consume the entire mangled
2975	 input string, which means that demangle_signature has no work
2976	 to do.  */
2977      if ((*mangled)[2] == 'v')
2978	(*mangled) += 5; /* New style, with thunks: "__vt_" */
2979      else
2980	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2981      while (**mangled != '\0')
2982	{
2983	  switch (**mangled)
2984	    {
2985	    case 'Q':
2986	    case 'K':
2987	      success = demangle_qualified (work, mangled, declp, 0, 1);
2988	      break;
2989	    case 't':
2990	      success = demangle_template (work, mangled, declp, 0, 1,
2991					   1);
2992	      break;
2993	    default:
2994	      if (ISDIGIT((unsigned char)*mangled[0]))
2995		{
2996		  n = consume_count(mangled);
2997		  /* We may be seeing a too-large size, or else a
2998		     ".<digits>" indicating a static local symbol.  In
2999		     any case, declare victory and move on; *don't* try
3000		     to use n to allocate.  */
3001		  if (n > (int) strlen (*mangled))
3002		    {
3003		      success = 1;
3004		      break;
3005		    }
3006		}
3007	      else
3008		{
3009		  n = strcspn (*mangled, cplus_markers);
3010		}
3011	      string_appendn (declp, *mangled, n);
3012	      (*mangled) += n;
3013	    }
3014
3015	  p = strpbrk (*mangled, cplus_markers);
3016	  if (success && ((p == NULL) || (p == *mangled)))
3017	    {
3018	      if (p != NULL)
3019		{
3020		  string_append (declp, SCOPE_STRING (work));
3021		  (*mangled)++;
3022		}
3023	    }
3024	  else
3025	    {
3026	      success = 0;
3027	      break;
3028	    }
3029	}
3030      if (success)
3031	string_append (declp, " virtual table");
3032    }
3033  else if ((*mangled)[0] == '_'
3034	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
3035	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
3036    {
3037      /* static data member, "_3foo$varname" for example */
3038      (*mangled)++;
3039      switch (**mangled)
3040	{
3041	case 'Q':
3042	case 'K':
3043	  success = demangle_qualified (work, mangled, declp, 0, 1);
3044	  break;
3045	case 't':
3046	  success = demangle_template (work, mangled, declp, 0, 1, 1);
3047	  break;
3048	default:
3049	  n = consume_count (mangled);
3050	  if (n < 0 || n > (long) strlen (*mangled))
3051	    {
3052	      success = 0;
3053	      break;
3054	    }
3055
3056	  if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
3057	      && (*mangled)[9] == 'N'
3058	      && (*mangled)[8] == (*mangled)[10]
3059	      && strchr (cplus_markers, (*mangled)[8]))
3060	    {
3061	      /* A member of the anonymous namespace.  There's information
3062		 about what identifier or filename it was keyed to, but
3063		 it's just there to make the mangled name unique; we just
3064		 step over it.  */
3065	      string_append (declp, "{anonymous}");
3066	      (*mangled) += n;
3067
3068	      /* Now p points to the marker before the N, so we need to
3069		 update it to the first marker after what we consumed.  */
3070	      p = strpbrk (*mangled, cplus_markers);
3071	      break;
3072	    }
3073
3074	  string_appendn (declp, *mangled, n);
3075	  (*mangled) += n;
3076	}
3077      if (success && (p == *mangled))
3078	{
3079	  /* Consumed everything up to the cplus_marker, append the
3080	     variable name.  */
3081	  (*mangled)++;
3082	  string_append (declp, SCOPE_STRING (work));
3083	  n = strlen (*mangled);
3084	  string_appendn (declp, *mangled, n);
3085	  (*mangled) += n;
3086	}
3087      else
3088	{
3089	  success = 0;
3090	}
3091    }
3092  else if (strncmp (*mangled, "__thunk_", 8) == 0)
3093    {
3094      int delta;
3095
3096      (*mangled) += 8;
3097      delta = consume_count (mangled);
3098      if (delta == -1)
3099	success = 0;
3100      else
3101	{
3102	  char *method = internal_cplus_demangle (work, ++*mangled);
3103
3104	  if (method)
3105	    {
3106	      char buf[50];
3107	      sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3108	      string_append (declp, buf);
3109	      string_append (declp, method);
3110	      free (method);
3111	      n = strlen (*mangled);
3112	      (*mangled) += n;
3113	    }
3114	  else
3115	    {
3116	      success = 0;
3117	    }
3118	}
3119    }
3120  else if (strncmp (*mangled, "__t", 3) == 0
3121	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3122    {
3123      p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3124      (*mangled) += 4;
3125      switch (**mangled)
3126	{
3127	case 'Q':
3128	case 'K':
3129	  success = demangle_qualified (work, mangled, declp, 0, 1);
3130	  break;
3131	case 't':
3132	  success = demangle_template (work, mangled, declp, 0, 1, 1);
3133	  break;
3134	default:
3135	  success = do_type (work, mangled, declp);
3136	  break;
3137	}
3138      if (success && **mangled != '\0')
3139	success = 0;
3140      if (success)
3141	string_append (declp, p);
3142    }
3143  else
3144    {
3145      success = 0;
3146    }
3147  return (success);
3148}
3149
3150static void
3151recursively_demangle(struct work_stuff *work, const char **mangled,
3152                     string *result, int namelength)
3153{
3154  char * recurse = (char *)NULL;
3155  char * recurse_dem = (char *)NULL;
3156
3157  recurse = XNEWVEC (char, namelength + 1);
3158  memcpy (recurse, *mangled, namelength);
3159  recurse[namelength] = '\000';
3160
3161  recurse_dem = ML_(cplus_demangle) (recurse, work->options);
3162
3163  if (recurse_dem)
3164    {
3165      string_append (result, recurse_dem);
3166      free (recurse_dem);
3167    }
3168  else
3169    {
3170      string_appendn (result, *mangled, namelength);
3171    }
3172  free (recurse);
3173  *mangled += namelength;
3174}
3175
3176/*
3177
3178LOCAL FUNCTION
3179
3180	arm_special -- special handling of ARM/lucid mangled strings
3181
3182SYNOPSIS
3183
3184	static int
3185	arm_special (const char **mangled,
3186		     string *declp);
3187
3188
3189DESCRIPTION
3190
3191	Process some special ARM style mangling forms that don't fit
3192	the normal pattern.  For example:
3193
3194		__vtbl__3foo		(foo virtual table)
3195		__vtbl__3foo__3bar	(bar::foo virtual table)
3196
3197 */
3198
3199static int
3200arm_special (const char **mangled, string *declp)
3201{
3202  int n;
3203  int success = 1;
3204  const char *scan;
3205
3206  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3207    {
3208      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3209         and create the decl.  Note that we consume the entire mangled
3210	 input string, which means that demangle_signature has no work
3211	 to do.  */
3212      scan = *mangled + ARM_VTABLE_STRLEN;
3213      while (*scan != '\0')        /* first check it can be demangled */
3214        {
3215          n = consume_count (&scan);
3216          if (n == -1)
3217	    {
3218	      return (0);           /* no good */
3219	    }
3220          scan += n;
3221          if (scan[0] == '_' && scan[1] == '_')
3222	    {
3223	      scan += 2;
3224	    }
3225        }
3226      (*mangled) += ARM_VTABLE_STRLEN;
3227      while (**mangled != '\0')
3228	{
3229	  n = consume_count (mangled);
3230          if (n == -1
3231	      || n > (long) strlen (*mangled))
3232	    return 0;
3233	  string_prependn (declp, *mangled, n);
3234	  (*mangled) += n;
3235	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3236	    {
3237	      string_prepend (declp, "::");
3238	      (*mangled) += 2;
3239	    }
3240	}
3241      string_append (declp, " virtual table");
3242    }
3243  else
3244    {
3245      success = 0;
3246    }
3247  return (success);
3248}
3249
3250/*
3251
3252LOCAL FUNCTION
3253
3254	demangle_qualified -- demangle 'Q' qualified name strings
3255
3256SYNOPSIS
3257
3258	static int
3259	demangle_qualified (struct work_stuff *, const char *mangled,
3260			    string *result, int isfuncname, int append);
3261
3262DESCRIPTION
3263
3264	Demangle a qualified name, such as "Q25Outer5Inner" which is
3265	the mangled form of "Outer::Inner".  The demangled output is
3266	prepended or appended to the result string according to the
3267	state of the append flag.
3268
3269	If isfuncname is nonzero, then the qualified name we are building
3270	is going to be used as a member function name, so if it is a
3271	constructor or destructor function, append an appropriate
3272	constructor or destructor name.  I.E. for the above example,
3273	the result for use as a constructor is "Outer::Inner::Inner"
3274	and the result for use as a destructor is "Outer::Inner::~Inner".
3275
3276BUGS
3277
3278	Numeric conversion is ASCII dependent (FIXME).
3279
3280 */
3281
3282static int
3283demangle_qualified (struct work_stuff *work, const char **mangled,
3284                    string *result, int isfuncname, int append)
3285{
3286  int qualifiers = 0;
3287  int success = 1;
3288  char num[2];
3289  string temp;
3290  string last_name;
3291  int bindex = register_Btype (work);
3292
3293  /* We only make use of ISFUNCNAME if the entity is a constructor or
3294     destructor.  */
3295  isfuncname = (isfuncname
3296		&& ((work->constructor & 1) || (work->destructor & 1)));
3297
3298  string_init (&temp);
3299  string_init (&last_name);
3300
3301  if ((*mangled)[0] == 'K')
3302    {
3303    /* Squangling qualified name reuse */
3304      int idx;
3305      (*mangled)++;
3306      idx = consume_count_with_underscores (mangled);
3307      if (idx == -1 || idx >= work -> numk)
3308        success = 0;
3309      else
3310        string_append (&temp, work -> ktypevec[idx]);
3311    }
3312  else
3313    switch ((*mangled)[1])
3314    {
3315    case '_':
3316      /* GNU mangled name with more than 9 classes.  The count is preceded
3317	 by an underscore (to distinguish it from the <= 9 case) and followed
3318	 by an underscore.  */
3319      (*mangled)++;
3320      qualifiers = consume_count_with_underscores (mangled);
3321      if (qualifiers == -1)
3322	success = 0;
3323      break;
3324
3325    case '1':
3326    case '2':
3327    case '3':
3328    case '4':
3329    case '5':
3330    case '6':
3331    case '7':
3332    case '8':
3333    case '9':
3334      /* The count is in a single digit.  */
3335      num[0] = (*mangled)[1];
3336      num[1] = '\0';
3337      qualifiers = atoi (num);
3338
3339      /* If there is an underscore after the digit, skip it.  This is
3340	 said to be for ARM-qualified names, but the ARM makes no
3341	 mention of such an underscore.  Perhaps cfront uses one.  */
3342      if ((*mangled)[2] == '_')
3343	{
3344	  (*mangled)++;
3345	}
3346      (*mangled) += 2;
3347      break;
3348
3349    case '0':
3350    default:
3351      success = 0;
3352    }
3353
3354  if (!success)
3355    return success;
3356
3357  /* Pick off the names and collect them in the temp buffer in the order
3358     in which they are found, separated by '::'.  */
3359
3360  while (qualifiers-- > 0)
3361    {
3362      int remember_K = 1;
3363      string_clear (&last_name);
3364
3365      if (*mangled[0] == '_')
3366	(*mangled)++;
3367
3368      if (*mangled[0] == 't')
3369	{
3370	  /* Here we always append to TEMP since we will want to use
3371	     the template name without the template parameters as a
3372	     constructor or destructor name.  The appropriate
3373	     (parameter-less) value is returned by demangle_template
3374	     in LAST_NAME.  We do not remember the template type here,
3375	     in order to match the G++ mangling algorithm.  */
3376	  success = demangle_template(work, mangled, &temp,
3377				      &last_name, 1, 0);
3378	  if (!success)
3379	    break;
3380	}
3381      else if (*mangled[0] == 'K')
3382	{
3383          int idx;
3384          (*mangled)++;
3385          idx = consume_count_with_underscores (mangled);
3386          if (idx == -1 || idx >= work->numk)
3387            success = 0;
3388          else
3389            string_append (&temp, work->ktypevec[idx]);
3390          remember_K = 0;
3391
3392	  if (!success) break;
3393	}
3394      else
3395	{
3396	  if (EDG_DEMANGLING)
3397            {
3398	      int namelength;
3399 	      /* Now recursively demangle the qualifier
3400 	       * This is necessary to deal with templates in
3401 	       * mangling styles like EDG */
3402	      namelength = consume_count (mangled);
3403	      if (namelength == -1)
3404		{
3405		  success = 0;
3406		  break;
3407		}
3408 	      recursively_demangle(work, mangled, &temp, namelength);
3409            }
3410          else
3411            {
3412              string_delete (&last_name);
3413              success = do_type (work, mangled, &last_name);
3414              if (!success)
3415                break;
3416              string_appends (&temp, &last_name);
3417            }
3418	}
3419
3420      if (remember_K)
3421	remember_Ktype (work, temp.b, LEN_STRING (&temp));
3422
3423      if (qualifiers > 0)
3424	string_append (&temp, SCOPE_STRING (work));
3425    }
3426
3427  remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3428
3429  /* If we are using the result as a function name, we need to append
3430     the appropriate '::' separated constructor or destructor name.
3431     We do this here because this is the most convenient place, where
3432     we already have a pointer to the name and the length of the name.  */
3433
3434  if (isfuncname)
3435    {
3436      string_append (&temp, SCOPE_STRING (work));
3437      if (work -> destructor & 1)
3438	string_append (&temp, "~");
3439      string_appends (&temp, &last_name);
3440    }
3441
3442  /* Now either prepend the temp buffer to the result, or append it,
3443     depending upon the state of the append flag.  */
3444
3445  if (append)
3446    string_appends (result, &temp);
3447  else
3448    {
3449      if (!STRING_EMPTY (result))
3450	string_append (&temp, SCOPE_STRING (work));
3451      string_prepends (result, &temp);
3452    }
3453
3454  string_delete (&last_name);
3455  string_delete (&temp);
3456  return (success);
3457}
3458
3459/*
3460
3461LOCAL FUNCTION
3462
3463	get_count -- convert an ascii count to integer, consuming tokens
3464
3465SYNOPSIS
3466
3467	static int
3468	get_count (const char **type, int *count)
3469
3470DESCRIPTION
3471
3472	Assume that *type points at a count in a mangled name; set
3473	*count to its value, and set *type to the next character after
3474	the count.  There are some weird rules in effect here.
3475
3476	If *type does not point at a string of digits, return zero.
3477
3478	If *type points at a string of digits followed by an
3479	underscore, set *count to their value as an integer, advance
3480	*type to point *after the underscore, and return 1.
3481
3482	If *type points at a string of digits not followed by an
3483	underscore, consume only the first digit.  Set *count to its
3484	value as an integer, leave *type pointing after that digit,
3485	and return 1.
3486
3487        The excuse for this odd behavior: in the ARM and HP demangling
3488        styles, a type can be followed by a repeat count of the form
3489        `Nxy', where:
3490
3491        `x' is a single digit specifying how many additional copies
3492            of the type to append to the argument list, and
3493
3494        `y' is one or more digits, specifying the zero-based index of
3495            the first repeated argument in the list.  Yes, as you're
3496            unmangling the name you can figure this out yourself, but
3497            it's there anyway.
3498
3499        So, for example, in `bar__3fooFPiN51', the first argument is a
3500        pointer to an integer (`Pi'), and then the next five arguments
3501        are the same (`N5'), and the first repeat is the function's
3502        second argument (`1').
3503*/
3504
3505static int
3506get_count (const char **type, int *count)
3507{
3508  const char *p;
3509  int n;
3510
3511  if (!ISDIGIT ((unsigned char)**type))
3512    return (0);
3513  else
3514    {
3515      *count = **type - '0';
3516      (*type)++;
3517      if (ISDIGIT ((unsigned char)**type))
3518	{
3519	  p = *type;
3520	  n = *count;
3521	  do
3522	    {
3523	      n *= 10;
3524	      n += *p - '0';
3525	      p++;
3526	    }
3527	  while (ISDIGIT ((unsigned char)*p));
3528	  if (*p == '_')
3529	    {
3530	      *type = p + 1;
3531	      *count = n;
3532	    }
3533	}
3534    }
3535  return (1);
3536}
3537
3538/* RESULT will be initialised here; it will be freed on failure.  The
3539   value returned is really a type_kind_t.  */
3540
3541static int
3542do_type (struct work_stuff *work, const char **mangled, string *result)
3543{
3544  int n;
3545  int done;
3546  int success;
3547  string decl;
3548  const char *remembered_type;
3549  int type_quals;
3550  type_kind_t tk = tk_none;
3551
3552  string_init (&decl);
3553  string_init (result);
3554
3555  done = 0;
3556  success = 1;
3557  while (success && !done)
3558    {
3559      int member;
3560      switch (**mangled)
3561	{
3562
3563	  /* A pointer type */
3564	case 'P':
3565	case 'p':
3566	  (*mangled)++;
3567	  if (! (work -> options & DMGL_JAVA))
3568	    string_prepend (&decl, "*");
3569	  if (tk == tk_none)
3570	    tk = tk_pointer;
3571	  break;
3572
3573	  /* A reference type */
3574	case 'R':
3575	  (*mangled)++;
3576	  string_prepend (&decl, "&");
3577	  if (tk == tk_none)
3578	    tk = tk_reference;
3579	  break;
3580
3581	  /* An array */
3582	case 'A':
3583	  {
3584	    ++(*mangled);
3585	    if (!STRING_EMPTY (&decl)
3586		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3587	      {
3588		string_prepend (&decl, "(");
3589		string_append (&decl, ")");
3590	      }
3591	    string_append (&decl, "[");
3592	    if (**mangled != '_')
3593	      success = demangle_template_value_parm (work, mangled, &decl,
3594						      tk_integral);
3595	    if (**mangled == '_')
3596	      ++(*mangled);
3597	    string_append (&decl, "]");
3598	    break;
3599	  }
3600
3601	/* A back reference to a previously seen type */
3602	case 'T':
3603	  (*mangled)++;
3604	  if (!get_count (mangled, &n) || n >= work -> ntypes)
3605	    {
3606	      success = 0;
3607	    }
3608	  else
3609	    {
3610	      remembered_type = work -> typevec[n];
3611	      mangled = &remembered_type;
3612	    }
3613	  break;
3614
3615	  /* A function */
3616	case 'F':
3617	  (*mangled)++;
3618	    if (!STRING_EMPTY (&decl)
3619		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3620	    {
3621	      string_prepend (&decl, "(");
3622	      string_append (&decl, ")");
3623	    }
3624	  /* After picking off the function args, we expect to either find the
3625	     function return type (preceded by an '_') or the end of the
3626	     string.  */
3627	  if (!demangle_nested_args (work, mangled, &decl)
3628	      || (**mangled != '_' && **mangled != '\0'))
3629	    {
3630	      success = 0;
3631	      break;
3632	    }
3633	  if (success && (**mangled == '_'))
3634	    (*mangled)++;
3635	  break;
3636
3637	case 'M':
3638	case 'O':
3639	  {
3640	    type_quals = TYPE_UNQUALIFIED;
3641
3642	    member = **mangled == 'M';
3643	    (*mangled)++;
3644
3645	    string_append (&decl, ")");
3646
3647	    /* We don't need to prepend `::' for a qualified name;
3648	       demangle_qualified will do that for us.  */
3649	    if (**mangled != 'Q')
3650	      string_prepend (&decl, SCOPE_STRING (work));
3651
3652	    if (ISDIGIT ((unsigned char)**mangled))
3653	      {
3654		n = consume_count (mangled);
3655		if (n == -1
3656		    || (int) strlen (*mangled) < n)
3657		  {
3658		    success = 0;
3659		    break;
3660		  }
3661		string_prependn (&decl, *mangled, n);
3662		*mangled += n;
3663	      }
3664	    else if (**mangled == 'X' || **mangled == 'Y')
3665	      {
3666		string temp;
3667		do_type (work, mangled, &temp);
3668		string_prepends (&decl, &temp);
3669		string_delete (&temp);
3670	      }
3671	    else if (**mangled == 't')
3672	      {
3673		string temp;
3674		string_init (&temp);
3675		success = demangle_template (work, mangled, &temp,
3676					     NULL, 1, 1);
3677		if (success)
3678		  {
3679		    string_prependn (&decl, temp.b, temp.p - temp.b);
3680		    string_delete (&temp);
3681		  }
3682		else
3683		  {
3684		    string_delete (&temp);
3685		    break;
3686		  }
3687	      }
3688	    else if (**mangled == 'Q')
3689	      {
3690		success = demangle_qualified (work, mangled, &decl,
3691					      /*isfuncnam=*/0,
3692					      /*append=*/0);
3693		if (!success)
3694		  break;
3695	      }
3696	    else
3697	      {
3698		success = 0;
3699		break;
3700	      }
3701
3702	    string_prepend (&decl, "(");
3703	    if (member)
3704	      {
3705		switch (**mangled)
3706		  {
3707		  case 'C':
3708		  case 'V':
3709		  case 'u':
3710		    type_quals |= code_for_qualifier (**mangled);
3711		    (*mangled)++;
3712		    break;
3713
3714		  default:
3715		    break;
3716		  }
3717
3718		if (*(*mangled)++ != 'F')
3719		  {
3720		    success = 0;
3721		    break;
3722		  }
3723	      }
3724	    if ((member && !demangle_nested_args (work, mangled, &decl))
3725		|| **mangled != '_')
3726	      {
3727		success = 0;
3728		break;
3729	      }
3730	    (*mangled)++;
3731	    if (! PRINT_ANSI_QUALIFIERS)
3732	      {
3733		break;
3734	      }
3735	    if (type_quals != TYPE_UNQUALIFIED)
3736	      {
3737		APPEND_BLANK (&decl);
3738		string_append (&decl, qualifier_string (type_quals));
3739	      }
3740	    break;
3741	  }
3742        case 'G':
3743	  (*mangled)++;
3744	  break;
3745
3746	case 'C':
3747	case 'V':
3748	case 'u':
3749	  if (PRINT_ANSI_QUALIFIERS)
3750	    {
3751	      if (!STRING_EMPTY (&decl))
3752		string_prepend (&decl, " ");
3753
3754	      string_prepend (&decl, demangle_qualifier (**mangled));
3755	    }
3756	  (*mangled)++;
3757	  break;
3758	  /*
3759	    }
3760	    */
3761
3762	  /* fall through */
3763	default:
3764	  done = 1;
3765	  break;
3766	}
3767    }
3768
3769  if (success) switch (**mangled)
3770    {
3771      /* A qualified name, such as "Outer::Inner".  */
3772    case 'Q':
3773    case 'K':
3774      {
3775        success = demangle_qualified (work, mangled, result, 0, 1);
3776        break;
3777      }
3778
3779    /* A back reference to a previously seen squangled type */
3780    case 'B':
3781      (*mangled)++;
3782      if (!get_count (mangled, &n) || n >= work -> numb)
3783	success = 0;
3784      else
3785	string_append (result, work->btypevec[n]);
3786      break;
3787
3788    case 'X':
3789    case 'Y':
3790      /* A template parm.  We substitute the corresponding argument. */
3791      {
3792	int idx;
3793
3794	(*mangled)++;
3795	idx = consume_count_with_underscores (mangled);
3796
3797	if (idx == -1
3798	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
3799	    || consume_count_with_underscores (mangled) == -1)
3800	  {
3801	    success = 0;
3802	    break;
3803	  }
3804
3805	if (work->tmpl_argvec)
3806	  string_append (result, work->tmpl_argvec[idx]);
3807	else
3808	  string_append_template_idx (result, idx);
3809
3810	success = 1;
3811      }
3812    break;
3813
3814    default:
3815      success = demangle_fund_type (work, mangled, result);
3816      if (tk == tk_none)
3817	tk = (type_kind_t) success;
3818      break;
3819    }
3820
3821  if (success)
3822    {
3823      if (!STRING_EMPTY (&decl))
3824	{
3825	  string_append (result, " ");
3826	  string_appends (result, &decl);
3827	}
3828    }
3829  else
3830    string_delete (result);
3831  string_delete (&decl);
3832
3833  if (success)
3834    /* Assume an integral type, if we're not sure.  */
3835    return (int) ((tk == tk_none) ? tk_integral : tk);
3836  else
3837    return 0;
3838}
3839
3840/* Given a pointer to a type string that represents a fundamental type
3841   argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3842   string in which the demangled output is being built in RESULT, and
3843   the WORK structure, decode the types and add them to the result.
3844
3845   For example:
3846
3847   	"Ci"	=>	"const int"
3848	"Sl"	=>	"signed long"
3849	"CUs"	=>	"const unsigned short"
3850
3851   The value returned is really a type_kind_t.  */
3852
3853static int
3854demangle_fund_type (struct work_stuff *work,
3855                    const char **mangled, string *result)
3856{
3857  int done = 0;
3858  int success = 1;
3859  char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3860  /* unsigned int dec = 0; */ /* JRS 2008-Oct-26: unused (see below) */
3861  type_kind_t tk = tk_integral;
3862
3863  /* First pick off any type qualifiers.  There can be more than one.  */
3864
3865  while (!done)
3866    {
3867      switch (**mangled)
3868	{
3869	case 'C':
3870	case 'V':
3871	case 'u':
3872	  if (PRINT_ANSI_QUALIFIERS)
3873	    {
3874              if (!STRING_EMPTY (result))
3875                string_prepend (result, " ");
3876	      string_prepend (result, demangle_qualifier (**mangled));
3877	    }
3878	  (*mangled)++;
3879	  break;
3880	case 'U':
3881	  (*mangled)++;
3882	  APPEND_BLANK (result);
3883	  string_append (result, "unsigned");
3884	  break;
3885	case 'S': /* signed char only */
3886	  (*mangled)++;
3887	  APPEND_BLANK (result);
3888	  string_append (result, "signed");
3889	  break;
3890	case 'J':
3891	  (*mangled)++;
3892	  APPEND_BLANK (result);
3893	  string_append (result, "__complex");
3894	  break;
3895	default:
3896	  done = 1;
3897	  break;
3898	}
3899    }
3900
3901  /* Now pick off the fundamental type.  There can be only one.  */
3902
3903  switch (**mangled)
3904    {
3905    case '\0':
3906    case '_':
3907      break;
3908    case 'v':
3909      (*mangled)++;
3910      APPEND_BLANK (result);
3911      string_append (result, "void");
3912      break;
3913    case 'x':
3914      (*mangled)++;
3915      APPEND_BLANK (result);
3916      string_append (result, "long long");
3917      break;
3918    case 'l':
3919      (*mangled)++;
3920      APPEND_BLANK (result);
3921      string_append (result, "long");
3922      break;
3923    case 'i':
3924      (*mangled)++;
3925      APPEND_BLANK (result);
3926      string_append (result, "int");
3927      break;
3928    case 's':
3929      (*mangled)++;
3930      APPEND_BLANK (result);
3931      string_append (result, "short");
3932      break;
3933    case 'b':
3934      (*mangled)++;
3935      APPEND_BLANK (result);
3936      string_append (result, "bool");
3937      tk = tk_bool;
3938      break;
3939    case 'c':
3940      (*mangled)++;
3941      APPEND_BLANK (result);
3942      string_append (result, "char");
3943      tk = tk_char;
3944      break;
3945    case 'w':
3946      (*mangled)++;
3947      APPEND_BLANK (result);
3948      string_append (result, "wchar_t");
3949      tk = tk_char;
3950      break;
3951    case 'r':
3952      (*mangled)++;
3953      APPEND_BLANK (result);
3954      string_append (result, "long double");
3955      tk = tk_real;
3956      break;
3957    case 'd':
3958      (*mangled)++;
3959      APPEND_BLANK (result);
3960      string_append (result, "double");
3961      tk = tk_real;
3962      break;
3963    case 'f':
3964      (*mangled)++;
3965      APPEND_BLANK (result);
3966      string_append (result, "float");
3967      tk = tk_real;
3968      break;
3969    case 'G':
3970      (*mangled)++;
3971      if (!ISDIGIT ((unsigned char)**mangled))
3972	{
3973	  success = 0;
3974	  break;
3975	}
3976    case 'I':
3977      (*mangled)++;
3978      if (**mangled == '_')
3979	{
3980	  int i;
3981	  (*mangled)++;
3982	  for (i = 0;
3983	       i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3984	       (*mangled)++, i++)
3985	    buf[i] = **mangled;
3986	  if (**mangled != '_')
3987	    {
3988	      success = 0;
3989	      break;
3990	    }
3991	  buf[i] = '\0';
3992	  (*mangled)++;
3993	}
3994      else
3995	{
3996	  strncpy (buf, *mangled, 2);
3997	  buf[2] = '\0';
3998	  *mangled += min (strlen (*mangled), 2);
3999	}
4000      /* JRS 2008-Oct-26: the next two commented out lines have been
4001         replaced by the sprintf that follows.  This is to avoid use
4002         of sscanf.  This hack is merely copied from the old demangler
4003         port (by Michael Matz, Simon Hausmann?) -- I have no idea if
4004         it is really correct/safe, but it looks ok. */
4005      /*sscanf (buf, "%x", &dec);
4006      sprintf (buf, "int%u_t", dec);*/
4007      sprintf (buf, "%s", "intXX_t");
4008      /* end JRS 2008-Oct-26 */
4009      APPEND_BLANK (result);
4010      string_append (result, buf);
4011      break;
4012
4013      /* fall through */
4014      /* An explicit type, such as "6mytype" or "7integer" */
4015    case '0':
4016    case '1':
4017    case '2':
4018    case '3':
4019    case '4':
4020    case '5':
4021    case '6':
4022    case '7':
4023    case '8':
4024    case '9':
4025      {
4026        int bindex = register_Btype (work);
4027        string btype;
4028        string_init (&btype);
4029        if (demangle_class_name (work, mangled, &btype)) {
4030          remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
4031          APPEND_BLANK (result);
4032          string_appends (result, &btype);
4033        }
4034        else
4035          success = 0;
4036        string_delete (&btype);
4037        break;
4038      }
4039    case 't':
4040      {
4041        string btype;
4042        string_init (&btype);
4043        success = demangle_template (work, mangled, &btype, 0, 1, 1);
4044        string_appends (result, &btype);
4045        string_delete (&btype);
4046        break;
4047      }
4048    default:
4049      success = 0;
4050      break;
4051    }
4052
4053  return success ? ((int) tk) : 0;
4054}
4055
4056
4057/* Handle a template's value parameter for HP aCC (extension from ARM)
4058   **mangled points to 'S' or 'U' */
4059
4060static int
4061do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
4062                               const char **mangled, string *result)
4063{
4064  int unsigned_const;
4065
4066  if (**mangled != 'U' && **mangled != 'S')
4067    return 0;
4068
4069  unsigned_const = (**mangled == 'U');
4070
4071  (*mangled)++;
4072
4073  switch (**mangled)
4074    {
4075      case 'N':
4076        string_append (result, "-");
4077        /* fall through */
4078      case 'P':
4079        (*mangled)++;
4080        break;
4081      case 'M':
4082        /* special case for -2^31 */
4083        string_append (result, "-2147483648");
4084        (*mangled)++;
4085        return 1;
4086      default:
4087        return 0;
4088    }
4089
4090  /* We have to be looking at an integer now */
4091  if (!(ISDIGIT ((unsigned char)**mangled)))
4092    return 0;
4093
4094  /* We only deal with integral values for template
4095     parameters -- so it's OK to look only for digits */
4096  while (ISDIGIT ((unsigned char)**mangled))
4097    {
4098      char_str[0] = **mangled;
4099      string_append (result, char_str);
4100      (*mangled)++;
4101    }
4102
4103  if (unsigned_const)
4104    string_append (result, "U");
4105
4106  /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4107     with L or LL suffixes. pai/1997-09-03 */
4108
4109  return 1; /* success */
4110}
4111
4112/* Handle a template's literal parameter for HP aCC (extension from ARM)
4113   **mangled is pointing to the 'A' */
4114
4115static int
4116do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
4117                           string *result)
4118{
4119  int literal_len = 0;
4120  char * recurse;
4121  char * recurse_dem;
4122
4123  if (**mangled != 'A')
4124    return 0;
4125
4126  (*mangled)++;
4127
4128  literal_len = consume_count (mangled);
4129
4130  if (literal_len <= 0)
4131    return 0;
4132
4133  /* Literal parameters are names of arrays, functions, etc.  and the
4134     canonical representation uses the address operator */
4135  string_append (result, "&");
4136
4137  /* Now recursively demangle the literal name */
4138  recurse = XNEWVEC (char, literal_len + 1);
4139  memcpy (recurse, *mangled, literal_len);
4140  recurse[literal_len] = '\000';
4141
4142  recurse_dem = ML_(cplus_demangle) (recurse, work->options);
4143
4144  if (recurse_dem)
4145    {
4146      string_append (result, recurse_dem);
4147      free (recurse_dem);
4148    }
4149  else
4150    {
4151      string_appendn (result, *mangled, literal_len);
4152    }
4153  (*mangled) += literal_len;
4154  free (recurse);
4155
4156  return 1;
4157}
4158
4159static int
4160snarf_numeric_literal (const char **args, string *arg)
4161{
4162  if (**args == '-')
4163    {
4164      char_str[0] = '-';
4165      string_append (arg, char_str);
4166      (*args)++;
4167    }
4168  else if (**args == '+')
4169    (*args)++;
4170
4171  if (!ISDIGIT ((unsigned char)**args))
4172    return 0;
4173
4174  while (ISDIGIT ((unsigned char)**args))
4175    {
4176      char_str[0] = **args;
4177      string_append (arg, char_str);
4178      (*args)++;
4179    }
4180
4181  return 1;
4182}
4183
4184/* Demangle the next argument, given by MANGLED into RESULT, which
4185   *should be an uninitialized* string.  It will be initialized here,
4186   and free'd should anything go wrong.  */
4187
4188static int
4189do_arg (struct work_stuff *work, const char **mangled, string *result)
4190{
4191  /* Remember where we started so that we can record the type, for
4192     non-squangling type remembering.  */
4193  const char *start = *mangled;
4194
4195  string_init (result);
4196
4197  if (work->nrepeats > 0)
4198    {
4199      --work->nrepeats;
4200
4201      if (work->previous_argument == 0)
4202	return 0;
4203
4204      /* We want to reissue the previous type in this argument list.  */
4205      string_appends (result, work->previous_argument);
4206      return 1;
4207    }
4208
4209  if (**mangled == 'n')
4210    {
4211      /* A squangling-style repeat.  */
4212      (*mangled)++;
4213      work->nrepeats = consume_count(mangled);
4214
4215      if (work->nrepeats <= 0)
4216	/* This was not a repeat count after all.  */
4217	return 0;
4218
4219      if (work->nrepeats > 9)
4220	{
4221	  if (**mangled != '_')
4222	    /* The repeat count should be followed by an '_' in this
4223	       case.  */
4224	    return 0;
4225	  else
4226	    (*mangled)++;
4227	}
4228
4229      /* Now, the repeat is all set up.  */
4230      return do_arg (work, mangled, result);
4231    }
4232
4233  /* Save the result in WORK->previous_argument so that we can find it
4234     if it's repeated.  Note that saving START is not good enough: we
4235     do not want to add additional types to the back-referenceable
4236     type vector when processing a repeated type.  */
4237  if (work->previous_argument)
4238    string_delete (work->previous_argument);
4239  else
4240    work->previous_argument = XNEW (string);
4241
4242  if (!do_type (work, mangled, work->previous_argument))
4243    return 0;
4244
4245  string_appends (result, work->previous_argument);
4246
4247  remember_type (work, start, *mangled - start);
4248  return 1;
4249}
4250
4251static void
4252remember_type (struct work_stuff *work, const char *start, int len)
4253{
4254  char *tem;
4255
4256  if (work->forgetting_types)
4257    return;
4258
4259  if (work -> ntypes >= work -> typevec_size)
4260    {
4261      if (work -> typevec_size == 0)
4262	{
4263	  work -> typevec_size = 3;
4264	  work -> typevec = XNEWVEC (char *, work->typevec_size);
4265	}
4266      else
4267	{
4268	  work -> typevec_size *= 2;
4269	  work -> typevec
4270	    = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4271	}
4272    }
4273  tem = XNEWVEC (char, len + 1);
4274  memcpy (tem, start, len);
4275  tem[len] = '\0';
4276  work -> typevec[work -> ntypes++] = tem;
4277}
4278
4279
4280/* Remember a K type class qualifier. */
4281static void
4282remember_Ktype (struct work_stuff *work, const char *start, int len)
4283{
4284  char *tem;
4285
4286  if (work -> numk >= work -> ksize)
4287    {
4288      if (work -> ksize == 0)
4289	{
4290	  work -> ksize = 5;
4291	  work -> ktypevec = XNEWVEC (char *, work->ksize);
4292	}
4293      else
4294	{
4295	  work -> ksize *= 2;
4296	  work -> ktypevec
4297	    = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4298	}
4299    }
4300  tem = XNEWVEC (char, len + 1);
4301  memcpy (tem, start, len);
4302  tem[len] = '\0';
4303  work -> ktypevec[work -> numk++] = tem;
4304}
4305
4306/* Register a B code, and get an index for it. B codes are registered
4307   as they are seen, rather than as they are completed, so map<temp<char> >
4308   registers map<temp<char> > as B0, and temp<char> as B1 */
4309
4310static int
4311register_Btype (struct work_stuff *work)
4312{
4313  int ret;
4314
4315  if (work -> numb >= work -> bsize)
4316    {
4317      if (work -> bsize == 0)
4318	{
4319	  work -> bsize = 5;
4320	  work -> btypevec = XNEWVEC (char *, work->bsize);
4321	}
4322      else
4323	{
4324	  work -> bsize *= 2;
4325	  work -> btypevec
4326	    = XRESIZEVEC (char *, work->btypevec, work->bsize);
4327	}
4328    }
4329  ret = work -> numb++;
4330  work -> btypevec[ret] = NULL;
4331  return(ret);
4332}
4333
4334/* Store a value into a previously registered B code type. */
4335
4336static void
4337remember_Btype (struct work_stuff *work, const char *start,
4338                int len, int indx)
4339{
4340  char *tem;
4341
4342  tem = XNEWVEC (char, len + 1);
4343  memcpy (tem, start, len);
4344  tem[len] = '\0';
4345  work -> btypevec[indx] = tem;
4346}
4347
4348/* Lose all the info related to B and K type codes. */
4349static void
4350forget_B_and_K_types (struct work_stuff *work)
4351{
4352  int i;
4353
4354  while (work -> numk > 0)
4355    {
4356      i = --(work -> numk);
4357      if (work -> ktypevec[i] != NULL)
4358	{
4359	  free (work -> ktypevec[i]);
4360	  work -> ktypevec[i] = NULL;
4361	}
4362    }
4363
4364  while (work -> numb > 0)
4365    {
4366      i = --(work -> numb);
4367      if (work -> btypevec[i] != NULL)
4368	{
4369	  free (work -> btypevec[i]);
4370	  work -> btypevec[i] = NULL;
4371	}
4372    }
4373}
4374/* Forget the remembered types, but not the type vector itself.  */
4375
4376static void
4377forget_types (struct work_stuff *work)
4378{
4379  int i;
4380
4381  while (work -> ntypes > 0)
4382    {
4383      i = --(work -> ntypes);
4384      if (work -> typevec[i] != NULL)
4385	{
4386	  free (work -> typevec[i]);
4387	  work -> typevec[i] = NULL;
4388	}
4389    }
4390}
4391
4392/* Process the argument list part of the signature, after any class spec
4393   has been consumed, as well as the first 'F' character (if any).  For
4394   example:
4395
4396   "__als__3fooRT0"		=>	process "RT0"
4397   "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
4398
4399   DECLP must be already initialised, usually non-empty.  It won't be freed
4400   on failure.
4401
4402   Note that g++ differs significantly from ARM and lucid style mangling
4403   with regards to references to previously seen types.  For example, given
4404   the source fragment:
4405
4406     class foo {
4407       public:
4408       foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4409     };
4410
4411     foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4412     void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4413
4414   g++ produces the names:
4415
4416     __3fooiRT0iT2iT2
4417     foo__FiR3fooiT1iT1
4418
4419   while lcc (and presumably other ARM style compilers as well) produces:
4420
4421     foo__FiR3fooT1T2T1T2
4422     __ct__3fooFiR3fooT1T2T1T2
4423
4424   Note that g++ bases its type numbers starting at zero and counts all
4425   previously seen types, while lucid/ARM bases its type numbers starting
4426   at one and only considers types after it has seen the 'F' character
4427   indicating the start of the function args.  For lucid/ARM style, we
4428   account for this difference by discarding any previously seen types when
4429   we see the 'F' character, and subtracting one from the type number
4430   reference.
4431
4432 */
4433
4434static int
4435demangle_args (struct work_stuff *work, const char **mangled,
4436               string *declp)
4437{
4438  string arg;
4439  int need_comma = 0;
4440  int r;
4441  int t;
4442  const char *tem;
4443  char temptype;
4444
4445  if (PRINT_ARG_TYPES)
4446    {
4447      string_append (declp, "(");
4448      if (**mangled == '\0')
4449	{
4450	  string_append (declp, "void");
4451	}
4452    }
4453
4454  while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4455	 || work->nrepeats > 0)
4456    {
4457      if ((**mangled == 'N') || (**mangled == 'T'))
4458	{
4459	  temptype = *(*mangled)++;
4460
4461	  if (temptype == 'N')
4462	    {
4463	      if (!get_count (mangled, &r))
4464		{
4465		  return (0);
4466		}
4467	    }
4468	  else
4469	    {
4470	      r = 1;
4471	    }
4472          if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4473            {
4474              /* If we have 10 or more types we might have more than a 1 digit
4475                 index so we'll have to consume the whole count here. This
4476                 will lose if the next thing is a type name preceded by a
4477                 count but it's impossible to demangle that case properly
4478                 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4479                 Pc, ...)"  or "(..., type12, char *, ...)" */
4480              if ((t = consume_count(mangled)) <= 0)
4481                {
4482                  return (0);
4483                }
4484            }
4485          else
4486	    {
4487	      if (!get_count (mangled, &t))
4488	    	{
4489	          return (0);
4490	    	}
4491	    }
4492	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4493	    {
4494	      t--;
4495	    }
4496	  /* Validate the type index.  Protect against illegal indices from
4497	     malformed type strings.  */
4498	  if ((t < 0) || (t >= work -> ntypes))
4499	    {
4500	      return (0);
4501	    }
4502	  while (work->nrepeats > 0 || --r >= 0)
4503	    {
4504	      tem = work -> typevec[t];
4505	      if (need_comma && PRINT_ARG_TYPES)
4506		{
4507		  string_append (declp, ", ");
4508		}
4509	      if (!do_arg (work, &tem, &arg))
4510		{
4511		  return (0);
4512		}
4513	      if (PRINT_ARG_TYPES)
4514		{
4515		  string_appends (declp, &arg);
4516		}
4517	      string_delete (&arg);
4518	      need_comma = 1;
4519	    }
4520	}
4521      else
4522	{
4523	  if (need_comma && PRINT_ARG_TYPES)
4524	    string_append (declp, ", ");
4525	  if (!do_arg (work, mangled, &arg))
4526	    return (0);
4527	  if (PRINT_ARG_TYPES)
4528	    string_appends (declp, &arg);
4529	  string_delete (&arg);
4530	  need_comma = 1;
4531	}
4532    }
4533
4534  if (**mangled == 'e')
4535    {
4536      (*mangled)++;
4537      if (PRINT_ARG_TYPES)
4538	{
4539	  if (need_comma)
4540	    {
4541	      string_append (declp, ",");
4542	    }
4543	  string_append (declp, "...");
4544	}
4545    }
4546
4547  if (PRINT_ARG_TYPES)
4548    {
4549      string_append (declp, ")");
4550    }
4551  return (1);
4552}
4553
4554/* Like demangle_args, but for demangling the argument lists of function
4555   and method pointers or references, not top-level declarations.  */
4556
4557static int
4558demangle_nested_args (struct work_stuff *work, const char **mangled,
4559                      string *declp)
4560{
4561  string* saved_previous_argument;
4562  int result;
4563  int saved_nrepeats;
4564
4565  /* The G++ name-mangling algorithm does not remember types on nested
4566     argument lists, unless -fsquangling is used, and in that case the
4567     type vector updated by remember_type is not used.  So, we turn
4568     off remembering of types here.  */
4569  ++work->forgetting_types;
4570
4571  /* For the repeat codes used with -fsquangling, we must keep track of
4572     the last argument.  */
4573  saved_previous_argument = work->previous_argument;
4574  saved_nrepeats = work->nrepeats;
4575  work->previous_argument = 0;
4576  work->nrepeats = 0;
4577
4578  /* Actually demangle the arguments.  */
4579  result = demangle_args (work, mangled, declp);
4580
4581  /* Restore the previous_argument field.  */
4582  if (work->previous_argument)
4583    {
4584      string_delete (work->previous_argument);
4585      free ((char *) work->previous_argument);
4586    }
4587  work->previous_argument = saved_previous_argument;
4588  --work->forgetting_types;
4589  work->nrepeats = saved_nrepeats;
4590
4591  return result;
4592}
4593
4594/* Returns 1 if a valid function name was found or 0 otherwise.  */
4595
4596static int
4597demangle_function_name (struct work_stuff *work, const char **mangled,
4598                        string *declp, const char *scan)
4599{
4600  size_t i;
4601  string type;
4602  const char *tem;
4603
4604  string_appendn (declp, (*mangled), scan - (*mangled));
4605  string_need (declp, 1);
4606  *(declp -> p) = '\0';
4607
4608  /* Consume the function name, including the "__" separating the name
4609     from the signature.  We are guaranteed that SCAN points to the
4610     separator.  */
4611
4612  (*mangled) = scan + 2;
4613  /* We may be looking at an instantiation of a template function:
4614     foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4615     following _F marks the start of the function arguments.  Handle
4616     the template arguments first. */
4617
4618  if (HP_DEMANGLING && (**mangled == 'X'))
4619    {
4620      demangle_arm_hp_template (work, mangled, 0, declp);
4621      /* This leaves MANGLED pointing to the 'F' marking func args */
4622    }
4623
4624  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4625    {
4626
4627      /* See if we have an ARM style constructor or destructor operator.
4628	 If so, then just record it, clear the decl, and return.
4629	 We can't build the actual constructor/destructor decl until later,
4630	 when we recover the class name from the signature.  */
4631
4632      if (strcmp (declp -> b, "__ct") == 0)
4633	{
4634	  work -> constructor += 1;
4635	  string_clear (declp);
4636	  return 1;
4637	}
4638      else if (strcmp (declp -> b, "__dt") == 0)
4639	{
4640	  work -> destructor += 1;
4641	  string_clear (declp);
4642	  return 1;
4643	}
4644    }
4645
4646  if (declp->p - declp->b >= 3
4647      && declp->b[0] == 'o'
4648      && declp->b[1] == 'p'
4649      && strchr (cplus_markers, declp->b[2]) != NULL)
4650    {
4651      /* see if it's an assignment expression */
4652      if (declp->p - declp->b >= 10 /* op$assign_ */
4653	  && memcmp (declp->b + 3, "assign_", 7) == 0)
4654	{
4655	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4656	    {
4657	      int len = declp->p - declp->b - 10;
4658	      if ((int) strlen (optable[i].in) == len
4659		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
4660		{
4661		  string_clear (declp);
4662		  string_append (declp, "operator");
4663		  string_append (declp, optable[i].out);
4664		  string_append (declp, "=");
4665		  break;
4666		}
4667	    }
4668	}
4669      else
4670	{
4671	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4672	    {
4673	      int len = declp->p - declp->b - 3;
4674	      if ((int) strlen (optable[i].in) == len
4675		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
4676		{
4677		  string_clear (declp);
4678		  string_append (declp, "operator");
4679		  string_append (declp, optable[i].out);
4680		  break;
4681		}
4682	    }
4683	}
4684    }
4685  else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4686	   && strchr (cplus_markers, declp->b[4]) != NULL)
4687    {
4688      /* type conversion operator */
4689      tem = declp->b + 5;
4690      if (do_type (work, &tem, &type))
4691	{
4692	  string_clear (declp);
4693	  string_append (declp, "operator ");
4694	  string_appends (declp, &type);
4695	  string_delete (&type);
4696	}
4697    }
4698  else if (declp->b[0] == '_' && declp->b[1] == '_'
4699	   && declp->b[2] == 'o' && declp->b[3] == 'p')
4700    {
4701      /* ANSI.  */
4702      /* type conversion operator.  */
4703      tem = declp->b + 4;
4704      if (do_type (work, &tem, &type))
4705	{
4706	  string_clear (declp);
4707	  string_append (declp, "operator ");
4708	  string_appends (declp, &type);
4709	  string_delete (&type);
4710	}
4711    }
4712  else if (declp->b[0] == '_' && declp->b[1] == '_'
4713	   && ISLOWER((unsigned char)declp->b[2])
4714	   && ISLOWER((unsigned char)declp->b[3]))
4715    {
4716      if (declp->b[4] == '\0')
4717	{
4718	  /* Operator.  */
4719	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4720	    {
4721	      if (strlen (optable[i].in) == 2
4722		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4723		{
4724		  string_clear (declp);
4725		  string_append (declp, "operator");
4726		  string_append (declp, optable[i].out);
4727		  break;
4728		}
4729	    }
4730	}
4731
4732      /* BEGIN hack inserted 20050403 by JRS to deal with apparently
4733         non-cfront compliant new[]/delete[] manglings generated by
4734         the Portland Group's C++ compiler. */
4735      else
4736      if (strcmp (declp -> b, "__nwa") == 0) {
4737         string_clear (declp);
4738         string_append (declp, "operator new[]");
4739      }
4740      else
4741      if (strcmp (declp -> b, "__dla") == 0) {
4742         string_clear (declp);
4743         string_append (declp, "operator delete[]");
4744      }
4745      /* END hack */
4746
4747      else
4748	{
4749	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
4750	    {
4751	      /* Assignment.  */
4752	      for (i = 0; i < ARRAY_SIZE (optable); i++)
4753		{
4754		  if (strlen (optable[i].in) == 3
4755		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4756		    {
4757		      string_clear (declp);
4758		      string_append (declp, "operator");
4759		      string_append (declp, optable[i].out);
4760		      break;
4761		    }
4762		}
4763	    }
4764	}
4765    }
4766
4767  /* If a function name was obtained but it's not valid, we were not
4768     successful.  */
4769  if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
4770    return 0;
4771  else
4772    return 1;
4773}
4774
4775/* a mini string-handling package */
4776
4777static void
4778string_need (string *s, int n)
4779{
4780  int tem;
4781
4782  if (s->b == NULL)
4783    {
4784      if (n < 32)
4785	{
4786	  n = 32;
4787	}
4788      s->p = s->b = XNEWVEC (char, n);
4789      s->e = s->b + n;
4790    }
4791  else if (s->e - s->p < n)
4792    {
4793      tem = s->p - s->b;
4794      n += tem;
4795      n *= 2;
4796      s->b = XRESIZEVEC (char, s->b, n);
4797      s->p = s->b + tem;
4798      s->e = s->b + n;
4799    }
4800}
4801
4802static void
4803string_delete (string *s)
4804{
4805  if (s->b != NULL)
4806    {
4807      free (s->b);
4808      s->b = s->e = s->p = NULL;
4809    }
4810}
4811
4812static void
4813string_init (string *s)
4814{
4815  s->b = s->p = s->e = NULL;
4816}
4817
4818static void
4819string_clear (string *s)
4820{
4821  s->p = s->b;
4822}
4823
4824#if 0
4825
4826static int
4827string_empty (string *s)
4828{
4829  return (s->b == s->p);
4830}
4831
4832#endif
4833
4834static void
4835string_append (string *p, const char *s)
4836{
4837  int n;
4838  if (s == NULL || *s == '\0')
4839    return;
4840  n = strlen (s);
4841  string_need (p, n);
4842  memcpy (p->p, s, n);
4843  p->p += n;
4844}
4845
4846static void
4847string_appends (string *p, string *s)
4848{
4849  int n;
4850
4851  if (s->b != s->p)
4852    {
4853      n = s->p - s->b;
4854      string_need (p, n);
4855      memcpy (p->p, s->b, n);
4856      p->p += n;
4857    }
4858}
4859
4860static void
4861string_appendn (string *p, const char *s, int n)
4862{
4863  if (n != 0)
4864    {
4865      string_need (p, n);
4866      memcpy (p->p, s, n);
4867      p->p += n;
4868    }
4869}
4870
4871static void
4872string_prepend (string *p, const char *s)
4873{
4874  if (s != NULL && *s != '\0')
4875    {
4876      string_prependn (p, s, strlen (s));
4877    }
4878}
4879
4880static void
4881string_prepends (string *p, string *s)
4882{
4883  if (s->b != s->p)
4884    {
4885      string_prependn (p, s->b, s->p - s->b);
4886    }
4887}
4888
4889static void
4890string_prependn (string *p, const char *s, int n)
4891{
4892  char *q;
4893
4894  if (n != 0)
4895    {
4896      string_need (p, n);
4897      for (q = p->p - 1; q >= p->b; q--)
4898	{
4899	  q[n] = q[0];
4900	}
4901      memcpy (p->b, s, n);
4902      p->p += n;
4903    }
4904}
4905
4906static void
4907string_append_template_idx (string *s, int idx)
4908{
4909  char buf[INTBUF_SIZE + 1 /* 'T' */];
4910  sprintf(buf, "T%d", idx);
4911  string_append (s, buf);
4912}
4913