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