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