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