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