cplus-dem.c revision 38889
1/* Demangler for GNU C++
2   Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
3   Written by James Clark (jjc@jclark.uucp)
4   Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
6This file is part of the libiberty library.
7Libiberty is free software; you can redistribute it and/or
8modify it under the terms of the GNU Library General Public
9License as published by the Free Software Foundation; either
10version 2 of the License, or (at your option) any later version.
11
12Libiberty is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15Library General Public License for more details.
16
17You should have received a copy of the GNU Library General Public
18License along with libiberty; see the file COPYING.LIB.  If
19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
23
24   This file imports xmalloc and xrealloc, which are like malloc and
25   realloc except that they generate a fatal error if there is no
26   available memory.  */
27
28/* This file lives in both GCC and libiberty.  When making changes, please
29   try not to break either.  */
30
31#include <ctype.h>
32#include <string.h>
33#include <stdio.h>
34
35#include <demangle.h>
36#undef CURRENT_DEMANGLING_STYLE
37#define CURRENT_DEMANGLING_STYLE work->options
38
39extern char *xmalloc PARAMS((unsigned));
40extern char *xrealloc PARAMS((char *, unsigned));
41
42static const char *mystrstr PARAMS ((const char *, const char *));
43
44static const char *
45mystrstr (s1, s2)
46     const char *s1, *s2;
47{
48  register const char *p = s1;
49  register int len = strlen (s2);
50
51  for (; (p = strchr (p, *s2)) != 0; p++)
52    {
53      if (strncmp (p, s2, len) == 0)
54	{
55	  return (p);
56	}
57    }
58  return (0);
59}
60
61/* In order to allow a single demangler executable to demangle strings
62   using various common values of CPLUS_MARKER, as well as any specific
63   one set at compile time, we maintain a string containing all the
64   commonly used ones, and check to see if the marker we are looking for
65   is in that string.  CPLUS_MARKER is usually '$' on systems where the
66   assembler can deal with that.  Where the assembler can't, it's usually
67   '.' (but on many systems '.' is used for other things).  We put the
68   current defined CPLUS_MARKER first (which defaults to '$'), followed
69   by the next most common value, followed by an explicit '$' in case
70   the value of CPLUS_MARKER is not '$'.
71
72   We could avoid this if we could just get g++ to tell us what the actual
73   cplus marker character is as part of the debug information, perhaps by
74   ensuring that it is the character that terminates the gcc<n>_compiled
75   marker symbol (FIXME).  */
76
77#if !defined (CPLUS_MARKER)
78#define CPLUS_MARKER '$'
79#endif
80
81enum demangling_styles current_demangling_style = gnu_demangling;
82
83static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
84
85void
86set_cplus_marker_for_demangling (ch)
87     int ch;
88{
89  cplus_markers[0] = ch;
90}
91
92/* Stuff that is shared between sub-routines.
93   Using a shared structure allows cplus_demangle to be reentrant.  */
94
95struct work_stuff
96{
97  int options;
98  char **typevec;
99  int ntypes;
100  int typevec_size;
101  int constructor;
102  int destructor;
103  int static_type;	/* A static member function */
104  int const_type;	/* A const member function */
105  char **tmpl_argvec;   /* Template function arguments. */
106  int ntmpl_args;       /* The number of template function arguments. */
107};
108
109#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110#define PRINT_ARG_TYPES       (work -> options & DMGL_PARAMS)
111
112static const struct optable
113{
114  const char *in;
115  const char *out;
116  int flags;
117} optable[] = {
118  {"nw",	  " new",	DMGL_ANSI},	/* new (1.92,	 ansi) */
119  {"dl",	  " delete",	DMGL_ANSI},	/* new (1.92,	 ansi) */
120  {"new",	  " new",	0},		/* old (1.91,	 and 1.x) */
121  {"delete",	  " delete",	0},		/* old (1.91,	 and 1.x) */
122  {"vn",	  " new []",	DMGL_ANSI},	/* GNU, pending ansi */
123  {"vd",	  " delete []",	DMGL_ANSI},	/* GNU, pending ansi */
124  {"as",	  "=",		DMGL_ANSI},	/* ansi */
125  {"ne",	  "!=",		DMGL_ANSI},	/* old, ansi */
126  {"eq",	  "==",		DMGL_ANSI},	/* old,	ansi */
127  {"ge",	  ">=",		DMGL_ANSI},	/* old,	ansi */
128  {"gt",	  ">",		DMGL_ANSI},	/* old,	ansi */
129  {"le",	  "<=",		DMGL_ANSI},	/* old,	ansi */
130  {"lt",	  "<",		DMGL_ANSI},	/* old,	ansi */
131  {"plus",	  "+",		0},		/* old */
132  {"pl",	  "+",		DMGL_ANSI},	/* ansi */
133  {"apl",	  "+=",		DMGL_ANSI},	/* ansi */
134  {"minus",	  "-",		0},		/* old */
135  {"mi",	  "-",		DMGL_ANSI},	/* ansi */
136  {"ami",	  "-=",		DMGL_ANSI},	/* ansi */
137  {"mult",	  "*",		0},		/* old */
138  {"ml",	  "*",		DMGL_ANSI},	/* ansi */
139  {"amu",	  "*=",		DMGL_ANSI},	/* ansi (ARM/Lucid) */
140  {"aml",	  "*=",		DMGL_ANSI},	/* ansi (GNU/g++) */
141  {"convert",	  "+",		0},		/* old (unary +) */
142  {"negate",	  "-",		0},		/* old (unary -) */
143  {"trunc_mod",	  "%",		0},		/* old */
144  {"md",	  "%",		DMGL_ANSI},	/* ansi */
145  {"amd",	  "%=",		DMGL_ANSI},	/* ansi */
146  {"trunc_div",	  "/",		0},		/* old */
147  {"dv",	  "/",		DMGL_ANSI},	/* ansi */
148  {"adv",	  "/=",		DMGL_ANSI},	/* ansi */
149  {"truth_andif", "&&",		0},		/* old */
150  {"aa",	  "&&",		DMGL_ANSI},	/* ansi */
151  {"truth_orif",  "||",		0},		/* old */
152  {"oo",	  "||",		DMGL_ANSI},	/* ansi */
153  {"truth_not",	  "!",		0},		/* old */
154  {"nt",	  "!",		DMGL_ANSI},	/* ansi */
155  {"postincrement","++",	0},		/* old */
156  {"pp",	  "++",		DMGL_ANSI},	/* ansi */
157  {"postdecrement","--",	0},		/* old */
158  {"mm",	  "--",		DMGL_ANSI},	/* ansi */
159  {"bit_ior",	  "|",		0},		/* old */
160  {"or",	  "|",		DMGL_ANSI},	/* ansi */
161  {"aor",	  "|=",		DMGL_ANSI},	/* ansi */
162  {"bit_xor",	  "^",		0},		/* old */
163  {"er",	  "^",		DMGL_ANSI},	/* ansi */
164  {"aer",	  "^=",		DMGL_ANSI},	/* ansi */
165  {"bit_and",	  "&",		0},		/* old */
166  {"ad",	  "&",		DMGL_ANSI},	/* ansi */
167  {"aad",	  "&=",		DMGL_ANSI},	/* ansi */
168  {"bit_not",	  "~",		0},		/* old */
169  {"co",	  "~",		DMGL_ANSI},	/* ansi */
170  {"call",	  "()",		0},		/* old */
171  {"cl",	  "()",		DMGL_ANSI},	/* ansi */
172  {"alshift",	  "<<",		0},		/* old */
173  {"ls",	  "<<",		DMGL_ANSI},	/* ansi */
174  {"als",	  "<<=",	DMGL_ANSI},	/* ansi */
175  {"arshift",	  ">>",		0},		/* old */
176  {"rs",	  ">>",		DMGL_ANSI},	/* ansi */
177  {"ars",	  ">>=",	DMGL_ANSI},	/* ansi */
178  {"component",	  "->",		0},		/* old */
179  {"pt",	  "->",		DMGL_ANSI},	/* ansi; Lucid C++ form */
180  {"rf",	  "->",		DMGL_ANSI},	/* ansi; ARM/GNU form */
181  {"indirect",	  "*",		0},		/* old */
182  {"method_call",  "->()",	0},		/* old */
183  {"addr",	  "&",		0},		/* old (unary &) */
184  {"array",	  "[]",		0},		/* old */
185  {"vc",	  "[]",		DMGL_ANSI},	/* ansi */
186  {"compound",	  ", ",		0},		/* old */
187  {"cm",	  ", ",		DMGL_ANSI},	/* ansi */
188  {"cond",	  "?:",		0},		/* old */
189  {"cn",	  "?:",		DMGL_ANSI},	/* pseudo-ansi */
190  {"max",	  ">?",		0},		/* old */
191  {"mx",	  ">?",		DMGL_ANSI},	/* pseudo-ansi */
192  {"min",	  "<?",		0},		/* old */
193  {"mn",	  "<?",		DMGL_ANSI},	/* pseudo-ansi */
194  {"nop",	  "",		0},		/* old (for operator=) */
195  {"rm",	  "->*",	DMGL_ANSI}	/* ansi */
196};
197
198
199typedef struct string		/* Beware: these aren't required to be */
200{				/*  '\0' terminated.  */
201  char *b;			/* pointer to start of string */
202  char *p;			/* pointer after last character */
203  char *e;			/* pointer after end of allocated space */
204} string;
205
206#define STRING_EMPTY(str)	((str) -> b == (str) -> p)
207#define PREPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
208    string_prepend(str, " ");}
209#define APPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
210    string_append(str, " ");}
211
212#define ARM_VTABLE_STRING "__vtbl__"	/* Lucid/ARM virtual table prefix */
213#define ARM_VTABLE_STRLEN 8		/* strlen (ARM_VTABLE_STRING) */
214
215/* Prototypes for local functions */
216
217static char *
218mop_up PARAMS ((struct work_stuff *, string *, int));
219
220#if 0
221static int
222demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
223#endif
224
225static int
226demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
227			   string *, int));
228
229static int
230arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
231		const char **));
232
233static void
234demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
235
236static int
237demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
238
239static int
240demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
241			    int, int));
242
243static int
244demangle_class PARAMS ((struct work_stuff *, const char **, string *));
245
246static int
247demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
248
249static int
250demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
251
252static int
253demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
254
255static int
256gnu_special PARAMS ((struct work_stuff *, const char **, string *));
257
258static int
259arm_special PARAMS ((struct work_stuff *, const char **, string *));
260
261static void
262string_need PARAMS ((string *, int));
263
264static void
265string_delete PARAMS ((string *));
266
267static void
268string_init PARAMS ((string *));
269
270static void
271string_clear PARAMS ((string *));
272
273#if 0
274static int
275string_empty PARAMS ((string *));
276#endif
277
278static void
279string_append PARAMS ((string *, const char *));
280
281static void
282string_appends PARAMS ((string *, string *));
283
284static void
285string_appendn PARAMS ((string *, const char *, int));
286
287static void
288string_prepend PARAMS ((string *, const char *));
289
290static void
291string_prependn PARAMS ((string *, const char *, int));
292
293static int
294get_count PARAMS ((const char **, int *));
295
296static int
297consume_count PARAMS ((const char **));
298
299static int
300consume_count_with_underscores PARAMS ((const char**));
301
302static int
303demangle_args PARAMS ((struct work_stuff *, const char **, string *));
304
305static int
306do_type PARAMS ((struct work_stuff *, const char **, string *));
307
308static int
309do_arg PARAMS ((struct work_stuff *, const char **, string *));
310
311static void
312demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
313				const char *));
314
315static void
316remember_type PARAMS ((struct work_stuff *, const char *, int));
317
318static void
319forget_types PARAMS ((struct work_stuff *));
320
321static void
322string_prepends PARAMS ((string *, string *));
323
324/*  Translate count to integer, consuming tokens in the process.
325    Conversion terminates on the first non-digit character.
326    Trying to consume something that isn't a count results in
327    no consumption of input and a return of 0.  */
328
329static int
330consume_count (type)
331     const char **type;
332{
333  int count = 0;
334
335  while (isdigit (**type))
336    {
337      count *= 10;
338      count += **type - '0';
339      (*type)++;
340    }
341  return (count);
342}
343
344
345/* Like consume_count, but for counts that are preceeded and followed
346   by '_' if they are greater than 10.  Also, -1 is returned for
347   failure, since 0 can be a valid value.  */
348
349static int
350consume_count_with_underscores (mangled)
351     const char **mangled;
352{
353  int idx;
354
355  if (**mangled == '_')
356    {
357      (*mangled)++;
358      if (!isdigit (**mangled))
359	return -1;
360
361      idx = consume_count (mangled);
362      if (**mangled != '_')
363	/* The trailing underscore was missing. */
364	return -1;
365
366      (*mangled)++;
367    }
368  else
369    {
370      if (**mangled < '0' || **mangled > '9')
371	return -1;
372
373      idx = **mangled - '0';
374      (*mangled)++;
375    }
376
377  return idx;
378}
379
380int
381cplus_demangle_opname (opname, result, options)
382     const char *opname;
383     char *result;
384     int options;
385{
386  int len, i, len1, ret;
387  string type;
388  struct work_stuff work[1];
389  const char *tem;
390
391  len = strlen(opname);
392  result[0] = '\0';
393  ret = 0;
394  work->options = options;
395
396  if (opname[0] == '_' && opname[1] == '_'
397      && opname[2] == 'o' && opname[3] == 'p')
398    {
399      /* ANSI.  */
400      /* type conversion operator.  */
401      tem = opname + 4;
402      if (do_type (work, &tem, &type))
403	{
404	  strcat (result, "operator ");
405	  strncat (result, type.b, type.p - type.b);
406	  string_delete (&type);
407	  ret = 1;
408	}
409    }
410  else if (opname[0] == '_' && opname[1] == '_'
411	   && opname[2] >= 'a' && opname[2] <= 'z'
412	   && opname[3] >= 'a' && opname[3] <= 'z')
413    {
414      if (opname[4] == '\0')
415	{
416	  /* Operator.  */
417	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
418	    {
419	      if (strlen (optable[i].in) == 2
420		  && memcmp (optable[i].in, opname + 2, 2) == 0)
421		{
422		  strcat (result, "operator");
423		  strcat (result, optable[i].out);
424		  ret = 1;
425		  break;
426		}
427	    }
428	}
429      else
430	{
431	  if (opname[2] == 'a' && opname[5] == '\0')
432	    {
433	      /* Assignment.  */
434	      for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
435		{
436		  if (strlen (optable[i].in) == 3
437		      && memcmp (optable[i].in, opname + 2, 3) == 0)
438		    {
439		      strcat (result, "operator");
440		      strcat (result, optable[i].out);
441		      ret = 1;
442		      break;
443		    }
444		}
445	    }
446	}
447    }
448  else if (len >= 3
449	   && opname[0] == 'o'
450	   && opname[1] == 'p'
451	   && strchr (cplus_markers, opname[2]) != NULL)
452    {
453      /* see if it's an assignment expression */
454      if (len >= 10 /* op$assign_ */
455	  && memcmp (opname + 3, "assign_", 7) == 0)
456	{
457	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
458	    {
459	      len1 = len - 10;
460	      if (strlen (optable[i].in) == len1
461		  && memcmp (optable[i].in, opname + 10, len1) == 0)
462		{
463		  strcat (result, "operator");
464		  strcat (result, optable[i].out);
465		  strcat (result, "=");
466		  ret = 1;
467		  break;
468		}
469	    }
470	}
471      else
472	{
473	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
474	    {
475	      len1 = len - 3;
476	      if (strlen (optable[i].in) == len1
477		  && memcmp (optable[i].in, opname + 3, len1) == 0)
478		{
479		  strcat (result, "operator");
480		  strcat (result, optable[i].out);
481		  ret = 1;
482		  break;
483		}
484	    }
485	}
486    }
487  else if (len >= 5 && memcmp (opname, "type", 4) == 0
488	   && strchr (cplus_markers, opname[4]) != NULL)
489    {
490      /* type conversion operator */
491      tem = opname + 5;
492      if (do_type (work, &tem, &type))
493	{
494	  strcat (result, "operator ");
495	  strncat (result, type.b, type.p - type.b);
496	  string_delete (&type);
497	  ret = 1;
498	}
499    }
500  return ret;
501
502}
503/* Takes operator name as e.g. "++" and returns mangled
504   operator name (e.g. "postincrement_expr"), or NULL if not found.
505
506   If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
507   if OPTIONS & DMGL_ANSI == 0, return the old GNU name.  */
508
509const char *
510cplus_mangle_opname (opname, options)
511     const char *opname;
512     int options;
513{
514  int i;
515  int len;
516
517  len = strlen (opname);
518  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
519    {
520      if (strlen (optable[i].out) == len
521	  && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
522	  && memcmp (optable[i].out, opname, len) == 0)
523	return optable[i].in;
524    }
525  return (0);
526}
527
528/* char *cplus_demangle (const char *mangled, int options)
529
530   If MANGLED is a mangled function name produced by GNU C++, then
531   a pointer to a malloced string giving a C++ representation
532   of the name will be returned; otherwise NULL will be returned.
533   It is the caller's responsibility to free the string which
534   is returned.
535
536   The OPTIONS arg may contain one or more of the following bits:
537
538   	DMGL_ANSI	ANSI qualifiers such as `const' and `void' are
539			included.
540	DMGL_PARAMS	Function parameters are included.
541
542   For example,
543
544   cplus_demangle ("foo__1Ai", DMGL_PARAMS)		=> "A::foo(int)"
545   cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI)	=> "A::foo(int)"
546   cplus_demangle ("foo__1Ai", 0)			=> "A::foo"
547
548   cplus_demangle ("foo__1Afe", DMGL_PARAMS)		=> "A::foo(float,...)"
549   cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
550   cplus_demangle ("foo__1Afe", 0)			=> "A::foo"
551
552   Note that any leading underscores, or other such characters prepended by
553   the compilation system, are presumed to have already been stripped from
554   MANGLED.  */
555
556char *
557cplus_demangle (mangled, options)
558     const char *mangled;
559     int options;
560{
561  string decl;
562  int success = 0;
563  struct work_stuff work[1];
564  char *demangled = NULL;
565
566  if ((mangled != NULL) && (*mangled != '\0'))
567    {
568      memset ((char *) work, 0, sizeof (work));
569      work -> options = options;
570      if ((work->options & DMGL_STYLE_MASK) == 0)
571	work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
572
573      string_init (&decl);
574
575      /* First check to see if gnu style demangling is active and if the
576	 string to be demangled contains a CPLUS_MARKER.  If so, attempt to
577	 recognize one of the gnu special forms rather than looking for a
578	 standard prefix.  In particular, don't worry about whether there
579	 is a "__" string in the mangled string.  Consider "_$_5__foo" for
580	 example.  */
581
582      if ((AUTO_DEMANGLING || GNU_DEMANGLING))
583	{
584	  success = gnu_special (work, &mangled, &decl);
585	}
586      if (!success)
587	{
588	  success = demangle_prefix (work, &mangled, &decl);
589	}
590      if (success && (*mangled != '\0'))
591	{
592	  success = demangle_signature (work, &mangled, &decl);
593	}
594      if (work->constructor == 2)
595        {
596          string_prepend(&decl, "global constructors keyed to ");
597          work->constructor = 0;
598        }
599      else if (work->destructor == 2)
600        {
601          string_prepend(&decl, "global destructors keyed to ");
602          work->destructor = 0;
603        }
604      demangled = mop_up (work, &decl, success);
605    }
606  return (demangled);
607}
608
609static char *
610mop_up (work, declp, success)
611     struct work_stuff *work;
612     string *declp;
613     int success;
614{
615  char *demangled = NULL;
616
617  /* Discard the remembered types, if any.  */
618
619  forget_types (work);
620  if (work -> typevec != NULL)
621    {
622      free ((char *) work -> typevec);
623    }
624  if (work->tmpl_argvec)
625    {
626      int i;
627
628      for (i = 0; i < work->ntmpl_args; i++)
629	if (work->tmpl_argvec[i])
630	  free ((char*) work->tmpl_argvec[i]);
631
632      free ((char*) work->tmpl_argvec);
633    }
634
635  /* If demangling was successful, ensure that the demangled string is null
636     terminated and return it.  Otherwise, free the demangling decl.  */
637
638  if (!success)
639    {
640      string_delete (declp);
641    }
642  else
643    {
644      string_appendn (declp, "", 1);
645      demangled = declp -> b;
646    }
647  return (demangled);
648}
649
650/*
651
652LOCAL FUNCTION
653
654	demangle_signature -- demangle the signature part of a mangled name
655
656SYNOPSIS
657
658	static int
659	demangle_signature (struct work_stuff *work, const char **mangled,
660			    string *declp);
661
662DESCRIPTION
663
664	Consume and demangle the signature portion of the mangled name.
665
666	DECLP is the string where demangled output is being built.  At
667	entry it contains the demangled root name from the mangled name
668	prefix.  I.E. either a demangled operator name or the root function
669	name.  In some special cases, it may contain nothing.
670
671	*MANGLED points to the current unconsumed location in the mangled
672	name.  As tokens are consumed and demangling is performed, the
673	pointer is updated to continuously point at the next token to
674	be consumed.
675
676	Demangling GNU style mangled names is nasty because there is no
677	explicit token that marks the start of the outermost function
678	argument list.  */
679
680static int
681demangle_signature (work, mangled, declp)
682     struct work_stuff *work;
683     const char **mangled;
684     string *declp;
685{
686  int success = 1;
687  int func_done = 0;
688  int expect_func = 0;
689  int expect_return_type = 0;
690  const char *oldmangled = NULL;
691  string trawname;
692  string tname;
693
694  while (success && (**mangled != '\0'))
695    {
696      switch (**mangled)
697	{
698	case 'Q':
699	  oldmangled = *mangled;
700	  success = demangle_qualified (work, mangled, declp, 1, 0);
701	  if (success)
702	    {
703	      remember_type (work, oldmangled, *mangled - oldmangled);
704	    }
705	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
706	    {
707	      expect_func = 1;
708	    }
709	  oldmangled = NULL;
710	  break;
711
712	case 'S':
713	  /* Static member function */
714	  if (oldmangled == NULL)
715	    {
716	      oldmangled = *mangled;
717	    }
718	  (*mangled)++;
719	  work -> static_type = 1;
720	  break;
721
722	case 'C':
723	  /* a const member function */
724	  if (oldmangled == NULL)
725	    {
726	      oldmangled = *mangled;
727	    }
728	  (*mangled)++;
729	  work -> const_type = 1;
730	  break;
731
732	case '0': case '1': case '2': case '3': case '4':
733	case '5': case '6': case '7': case '8': case '9':
734	  if (oldmangled == NULL)
735	    {
736	      oldmangled = *mangled;
737	    }
738	  success = demangle_class (work, mangled, declp);
739	  if (success)
740	    {
741	      remember_type (work, oldmangled, *mangled - oldmangled);
742	    }
743	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
744	    {
745	      expect_func = 1;
746	    }
747	  oldmangled = NULL;
748	  break;
749
750	case 'F':
751	  /* Function */
752	  /* ARM style demangling includes a specific 'F' character after
753	     the class name.  For GNU style, it is just implied.  So we can
754	     safely just consume any 'F' at this point and be compatible
755	     with either style.  */
756
757	  oldmangled = NULL;
758	  func_done = 1;
759	  (*mangled)++;
760
761	  /* For lucid/ARM style we have to forget any types we might
762	     have remembered up to this point, since they were not argument
763	     types.  GNU style considers all types seen as available for
764	     back references.  See comment in demangle_args() */
765
766	  if (LUCID_DEMANGLING || ARM_DEMANGLING)
767	    {
768	      forget_types (work);
769	    }
770	  success = demangle_args (work, mangled, declp);
771	  break;
772
773	case 't':
774	  /* G++ Template */
775	  string_init(&trawname);
776	  string_init(&tname);
777	  if (oldmangled == NULL)
778	    {
779	      oldmangled = *mangled;
780	    }
781	  success = demangle_template (work, mangled, &tname, &trawname, 1);
782	  if (success)
783	    {
784	      remember_type (work, oldmangled, *mangled - oldmangled);
785	    }
786	  string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
787	  string_prepends(declp, &tname);
788	  if (work -> destructor & 1)
789	    {
790	      string_prepend (&trawname, "~");
791	      string_appends (declp, &trawname);
792	      work->destructor -= 1;
793	    }
794	  if ((work->constructor & 1) || (work->destructor & 1))
795	    {
796	      string_appends (declp, &trawname);
797	      work->constructor -= 1;
798	    }
799	  string_delete(&trawname);
800	  string_delete(&tname);
801	  oldmangled = NULL;
802	  expect_func = 1;
803	  break;
804
805	case '_':
806	  if (GNU_DEMANGLING && expect_return_type)
807	    {
808	      /* Read the return type. */
809	      string return_type;
810	      string_init (&return_type);
811
812	      (*mangled)++;
813	      success = do_type (work, mangled, &return_type);
814	      APPEND_BLANK (&return_type);
815
816	      string_prepends (declp, &return_type);
817	      string_delete (&return_type);
818	      break;
819	    }
820	  else
821	    /* At the outermost level, we cannot have a return type specified,
822	       so if we run into another '_' at this point we are dealing with
823	       a mangled name that is either bogus, or has been mangled by
824	       some algorithm we don't know how to deal with.  So just
825	       reject the entire demangling.  */
826	    success = 0;
827	  break;
828
829	case 'H':
830	  if (GNU_DEMANGLING)
831	    {
832	      /* A G++ template function.  Read the template arguments. */
833	      success = demangle_template (work, mangled, declp, 0, 0);
834	      if (!(work->constructor & 1))
835		expect_return_type = 1;
836	      (*mangled)++;
837	      break;
838	    }
839	  else
840	    /* fall through */
841	    ;
842
843	default:
844	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
845	    {
846	      /* Assume we have stumbled onto the first outermost function
847		 argument token, and start processing args.  */
848	      func_done = 1;
849	      success = demangle_args (work, mangled, declp);
850	    }
851	  else
852	    {
853	      /* Non-GNU demanglers use a specific token to mark the start
854		 of the outermost function argument tokens.  Typically 'F',
855		 for ARM-demangling, for example.  So if we find something
856		 we are not prepared for, it must be an error.  */
857	      success = 0;
858	    }
859	  break;
860	}
861      /*
862	if (AUTO_DEMANGLING || GNU_DEMANGLING)
863	*/
864      {
865	if (success && expect_func)
866	  {
867	    func_done = 1;
868	    success = demangle_args (work, mangled, declp);
869	    /* Since template include the mangling of their return types,
870	       we must set expect_func to 0 so that we don't try do
871	       demangle more arguments the next time we get here.  */
872	    expect_func = 0;
873	  }
874      }
875    }
876  if (success && !func_done)
877    {
878      if (AUTO_DEMANGLING || GNU_DEMANGLING)
879	{
880	  /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
881	     bar__3fooi is 'foo::bar(int)'.  We get here when we find the
882	     first case, and need to ensure that the '(void)' gets added to
883	     the current declp.  Note that with ARM, the first case
884	     represents the name of a static data member 'foo::bar',
885	     which is in the current declp, so we leave it alone.  */
886	  success = demangle_args (work, mangled, declp);
887	}
888    }
889  if (success && work -> static_type && PRINT_ARG_TYPES)
890    {
891      string_append (declp, " static");
892    }
893  if (success && work -> const_type && PRINT_ARG_TYPES)
894    {
895      string_append (declp, " const");
896    }
897  return (success);
898}
899
900#if 0
901
902static int
903demangle_method_args (work, mangled, declp)
904     struct work_stuff *work;
905     const char **mangled;
906     string *declp;
907{
908  int success = 0;
909
910  if (work -> static_type)
911    {
912      string_append (declp, *mangled + 1);
913      *mangled += strlen (*mangled);
914      success = 1;
915    }
916  else
917    {
918      success = demangle_args (work, mangled, declp);
919    }
920  return (success);
921}
922
923#endif
924
925static int
926demangle_template (work, mangled, tname, trawname, is_type)
927     struct work_stuff *work;
928     const char **mangled;
929     string *tname;
930     string *trawname;
931     int is_type;
932{
933  int i;
934  int is_pointer;
935  int is_real;
936  int is_integral;
937  int is_char;
938  int is_bool;
939  int r;
940  int need_comma = 0;
941  int success = 0;
942  int done;
943  const char *old_p;
944  const char *start;
945  int symbol_len;
946  int is_java_array = 0;
947  string temp;
948
949  (*mangled)++;
950  if (is_type)
951    {
952      start = *mangled;
953      /* get template name */
954      if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
955	{
956	  return (0);
957	}
958      if (trawname)
959	string_appendn (trawname, *mangled, r);
960      is_java_array = (work -> options & DMGL_JAVA)
961	&& strncmp (*mangled, "JArray1Z", 8) == 0;
962      if (! is_java_array)
963	{
964	  string_appendn (tname, *mangled, r);
965	}
966      *mangled += r;
967    }
968  if (!is_java_array)
969    string_append (tname, "<");
970  /* get size of template parameter list */
971  if (!get_count (mangled, &r))
972    {
973      return (0);
974    }
975  if (!is_type)
976    {
977      /* Create an array for saving the template argument values. */
978      work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
979      work->ntmpl_args = r;
980      for (i = 0; i < r; i++)
981	work->tmpl_argvec[i] = 0;
982    }
983  for (i = 0; i < r; i++)
984    {
985      if (need_comma)
986	{
987	  string_append (tname, ", ");
988	}
989      /* Z for type parameters */
990      if (**mangled == 'Z')
991	{
992	  (*mangled)++;
993	  /* temp is initialized in do_type */
994	  success = do_type (work, mangled, &temp);
995	  if (success)
996	    {
997	      string_appends (tname, &temp);
998
999	      if (!is_type)
1000		{
1001		  /* Save the template argument. */
1002		  int len = temp.p - temp.b;
1003		  work->tmpl_argvec[i] = xmalloc (len + 1);
1004		  memcpy (work->tmpl_argvec[i], temp.b, len);
1005		  work->tmpl_argvec[i][len] = '\0';
1006		}
1007	    }
1008	  string_delete(&temp);
1009	  if (!success)
1010	    {
1011	      break;
1012	    }
1013	}
1014      else
1015	{
1016	  string  param;
1017	  string* s;
1018
1019	  /* otherwise, value parameter */
1020	  old_p  = *mangled;
1021	  is_pointer = 0;
1022	  is_real = 0;
1023	  is_integral = 0;
1024          is_char = 0;
1025	  is_bool = 0;
1026	  done = 0;
1027	  /* temp is initialized in do_type */
1028	  success = do_type (work, mangled, &temp);
1029	  /*
1030	    if (success)
1031	    {
1032	    string_appends (s, &temp);
1033	    }
1034	    */
1035	  string_delete(&temp);
1036	  if (!success)
1037	    {
1038	      break;
1039	    }
1040	  /*
1041	    string_append (s, "=");
1042	    */
1043
1044	  if (!is_type)
1045	    {
1046	      s = &param;
1047	      string_init (s);
1048	    }
1049	  else
1050	    s = tname;
1051
1052	  while (*old_p && !done)
1053	    {
1054	      switch (*old_p)
1055		{
1056		case 'P':
1057		case 'p':
1058		case 'R':
1059		  done = is_pointer = 1;
1060		  break;
1061		case 'C':	/* const */
1062		case 'S':	/* explicitly signed [char] */
1063		case 'U':	/* unsigned */
1064		case 'V':	/* volatile */
1065		case 'F':	/* function */
1066		case 'M':	/* member function */
1067		case 'O':	/* ??? */
1068		case 'J':	/* complex */
1069		  old_p++;
1070		  continue;
1071		case 'Q':	/* qualified name */
1072		  done = is_integral = 1;
1073		  break;
1074		case 'T':	/* remembered type */
1075		  abort ();
1076		  break;
1077		case 'v':	/* void */
1078		  abort ();
1079		  break;
1080		case 'x':	/* long long */
1081		case 'l':	/* long */
1082		case 'i':	/* int */
1083		case 's':	/* short */
1084		case 'w':	/* wchar_t */
1085		  done = is_integral = 1;
1086		  break;
1087		case 'b':	/* bool */
1088		  done = is_bool = 1;
1089		  break;
1090		case 'c':	/* char */
1091		  done = is_char = 1;
1092		  break;
1093		case 'r':	/* long double */
1094		case 'd':	/* double */
1095		case 'f':	/* float */
1096		  done = is_real = 1;
1097		  break;
1098		default:
1099		  /* it's probably user defined type, let's assume
1100		     it's integral, it seems hard to figure out
1101		     what it really is */
1102		  done = is_integral = 1;
1103		}
1104	    }
1105	  if (**mangled == 'Y')
1106	    {
1107	      /* The next argument is a template parameter. */
1108	      int idx;
1109
1110	      (*mangled)++;
1111	      idx = consume_count_with_underscores (mangled);
1112	      if (idx == -1
1113		  || (work->tmpl_argvec && idx >= work->ntmpl_args)
1114		  || consume_count_with_underscores (mangled) == -1)
1115		{
1116		  success = 0;
1117		  if (!is_type)
1118		    string_delete (s);
1119		  break;
1120		}
1121	      if (work->tmpl_argvec)
1122		string_append (s, work->tmpl_argvec[idx]);
1123	      else
1124		{
1125		  char buf[10];
1126		  sprintf(buf, "T%d", idx);
1127		  string_append (s, buf);
1128		}
1129	    }
1130	  else if (is_integral)
1131	    {
1132	      if (**mangled == 'm')
1133		{
1134		  string_appendn (s, "-", 1);
1135		  (*mangled)++;
1136		}
1137	      while (isdigit (**mangled))
1138		{
1139		  string_appendn (s, *mangled, 1);
1140		  (*mangled)++;
1141		}
1142	    }
1143	  else if (is_char)
1144	    {
1145	      char tmp[2];
1146	      int val;
1147              if (**mangled == 'm')
1148                {
1149                  string_appendn (s, "-", 1);
1150                  (*mangled)++;
1151                }
1152	      string_appendn (s, "'", 1);
1153              val = consume_count(mangled);
1154	      if (val == 0)
1155		{
1156		  success = 0;
1157		  if (!is_type)
1158		    string_delete (s);
1159		  break;
1160                }
1161              tmp[0] = (char)val;
1162              tmp[1] = '\0';
1163              string_appendn (s, &tmp[0], 1);
1164	      string_appendn (s, "'", 1);
1165	    }
1166	  else if (is_bool)
1167	    {
1168	      int val = consume_count (mangled);
1169	      if (val == 0)
1170		string_appendn (s, "false", 5);
1171	      else if (val == 1)
1172		string_appendn (s, "true", 4);
1173	      else
1174		success = 0;
1175	    }
1176	  else if (is_real)
1177	    {
1178	      if (**mangled == 'm')
1179		{
1180		  string_appendn (s, "-", 1);
1181		  (*mangled)++;
1182		}
1183	      while (isdigit (**mangled))
1184		{
1185		  string_appendn (s, *mangled, 1);
1186		  (*mangled)++;
1187		}
1188	      if (**mangled == '.') /* fraction */
1189		{
1190		  string_appendn (s, ".", 1);
1191		  (*mangled)++;
1192		  while (isdigit (**mangled))
1193		    {
1194		      string_appendn (s, *mangled, 1);
1195		      (*mangled)++;
1196		    }
1197		}
1198	      if (**mangled == 'e') /* exponent */
1199		{
1200		  string_appendn (s, "e", 1);
1201		  (*mangled)++;
1202		  while (isdigit (**mangled))
1203		    {
1204		      string_appendn (s, *mangled, 1);
1205		      (*mangled)++;
1206		    }
1207		}
1208	    }
1209	  else if (is_pointer)
1210	    {
1211	      symbol_len = consume_count (mangled);
1212	      if (symbol_len == 0)
1213		{
1214		  success = 0;
1215		  if (!is_type)
1216		    string_delete (s);
1217		  break;
1218		}
1219	      if (symbol_len == 0)
1220		string_appendn (s, "0", 1);
1221	      else
1222		{
1223		  char *p = xmalloc (symbol_len + 1), *q;
1224		  strncpy (p, *mangled, symbol_len);
1225		  p [symbol_len] = '\0';
1226		  q = cplus_demangle (p, work->options);
1227		  string_appendn (s, "&", 1);
1228		  if (q)
1229		    {
1230		      string_append (s, q);
1231		      free (q);
1232		    }
1233		  else
1234		    string_append (s, p);
1235		  free (p);
1236		}
1237	      *mangled += symbol_len;
1238	    }
1239	  if (!is_type)
1240	    {
1241	      int len = s->p - s->b;
1242	      work->tmpl_argvec[i] = xmalloc (len + 1);
1243	      memcpy (work->tmpl_argvec[i], s->b, len);
1244	      work->tmpl_argvec[i][len] = '\0';
1245
1246	      string_appends (tname, s);
1247	      string_delete (s);
1248	    }
1249	}
1250      need_comma = 1;
1251    }
1252  if (is_java_array)
1253    {
1254      string_append (tname, "[]");
1255    }
1256  else
1257    {
1258      if (tname->p[-1] == '>')
1259	string_append (tname, " ");
1260      string_append (tname, ">");
1261    }
1262
1263  /*
1264    if (work -> static_type)
1265    {
1266    string_append (declp, *mangled + 1);
1267    *mangled += strlen (*mangled);
1268    success = 1;
1269    }
1270    else
1271    {
1272    success = demangle_args (work, mangled, declp);
1273    }
1274    }
1275    */
1276  return (success);
1277}
1278
1279static int
1280arm_pt (work, mangled, n, anchor, args)
1281     struct work_stuff *work;
1282     const char *mangled;
1283     int n;
1284     const char **anchor, **args;
1285{
1286  /* ARM template? */
1287  if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1288    {
1289      int len;
1290      *args = *anchor + 6;
1291      len = consume_count (args);
1292      if (*args + len == mangled + n && **args == '_')
1293	{
1294	  ++*args;
1295	  return 1;
1296	}
1297    }
1298  return 0;
1299}
1300
1301static void
1302demangle_arm_pt (work, mangled, n, declp)
1303     struct work_stuff *work;
1304     const char **mangled;
1305     int n;
1306     string *declp;
1307{
1308  const char *p;
1309  const char *args;
1310  const char *e = *mangled + n;
1311
1312  /* ARM template? */
1313  if (arm_pt (work, *mangled, n, &p, &args))
1314    {
1315      string arg;
1316      string_init (&arg);
1317      string_appendn (declp, *mangled, p - *mangled);
1318      string_append (declp, "<");
1319      /* should do error checking here */
1320      while (args < e) {
1321	string_clear (&arg);
1322	do_type (work, &args, &arg);
1323	string_appends (declp, &arg);
1324	string_append (declp, ",");
1325      }
1326      string_delete (&arg);
1327      --declp->p;
1328      string_append (declp, ">");
1329    }
1330  else
1331    {
1332      string_appendn (declp, *mangled, n);
1333    }
1334  *mangled += n;
1335}
1336
1337static int
1338demangle_class_name (work, mangled, declp)
1339     struct work_stuff *work;
1340     const char **mangled;
1341     string *declp;
1342{
1343  int n;
1344  int success = 0;
1345
1346  n = consume_count (mangled);
1347  if (strlen (*mangled) >= n)
1348    {
1349      demangle_arm_pt (work, mangled, n, declp);
1350      success = 1;
1351    }
1352
1353  return (success);
1354}
1355
1356/*
1357
1358LOCAL FUNCTION
1359
1360	demangle_class -- demangle a mangled class sequence
1361
1362SYNOPSIS
1363
1364	static int
1365	demangle_class (struct work_stuff *work, const char **mangled,
1366			strint *declp)
1367
1368DESCRIPTION
1369
1370	DECLP points to the buffer into which demangling is being done.
1371
1372	*MANGLED points to the current token to be demangled.  On input,
1373	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1374	On exit, it points to the next token after the mangled class on
1375	success, or the first unconsumed token on failure.
1376
1377	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1378	we are demangling a constructor or destructor.  In this case
1379	we prepend "class::class" or "class::~class" to DECLP.
1380
1381	Otherwise, we prepend "class::" to the current DECLP.
1382
1383	Reset the constructor/destructor flags once they have been
1384	"consumed".  This allows demangle_class to be called later during
1385	the same demangling, to do normal class demangling.
1386
1387	Returns 1 if demangling is successful, 0 otherwise.
1388
1389*/
1390
1391static int
1392demangle_class (work, mangled, declp)
1393     struct work_stuff *work;
1394     const char **mangled;
1395     string *declp;
1396{
1397  int success = 0;
1398  string class_name;
1399
1400  string_init (&class_name);
1401  if (demangle_class_name (work, mangled, &class_name))
1402    {
1403      if ((work->constructor & 1) || (work->destructor & 1))
1404	{
1405	  string_prepends (declp, &class_name);
1406	  if (work -> destructor & 1)
1407	    {
1408	      string_prepend (declp, "~");
1409              work -> destructor -= 1;
1410	    }
1411	  else
1412	    {
1413	      work -> constructor -= 1;
1414	    }
1415	}
1416      string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1417      string_prepends (declp, &class_name);
1418      success = 1;
1419    }
1420  string_delete (&class_name);
1421  return (success);
1422}
1423
1424/*
1425
1426LOCAL FUNCTION
1427
1428	demangle_prefix -- consume the mangled name prefix and find signature
1429
1430SYNOPSIS
1431
1432	static int
1433	demangle_prefix (struct work_stuff *work, const char **mangled,
1434			 string *declp);
1435
1436DESCRIPTION
1437
1438	Consume and demangle the prefix of the mangled name.
1439
1440	DECLP points to the string buffer into which demangled output is
1441	placed.  On entry, the buffer is empty.  On exit it contains
1442	the root function name, the demangled operator name, or in some
1443	special cases either nothing or the completely demangled result.
1444
1445	MANGLED points to the current pointer into the mangled name.  As each
1446	token of the mangled name is consumed, it is updated.  Upon entry
1447	the current mangled name pointer points to the first character of
1448	the mangled name.  Upon exit, it should point to the first character
1449	of the signature if demangling was successful, or to the first
1450	unconsumed character if demangling of the prefix was unsuccessful.
1451
1452	Returns 1 on success, 0 otherwise.
1453 */
1454
1455static int
1456demangle_prefix (work, mangled, declp)
1457     struct work_stuff *work;
1458     const char **mangled;
1459     string *declp;
1460{
1461  int success = 1;
1462  const char *scan;
1463  int i;
1464
1465  if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1466    {
1467      char *marker = strchr (cplus_markers, (*mangled)[8]);
1468      if (marker != NULL && *marker == (*mangled)[10])
1469	{
1470	  if ((*mangled)[9] == 'D')
1471	    {
1472	      /* it's a GNU global destructor to be executed at program exit */
1473	      (*mangled) += 11;
1474	      work->destructor = 2;
1475	      if (gnu_special (work, mangled, declp))
1476		return success;
1477	    }
1478	  else if ((*mangled)[9] == 'I')
1479	    {
1480	      /* it's a GNU global constructor to be executed at program init */
1481	      (*mangled) += 11;
1482	      work->constructor = 2;
1483	      if (gnu_special (work, mangled, declp))
1484		return success;
1485	    }
1486	}
1487    }
1488  else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1489    {
1490      /* it's a ARM global destructor to be executed at program exit */
1491      (*mangled) += 7;
1492      work->destructor = 2;
1493    }
1494  else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1495    {
1496      /* it's a ARM global constructor to be executed at program initial */
1497      (*mangled) += 7;
1498      work->constructor = 2;
1499    }
1500
1501  /*  This block of code is a reduction in strength time optimization
1502      of:
1503      scan = mystrstr (*mangled, "__"); */
1504
1505  {
1506    scan = *mangled;
1507
1508    do {
1509      scan = strchr (scan, '_');
1510    } while (scan != NULL && *++scan != '_');
1511
1512    if (scan != NULL) --scan;
1513  }
1514
1515  if (scan != NULL)
1516    {
1517      /* We found a sequence of two or more '_', ensure that we start at
1518	 the last pair in the sequence.  */
1519      i = strspn (scan, "_");
1520      if (i > 2)
1521	{
1522	  scan += (i - 2);
1523	}
1524    }
1525
1526  if (scan == NULL)
1527    {
1528      success = 0;
1529    }
1530  else if (work -> static_type)
1531    {
1532      if (!isdigit (scan[0]) && (scan[0] != 't'))
1533	{
1534	  success = 0;
1535	}
1536    }
1537  else if ((scan == *mangled)
1538	   && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1539	       || (scan[2] == 'H')))
1540    {
1541      /* The ARM says nothing about the mangling of local variables.
1542	 But cfront mangles local variables by prepending __<nesting_level>
1543	 to them. As an extension to ARM demangling we handle this case.  */
1544      if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1545	{
1546	  *mangled = scan + 2;
1547	  consume_count (mangled);
1548	  string_append (declp, *mangled);
1549	  *mangled += strlen (*mangled);
1550	  success = 1;
1551	}
1552      else
1553	{
1554	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
1555	     names like __Q2_3foo3bar for nested type names.  So don't accept
1556	     this style of constructor for cfront demangling.  A GNU
1557	     style member-template constructor starts with 'H'. */
1558	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1559	    work -> constructor += 1;
1560	  *mangled = scan + 2;
1561	}
1562    }
1563  else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1564    {
1565      /* Mangled name starts with "__".  Skip over any leading '_' characters,
1566	 then find the next "__" that separates the prefix from the signature.
1567	 */
1568      if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1569	  || (arm_special (work, mangled, declp) == 0))
1570	{
1571	  while (*scan == '_')
1572	    {
1573	      scan++;
1574	    }
1575	  if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1576	    {
1577	      /* No separator (I.E. "__not_mangled"), or empty signature
1578		 (I.E. "__not_mangled_either__") */
1579	      success = 0;
1580	    }
1581	  else
1582	    {
1583	      demangle_function_name (work, mangled, declp, scan);
1584	    }
1585	}
1586    }
1587  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1588    {
1589      /* Cfront-style parameterized type.  Handled later as a signature.  */
1590      success = 1;
1591
1592      /* ARM template? */
1593      demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1594    }
1595  else if (*(scan + 2) != '\0')
1596    {
1597      /* Mangled name does not start with "__" but does have one somewhere
1598	 in there with non empty stuff after it.  Looks like a global
1599	 function name.  */
1600      demangle_function_name (work, mangled, declp, scan);
1601    }
1602  else
1603    {
1604      /* Doesn't look like a mangled name */
1605      success = 0;
1606    }
1607
1608  if (!success && (work->constructor == 2 || work->destructor == 2))
1609    {
1610      string_append (declp, *mangled);
1611      *mangled += strlen (*mangled);
1612      success = 1;
1613    }
1614  return (success);
1615}
1616
1617/*
1618
1619LOCAL FUNCTION
1620
1621	gnu_special -- special handling of gnu mangled strings
1622
1623SYNOPSIS
1624
1625	static int
1626	gnu_special (struct work_stuff *work, const char **mangled,
1627		     string *declp);
1628
1629
1630DESCRIPTION
1631
1632	Process some special GNU style mangling forms that don't fit
1633	the normal pattern.  For example:
1634
1635		_$_3foo		(destructor for class foo)
1636		_vt$foo		(foo virtual table)
1637		_vt$foo$bar	(foo::bar virtual table)
1638		__vt_foo	(foo virtual table, new style with thunks)
1639		_3foo$varname	(static data member)
1640		_Q22rs2tu$vw	(static data member)
1641		__t6vector1Zii	(constructor with template)
1642		__thunk_4__$_7ostream (virtual function thunk)
1643 */
1644
1645static int
1646gnu_special (work, mangled, declp)
1647     struct work_stuff *work;
1648     const char **mangled;
1649     string *declp;
1650{
1651  int n;
1652  int success = 1;
1653  const char *p;
1654
1655  if ((*mangled)[0] == '_'
1656      && strchr (cplus_markers, (*mangled)[1]) != NULL
1657      && (*mangled)[2] == '_')
1658    {
1659      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1660      (*mangled) += 3;
1661      work -> destructor += 1;
1662    }
1663  else if ((*mangled)[0] == '_'
1664	   && (((*mangled)[1] == '_'
1665		&& (*mangled)[2] == 'v'
1666		&& (*mangled)[3] == 't'
1667		&& (*mangled)[4] == '_')
1668	       || ((*mangled)[1] == 'v'
1669		   && (*mangled)[2] == 't'
1670		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1671    {
1672      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1673         and create the decl.  Note that we consume the entire mangled
1674	 input string, which means that demangle_signature has no work
1675	 to do.  */
1676      if ((*mangled)[2] == 'v')
1677	(*mangled) += 5; /* New style, with thunks: "__vt_" */
1678      else
1679	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1680      while (**mangled != '\0')
1681	{
1682	  p = strpbrk (*mangled, cplus_markers);
1683	  switch (**mangled)
1684	    {
1685	    case 'Q':
1686	      success = demangle_qualified (work, mangled, declp, 0, 1);
1687	      break;
1688	    case 't':
1689	      success = demangle_template (work, mangled, declp, 0, 1);
1690	      break;
1691	    default:
1692	      if (isdigit(*mangled[0]))
1693		{
1694		  n = consume_count(mangled);
1695		  /* We may be seeing a too-large size, or else a
1696		     ".<digits>" indicating a static local symbol.  In
1697		     any case, declare victory and move on; *don't* try
1698		     to use n to allocate.  */
1699		  if (n >= strlen (*mangled))
1700		    {
1701		      success = 1;
1702		      break;
1703		    }
1704		}
1705	      else
1706		{
1707		  n = strcspn (*mangled, cplus_markers);
1708		}
1709	      string_appendn (declp, *mangled, n);
1710	      (*mangled) += n;
1711	    }
1712
1713	  if (success && ((p == NULL) || (p == *mangled)))
1714	    {
1715	      if (p != NULL)
1716		{
1717		  string_append (declp,
1718				 (work -> options & DMGL_JAVA) ? "." : "::");
1719		  (*mangled)++;
1720		}
1721	    }
1722	  else
1723	    {
1724	      success = 0;
1725	      break;
1726	    }
1727	}
1728      if (success)
1729	string_append (declp, " virtual table");
1730    }
1731  else if ((*mangled)[0] == '_'
1732	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1733	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1734    {
1735      /* static data member, "_3foo$varname" for example */
1736      (*mangled)++;
1737      switch (**mangled)
1738	{
1739	case 'Q':
1740	  success = demangle_qualified (work, mangled, declp, 0, 1);
1741	  break;
1742	case 't':
1743	  success = demangle_template (work, mangled, declp, 0, 1);
1744	  break;
1745	default:
1746	  n = consume_count (mangled);
1747	  string_appendn (declp, *mangled, n);
1748	  (*mangled) += n;
1749	}
1750      if (success && (p == *mangled))
1751	{
1752	  /* Consumed everything up to the cplus_marker, append the
1753	     variable name.  */
1754	  (*mangled)++;
1755	  string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1756	  n = strlen (*mangled);
1757	  string_appendn (declp, *mangled, n);
1758	  (*mangled) += n;
1759	}
1760      else
1761	{
1762	  success = 0;
1763	}
1764    }
1765  else if (strncmp (*mangled, "__thunk_", 8) == 0)
1766    {
1767      int delta = ((*mangled) += 8, consume_count (mangled));
1768      char *method = cplus_demangle (++*mangled, work->options);
1769      if (method)
1770	{
1771	  char buf[50];
1772	  sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1773	  string_append (declp, buf);
1774	  string_append (declp, method);
1775	  free (method);
1776	  n = strlen (*mangled);
1777	  (*mangled) += n;
1778	}
1779      else
1780	{
1781	  success = 0;
1782	}
1783    }
1784  else if (strncmp (*mangled, "__t", 3) == 0
1785	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1786    {
1787      p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1788      (*mangled) += 4;
1789      switch (**mangled)
1790	{
1791	case 'Q':
1792	  success = demangle_qualified (work, mangled, declp, 0, 1);
1793	  break;
1794	case 't':
1795	  success = demangle_template (work, mangled, declp, 0, 1);
1796	  break;
1797	default:
1798	  success = demangle_fund_type (work, mangled, declp);
1799	  break;
1800	}
1801      if (success && **mangled != '\0')
1802	success = 0;
1803      if (success)
1804	string_append (declp, p);
1805    }
1806  else
1807    {
1808      success = 0;
1809    }
1810  return (success);
1811}
1812
1813/*
1814
1815LOCAL FUNCTION
1816
1817	arm_special -- special handling of ARM/lucid mangled strings
1818
1819SYNOPSIS
1820
1821	static int
1822	arm_special (struct work_stuff *work, const char **mangled,
1823			string *declp);
1824
1825
1826DESCRIPTION
1827
1828	Process some special ARM style mangling forms that don't fit
1829	the normal pattern.  For example:
1830
1831		__vtbl__3foo		(foo virtual table)
1832		__vtbl__3foo__3bar	(bar::foo virtual table)
1833
1834 */
1835
1836static int
1837arm_special (work, mangled, declp)
1838     struct work_stuff *work;
1839     const char **mangled;
1840     string *declp;
1841{
1842  int n;
1843  int success = 1;
1844  const char *scan;
1845
1846  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1847    {
1848      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1849         and create the decl.  Note that we consume the entire mangled
1850	 input string, which means that demangle_signature has no work
1851	 to do.  */
1852      scan = *mangled + ARM_VTABLE_STRLEN;
1853      while (*scan != '\0')        /* first check it can be demangled */
1854        {
1855          n = consume_count (&scan);
1856          if (n==0)
1857	    {
1858	      return (0);           /* no good */
1859	    }
1860          scan += n;
1861          if (scan[0] == '_' && scan[1] == '_')
1862	    {
1863	      scan += 2;
1864	    }
1865        }
1866      (*mangled) += ARM_VTABLE_STRLEN;
1867      while (**mangled != '\0')
1868	{
1869	  n = consume_count (mangled);
1870	  string_prependn (declp, *mangled, n);
1871	  (*mangled) += n;
1872	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1873	    {
1874	      string_prepend (declp, "::");
1875	      (*mangled) += 2;
1876	    }
1877	}
1878      string_append (declp, " virtual table");
1879    }
1880  else
1881    {
1882      success = 0;
1883    }
1884  return (success);
1885}
1886
1887/*
1888
1889LOCAL FUNCTION
1890
1891	demangle_qualified -- demangle 'Q' qualified name strings
1892
1893SYNOPSIS
1894
1895	static int
1896	demangle_qualified (struct work_stuff *, const char *mangled,
1897			    string *result, int isfuncname, int append);
1898
1899DESCRIPTION
1900
1901	Demangle a qualified name, such as "Q25Outer5Inner" which is
1902	the mangled form of "Outer::Inner".  The demangled output is
1903	prepended or appended to the result string according to the
1904	state of the append flag.
1905
1906	If isfuncname is nonzero, then the qualified name we are building
1907	is going to be used as a member function name, so if it is a
1908	constructor or destructor function, append an appropriate
1909	constructor or destructor name.  I.E. for the above example,
1910	the result for use as a constructor is "Outer::Inner::Inner"
1911	and the result for use as a destructor is "Outer::Inner::~Inner".
1912
1913BUGS
1914
1915	Numeric conversion is ASCII dependent (FIXME).
1916
1917 */
1918
1919static int
1920demangle_qualified (work, mangled, result, isfuncname, append)
1921     struct work_stuff *work;
1922     const char **mangled;
1923     string *result;
1924     int isfuncname;
1925     int append;
1926{
1927  int qualifiers;
1928  int namelength;
1929  int success = 1;
1930  const char *p;
1931  char num[2];
1932  string temp;
1933
1934  string_init (&temp);
1935  switch ((*mangled)[1])
1936    {
1937    case '_':
1938      /* GNU mangled name with more than 9 classes.  The count is preceded
1939	 by an underscore (to distinguish it from the <= 9 case) and followed
1940	 by an underscore.  */
1941      p = *mangled + 2;
1942      qualifiers = atoi (p);
1943      if (!isdigit (*p) || *p == '0')
1944	success = 0;
1945
1946      /* Skip the digits.  */
1947      while (isdigit (*p))
1948	++p;
1949
1950      if (*p != '_')
1951	success = 0;
1952
1953      *mangled = p + 1;
1954      break;
1955
1956    case '1':
1957    case '2':
1958    case '3':
1959    case '4':
1960    case '5':
1961    case '6':
1962    case '7':
1963    case '8':
1964    case '9':
1965      /* The count is in a single digit.  */
1966      num[0] = (*mangled)[1];
1967      num[1] = '\0';
1968      qualifiers = atoi (num);
1969
1970      /* If there is an underscore after the digit, skip it.  This is
1971	 said to be for ARM-qualified names, but the ARM makes no
1972	 mention of such an underscore.  Perhaps cfront uses one.  */
1973      if ((*mangled)[2] == '_')
1974	{
1975	  (*mangled)++;
1976	}
1977      (*mangled) += 2;
1978      break;
1979
1980    case '0':
1981    default:
1982      success = 0;
1983    }
1984
1985  if (!success)
1986    return success;
1987
1988  /* Pick off the names and collect them in the temp buffer in the order
1989     in which they are found, separated by '::'.  */
1990
1991  while (qualifiers-- > 0)
1992    {
1993      if (*mangled[0] == '_')
1994	*mangled = *mangled + 1;
1995      if (*mangled[0] == 't')
1996	{
1997	  success = demangle_template(work, mangled, &temp, 0, 1);
1998	  if (!success) break;
1999	}
2000      else if (*mangled[0] == 'X')
2001	{
2002	  success = do_type (work, mangled, &temp);
2003	  if (!success) break;
2004	}
2005      else
2006        {
2007	  namelength = consume_count (mangled);
2008      	  if (strlen (*mangled) < namelength)
2009	    {
2010	      /* Simple sanity check failed */
2011	      success = 0;
2012	      break;
2013	    }
2014      	  string_appendn (&temp, *mangled, namelength);
2015      	  *mangled += namelength;
2016	}
2017      if (qualifiers > 0)
2018        {
2019          string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2020        }
2021    }
2022
2023  /* If we are using the result as a function name, we need to append
2024     the appropriate '::' separated constructor or destructor name.
2025     We do this here because this is the most convenient place, where
2026     we already have a pointer to the name and the length of the name.  */
2027
2028  if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2029    {
2030      string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2031      if (work -> destructor & 1)
2032	{
2033	  string_append (&temp, "~");
2034	}
2035      string_appendn (&temp, (*mangled) - namelength, namelength);
2036    }
2037
2038  /* Now either prepend the temp buffer to the result, or append it,
2039     depending upon the state of the append flag.  */
2040
2041  if (append)
2042    {
2043      string_appends (result, &temp);
2044    }
2045  else
2046    {
2047      if (!STRING_EMPTY (result))
2048	{
2049	  string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2050	}
2051      string_prepends (result, &temp);
2052    }
2053
2054  string_delete (&temp);
2055  return (success);
2056}
2057
2058/*
2059
2060LOCAL FUNCTION
2061
2062	get_count -- convert an ascii count to integer, consuming tokens
2063
2064SYNOPSIS
2065
2066	static int
2067	get_count (const char **type, int *count)
2068
2069DESCRIPTION
2070
2071	Return 0 if no conversion is performed, 1 if a string is converted.
2072*/
2073
2074static int
2075get_count (type, count)
2076     const char **type;
2077     int *count;
2078{
2079  const char *p;
2080  int n;
2081
2082  if (!isdigit (**type))
2083    {
2084      return (0);
2085    }
2086  else
2087    {
2088      *count = **type - '0';
2089      (*type)++;
2090      if (isdigit (**type))
2091	{
2092	  p = *type;
2093	  n = *count;
2094	  do
2095	    {
2096	      n *= 10;
2097	      n += *p - '0';
2098	      p++;
2099	    }
2100	  while (isdigit (*p));
2101	  if (*p == '_')
2102	    {
2103	      *type = p + 1;
2104	      *count = n;
2105	    }
2106	}
2107    }
2108  return (1);
2109}
2110
2111/* result will be initialised here; it will be freed on failure */
2112
2113static int
2114do_type (work, mangled, result)
2115     struct work_stuff *work;
2116     const char **mangled;
2117     string *result;
2118{
2119  int n;
2120  int done;
2121  int success;
2122  string decl;
2123  const char *remembered_type;
2124  int constp;
2125  int volatilep;
2126
2127  string_init (&decl);
2128  string_init (result);
2129
2130  done = 0;
2131  success = 1;
2132  while (success && !done)
2133    {
2134      int member;
2135      switch (**mangled)
2136	{
2137
2138	  /* A pointer type */
2139	case 'P':
2140	case 'p':
2141	  (*mangled)++;
2142	  if (! (work -> options & DMGL_JAVA))
2143	    string_prepend (&decl, "*");
2144	  break;
2145
2146	  /* A reference type */
2147	case 'R':
2148	  (*mangled)++;
2149	  string_prepend (&decl, "&");
2150	  break;
2151
2152	  /* An array */
2153	case 'A':
2154	  {
2155	    const char *p = ++(*mangled);
2156
2157	    string_prepend (&decl, "(");
2158	    string_append (&decl, ")[");
2159	    /* Copy anything up until the next underscore (the size of the
2160	       array).  */
2161	    while (**mangled && **mangled != '_')
2162	      ++(*mangled);
2163	    if (**mangled == '_')
2164	      {
2165		string_appendn (&decl, p, *mangled - p);
2166		string_append (&decl, "]");
2167		*mangled += 1;
2168	      }
2169	    else
2170	      success = 0;
2171	    break;
2172	  }
2173
2174	/* A back reference to a previously seen type */
2175	case 'T':
2176	  (*mangled)++;
2177	  if (!get_count (mangled, &n) || n >= work -> ntypes)
2178	    {
2179	      success = 0;
2180	    }
2181	  else
2182	    {
2183	      remembered_type = work -> typevec[n];
2184	      mangled = &remembered_type;
2185	    }
2186	  break;
2187
2188	  /* A function */
2189	case 'F':
2190	  (*mangled)++;
2191	  if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2192	    {
2193	      string_prepend (&decl, "(");
2194	      string_append (&decl, ")");
2195	    }
2196	  /* After picking off the function args, we expect to either find the
2197	     function return type (preceded by an '_') or the end of the
2198	     string.  */
2199	  if (!demangle_args (work, mangled, &decl)
2200	      || (**mangled != '_' && **mangled != '\0'))
2201	    {
2202	      success = 0;
2203	    }
2204	  if (success && (**mangled == '_'))
2205	    {
2206	      (*mangled)++;
2207	    }
2208	  break;
2209
2210	case 'M':
2211	case 'O':
2212	  {
2213	    constp = 0;
2214	    volatilep = 0;
2215
2216	    member = **mangled == 'M';
2217	    (*mangled)++;
2218	    if (!isdigit (**mangled) && **mangled != 't')
2219	      {
2220		success = 0;
2221		break;
2222	      }
2223
2224	    string_append (&decl, ")");
2225	    string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2226	    if (isdigit (**mangled))
2227	      {
2228		n = consume_count (mangled);
2229		if (strlen (*mangled) < n)
2230		  {
2231		    success = 0;
2232		    break;
2233		  }
2234		string_prependn (&decl, *mangled, n);
2235		*mangled += n;
2236	      }
2237	    else
2238	      {
2239		string temp;
2240		string_init (&temp);
2241		success = demangle_template (work, mangled, &temp, NULL, 1);
2242		if (success)
2243		  {
2244		    string_prependn (&decl, temp.b, temp.p - temp.b);
2245		    string_clear (&temp);
2246		  }
2247		else
2248		  break;
2249	      }
2250	    string_prepend (&decl, "(");
2251	    if (member)
2252	      {
2253		if (**mangled == 'C')
2254		  {
2255		    (*mangled)++;
2256		    constp = 1;
2257		  }
2258		if (**mangled == 'V')
2259		  {
2260		    (*mangled)++;
2261		    volatilep = 1;
2262		  }
2263		if (*(*mangled)++ != 'F')
2264		  {
2265		    success = 0;
2266		    break;
2267		  }
2268	      }
2269	    if ((member && !demangle_args (work, mangled, &decl))
2270		|| **mangled != '_')
2271	      {
2272		success = 0;
2273		break;
2274	      }
2275	    (*mangled)++;
2276	    if (! PRINT_ANSI_QUALIFIERS)
2277	      {
2278		break;
2279	      }
2280	    if (constp)
2281	      {
2282		APPEND_BLANK (&decl);
2283		string_append (&decl, "const");
2284	      }
2285	    if (volatilep)
2286	      {
2287		APPEND_BLANK (&decl);
2288		string_append (&decl, "volatile");
2289	      }
2290	    break;
2291	  }
2292        case 'G':
2293	  (*mangled)++;
2294	  break;
2295
2296	case 'C':
2297	  (*mangled)++;
2298	  /*
2299	    if ((*mangled)[1] == 'P')
2300	    {
2301	    */
2302	  if (PRINT_ANSI_QUALIFIERS)
2303	    {
2304	      if (!STRING_EMPTY (&decl))
2305		{
2306		  string_prepend (&decl, " ");
2307		}
2308	      string_prepend (&decl, "const");
2309	    }
2310	  break;
2311	  /*
2312	    }
2313	    */
2314
2315	  /* fall through */
2316	default:
2317	  done = 1;
2318	  break;
2319	}
2320    }
2321
2322  switch (**mangled)
2323    {
2324      /* A qualified name, such as "Outer::Inner".  */
2325    case 'Q':
2326      success = demangle_qualified (work, mangled, result, 0, 1);
2327      break;
2328
2329    case 'X':
2330    case 'Y':
2331      /* A template parm.  We substitute the corresponding argument. */
2332      {
2333	int idx;
2334	int lvl;
2335
2336	(*mangled)++;
2337	idx = consume_count_with_underscores (mangled);
2338
2339	if (idx == -1
2340	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
2341	    || consume_count_with_underscores (mangled) == -1)
2342	  {
2343	    success = 0;
2344	    break;
2345	  }
2346
2347	if (work->tmpl_argvec)
2348	  string_append (result, work->tmpl_argvec[idx]);
2349	else
2350	  {
2351	    char buf[10];
2352	    sprintf(buf, "T%d", idx);
2353	    string_append (result, buf);
2354	  }
2355
2356	success = 1;
2357      }
2358    break;
2359
2360    default:
2361      success = demangle_fund_type (work, mangled, result);
2362      break;
2363    }
2364
2365  if (success)
2366    {
2367      if (!STRING_EMPTY (&decl))
2368	{
2369	  string_append (result, " ");
2370	  string_appends (result, &decl);
2371	}
2372    }
2373  else
2374    {
2375      string_delete (result);
2376    }
2377  string_delete (&decl);
2378  return (success);
2379}
2380
2381/* Given a pointer to a type string that represents a fundamental type
2382   argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2383   string in which the demangled output is being built in RESULT, and
2384   the WORK structure, decode the types and add them to the result.
2385
2386   For example:
2387
2388   	"Ci"	=>	"const int"
2389	"Sl"	=>	"signed long"
2390	"CUs"	=>	"const unsigned short"
2391
2392   */
2393
2394static int
2395demangle_fund_type (work, mangled, result)
2396     struct work_stuff *work;
2397     const char **mangled;
2398     string *result;
2399{
2400  int done = 0;
2401  int success = 1;
2402
2403  /* First pick off any type qualifiers.  There can be more than one.  */
2404
2405  while (!done)
2406    {
2407      switch (**mangled)
2408	{
2409	case 'C':
2410	  (*mangled)++;
2411	  if (PRINT_ANSI_QUALIFIERS)
2412	    {
2413	      APPEND_BLANK (result);
2414	      string_append (result, "const");
2415	    }
2416	  break;
2417	case 'U':
2418	  (*mangled)++;
2419	  APPEND_BLANK (result);
2420	  string_append (result, "unsigned");
2421	  break;
2422	case 'S': /* signed char only */
2423	  (*mangled)++;
2424	  APPEND_BLANK (result);
2425	  string_append (result, "signed");
2426	  break;
2427	case 'V':
2428	  (*mangled)++;
2429	  if (PRINT_ANSI_QUALIFIERS)
2430	    {
2431	      APPEND_BLANK (result);
2432	      string_append (result, "volatile");
2433	    }
2434	  break;
2435	case 'J':
2436	  (*mangled)++;
2437	  APPEND_BLANK (result);
2438	  string_append (result, "__complex");
2439	  break;
2440	default:
2441	  done = 1;
2442	  break;
2443	}
2444    }
2445
2446  /* Now pick off the fundamental type.  There can be only one.  */
2447
2448  switch (**mangled)
2449    {
2450    case '\0':
2451    case '_':
2452      break;
2453    case 'v':
2454      (*mangled)++;
2455      APPEND_BLANK (result);
2456      string_append (result, "void");
2457      break;
2458    case 'x':
2459      (*mangled)++;
2460      APPEND_BLANK (result);
2461      string_append (result, "long long");
2462      break;
2463    case 'l':
2464      (*mangled)++;
2465      APPEND_BLANK (result);
2466      string_append (result, "long");
2467      break;
2468    case 'i':
2469      (*mangled)++;
2470      APPEND_BLANK (result);
2471      string_append (result, "int");
2472      break;
2473    case 's':
2474      (*mangled)++;
2475      APPEND_BLANK (result);
2476      string_append (result, "short");
2477      break;
2478    case 'b':
2479      (*mangled)++;
2480      APPEND_BLANK (result);
2481      string_append (result, "bool");
2482      break;
2483    case 'c':
2484      (*mangled)++;
2485      APPEND_BLANK (result);
2486      string_append (result, "char");
2487      break;
2488    case 'w':
2489      (*mangled)++;
2490      APPEND_BLANK (result);
2491      string_append (result, "wchar_t");
2492      break;
2493    case 'r':
2494      (*mangled)++;
2495      APPEND_BLANK (result);
2496      string_append (result, "long double");
2497      break;
2498    case 'd':
2499      (*mangled)++;
2500      APPEND_BLANK (result);
2501      string_append (result, "double");
2502      break;
2503    case 'f':
2504      (*mangled)++;
2505      APPEND_BLANK (result);
2506      string_append (result, "float");
2507      break;
2508    case 'G':
2509      (*mangled)++;
2510      if (!isdigit (**mangled))
2511	{
2512	  success = 0;
2513	  break;
2514	}
2515      /* fall through */
2516      /* An explicit type, such as "6mytype" or "7integer" */
2517    case '0':
2518    case '1':
2519    case '2':
2520    case '3':
2521    case '4':
2522    case '5':
2523    case '6':
2524    case '7':
2525    case '8':
2526    case '9':
2527      APPEND_BLANK (result);
2528      if (!demangle_class_name (work, mangled, result)) {
2529	--result->p;
2530	success = 0;
2531      }
2532      break;
2533    case 't':
2534      success = demangle_template(work,mangled, result, 0, 1);
2535      break;
2536    default:
2537      success = 0;
2538      break;
2539    }
2540
2541  return (success);
2542}
2543
2544/* `result' will be initialized in do_type; it will be freed on failure */
2545
2546static int
2547do_arg (work, mangled, result)
2548     struct work_stuff *work;
2549     const char **mangled;
2550     string *result;
2551{
2552  const char *start = *mangled;
2553
2554  if (!do_type (work, mangled, result))
2555    {
2556      return (0);
2557    }
2558  else
2559    {
2560      remember_type (work, start, *mangled - start);
2561      return (1);
2562    }
2563}
2564
2565static void
2566remember_type (work, start, len)
2567     struct work_stuff *work;
2568     const char *start;
2569     int len;
2570{
2571  char *tem;
2572
2573  if (work -> ntypes >= work -> typevec_size)
2574    {
2575      if (work -> typevec_size == 0)
2576	{
2577	  work -> typevec_size = 3;
2578	  work -> typevec
2579	    = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2580	}
2581      else
2582	{
2583	  work -> typevec_size *= 2;
2584	  work -> typevec
2585	    = (char **) xrealloc ((char *)work -> typevec,
2586				  sizeof (char *) * work -> typevec_size);
2587	}
2588    }
2589  tem = xmalloc (len + 1);
2590  memcpy (tem, start, len);
2591  tem[len] = '\0';
2592  work -> typevec[work -> ntypes++] = tem;
2593}
2594
2595/* Forget the remembered types, but not the type vector itself.  */
2596
2597static void
2598forget_types (work)
2599     struct work_stuff *work;
2600{
2601  int i;
2602
2603  while (work -> ntypes > 0)
2604    {
2605      i = --(work -> ntypes);
2606      if (work -> typevec[i] != NULL)
2607	{
2608	  free (work -> typevec[i]);
2609	  work -> typevec[i] = NULL;
2610	}
2611    }
2612}
2613
2614/* Process the argument list part of the signature, after any class spec
2615   has been consumed, as well as the first 'F' character (if any).  For
2616   example:
2617
2618   "__als__3fooRT0"		=>	process "RT0"
2619   "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
2620
2621   DECLP must be already initialised, usually non-empty.  It won't be freed
2622   on failure.
2623
2624   Note that g++ differs significantly from ARM and lucid style mangling
2625   with regards to references to previously seen types.  For example, given
2626   the source fragment:
2627
2628     class foo {
2629       public:
2630       foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2631     };
2632
2633     foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2634     void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2635
2636   g++ produces the names:
2637
2638     __3fooiRT0iT2iT2
2639     foo__FiR3fooiT1iT1
2640
2641   while lcc (and presumably other ARM style compilers as well) produces:
2642
2643     foo__FiR3fooT1T2T1T2
2644     __ct__3fooFiR3fooT1T2T1T2
2645
2646   Note that g++ bases it's type numbers starting at zero and counts all
2647   previously seen types, while lucid/ARM bases it's type numbers starting
2648   at one and only considers types after it has seen the 'F' character
2649   indicating the start of the function args.  For lucid/ARM style, we
2650   account for this difference by discarding any previously seen types when
2651   we see the 'F' character, and subtracting one from the type number
2652   reference.
2653
2654 */
2655
2656static int
2657demangle_args (work, mangled, declp)
2658     struct work_stuff *work;
2659     const char **mangled;
2660     string *declp;
2661{
2662  string arg;
2663  int need_comma = 0;
2664  int r;
2665  int t;
2666  const char *tem;
2667  char temptype;
2668
2669  if (PRINT_ARG_TYPES)
2670    {
2671      string_append (declp, "(");
2672      if (**mangled == '\0')
2673	{
2674	  string_append (declp, "void");
2675	}
2676    }
2677
2678  while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2679    {
2680      if ((**mangled == 'N') || (**mangled == 'T'))
2681	{
2682	  temptype = *(*mangled)++;
2683
2684	  if (temptype == 'N')
2685	    {
2686	      if (!get_count (mangled, &r))
2687		{
2688		  return (0);
2689		}
2690	    }
2691	  else
2692	    {
2693	      r = 1;
2694	    }
2695          if (ARM_DEMANGLING && work -> ntypes >= 10)
2696            {
2697              /* If we have 10 or more types we might have more than a 1 digit
2698                 index so we'll have to consume the whole count here. This
2699                 will lose if the next thing is a type name preceded by a
2700                 count but it's impossible to demangle that case properly
2701                 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2702                 Pc, ...)"  or "(..., type12, char *, ...)" */
2703              if ((t = consume_count(mangled)) == 0)
2704                {
2705                  return (0);
2706                }
2707            }
2708          else
2709	    {
2710	      if (!get_count (mangled, &t))
2711	    	{
2712	          return (0);
2713	    	}
2714	    }
2715	  if (LUCID_DEMANGLING || ARM_DEMANGLING)
2716	    {
2717	      t--;
2718	    }
2719	  /* Validate the type index.  Protect against illegal indices from
2720	     malformed type strings.  */
2721	  if ((t < 0) || (t >= work -> ntypes))
2722	    {
2723	      return (0);
2724	    }
2725	  while (--r >= 0)
2726	    {
2727	      tem = work -> typevec[t];
2728	      if (need_comma && PRINT_ARG_TYPES)
2729		{
2730		  string_append (declp, ", ");
2731		}
2732	      if (!do_arg (work, &tem, &arg))
2733		{
2734		  return (0);
2735		}
2736	      if (PRINT_ARG_TYPES)
2737		{
2738		  string_appends (declp, &arg);
2739		}
2740	      string_delete (&arg);
2741	      need_comma = 1;
2742	    }
2743	}
2744      else
2745	{
2746	  if (need_comma & PRINT_ARG_TYPES)
2747	    {
2748	      string_append (declp, ", ");
2749	    }
2750	  if (!do_arg (work, mangled, &arg))
2751	    {
2752	      return (0);
2753	    }
2754	  if (PRINT_ARG_TYPES)
2755	    {
2756	      string_appends (declp, &arg);
2757	    }
2758	  string_delete (&arg);
2759	  need_comma = 1;
2760	}
2761    }
2762
2763  if (**mangled == 'e')
2764    {
2765      (*mangled)++;
2766      if (PRINT_ARG_TYPES)
2767	{
2768	  if (need_comma)
2769	    {
2770	      string_append (declp, ",");
2771	    }
2772	  string_append (declp, "...");
2773	}
2774    }
2775
2776  if (PRINT_ARG_TYPES)
2777    {
2778      string_append (declp, ")");
2779    }
2780  return (1);
2781}
2782
2783static void
2784demangle_function_name (work, mangled, declp, scan)
2785     struct work_stuff *work;
2786     const char **mangled;
2787     string *declp;
2788     const char *scan;
2789{
2790  int i;
2791  int len;
2792  string type;
2793  const char *tem;
2794
2795  string_appendn (declp, (*mangled), scan - (*mangled));
2796  string_need (declp, 1);
2797  *(declp -> p) = '\0';
2798
2799  /* Consume the function name, including the "__" separating the name
2800     from the signature.  We are guaranteed that SCAN points to the
2801     separator.  */
2802
2803  (*mangled) = scan + 2;
2804
2805  if (LUCID_DEMANGLING || ARM_DEMANGLING)
2806    {
2807
2808      /* See if we have an ARM style constructor or destructor operator.
2809	 If so, then just record it, clear the decl, and return.
2810	 We can't build the actual constructor/destructor decl until later,
2811	 when we recover the class name from the signature.  */
2812
2813      if (strcmp (declp -> b, "__ct") == 0)
2814	{
2815	  work -> constructor += 1;
2816	  string_clear (declp);
2817	  return;
2818	}
2819      else if (strcmp (declp -> b, "__dt") == 0)
2820	{
2821	  work -> destructor += 1;
2822	  string_clear (declp);
2823	  return;
2824	}
2825    }
2826
2827  if (declp->p - declp->b >= 3
2828      && declp->b[0] == 'o'
2829      && declp->b[1] == 'p'
2830      && strchr (cplus_markers, declp->b[2]) != NULL)
2831    {
2832      /* see if it's an assignment expression */
2833      if (declp->p - declp->b >= 10 /* op$assign_ */
2834	  && memcmp (declp->b + 3, "assign_", 7) == 0)
2835	{
2836	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2837	    {
2838	      len = declp->p - declp->b - 10;
2839	      if (strlen (optable[i].in) == len
2840		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
2841		{
2842		  string_clear (declp);
2843		  string_append (declp, "operator");
2844		  string_append (declp, optable[i].out);
2845		  string_append (declp, "=");
2846		  break;
2847		}
2848	    }
2849	}
2850      else
2851	{
2852	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2853	    {
2854	      int len = declp->p - declp->b - 3;
2855	      if (strlen (optable[i].in) == len
2856		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
2857		{
2858		  string_clear (declp);
2859		  string_append (declp, "operator");
2860		  string_append (declp, optable[i].out);
2861		  break;
2862		}
2863	    }
2864	}
2865    }
2866  else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2867	   && strchr (cplus_markers, declp->b[4]) != NULL)
2868    {
2869      /* type conversion operator */
2870      tem = declp->b + 5;
2871      if (do_type (work, &tem, &type))
2872	{
2873	  string_clear (declp);
2874	  string_append (declp, "operator ");
2875	  string_appends (declp, &type);
2876	  string_delete (&type);
2877	}
2878    }
2879  else if (declp->b[0] == '_' && declp->b[1] == '_'
2880	   && declp->b[2] == 'o' && declp->b[3] == 'p')
2881    {
2882      /* ANSI.  */
2883      /* type conversion operator.  */
2884      tem = declp->b + 4;
2885      if (do_type (work, &tem, &type))
2886	{
2887	  string_clear (declp);
2888	  string_append (declp, "operator ");
2889	  string_appends (declp, &type);
2890	  string_delete (&type);
2891	}
2892    }
2893  else if (declp->b[0] == '_' && declp->b[1] == '_'
2894	   && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2895	   && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2896    {
2897      if (declp->b[4] == '\0')
2898	{
2899	  /* Operator.  */
2900	  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2901	    {
2902	      if (strlen (optable[i].in) == 2
2903		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2904		{
2905		  string_clear (declp);
2906		  string_append (declp, "operator");
2907		  string_append (declp, optable[i].out);
2908		  break;
2909		}
2910	    }
2911	}
2912      else
2913	{
2914	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
2915	    {
2916	      /* Assignment.  */
2917	      for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2918		{
2919		  if (strlen (optable[i].in) == 3
2920		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2921		    {
2922		      string_clear (declp);
2923		      string_append (declp, "operator");
2924		      string_append (declp, optable[i].out);
2925		      break;
2926		    }
2927		}
2928	    }
2929	}
2930    }
2931}
2932
2933/* a mini string-handling package */
2934
2935static void
2936string_need (s, n)
2937     string *s;
2938     int n;
2939{
2940  int tem;
2941
2942  if (s->b == NULL)
2943    {
2944      if (n < 32)
2945	{
2946	  n = 32;
2947	}
2948      s->p = s->b = xmalloc (n);
2949      s->e = s->b + n;
2950    }
2951  else if (s->e - s->p < n)
2952    {
2953      tem = s->p - s->b;
2954      n += tem;
2955      n *= 2;
2956      s->b = xrealloc (s->b, n);
2957      s->p = s->b + tem;
2958      s->e = s->b + n;
2959    }
2960}
2961
2962static void
2963string_delete (s)
2964     string *s;
2965{
2966  if (s->b != NULL)
2967    {
2968      free (s->b);
2969      s->b = s->e = s->p = NULL;
2970    }
2971}
2972
2973static void
2974string_init (s)
2975     string *s;
2976{
2977  s->b = s->p = s->e = NULL;
2978}
2979
2980static void
2981string_clear (s)
2982     string *s;
2983{
2984  s->p = s->b;
2985}
2986
2987#if 0
2988
2989static int
2990string_empty (s)
2991     string *s;
2992{
2993  return (s->b == s->p);
2994}
2995
2996#endif
2997
2998static void
2999string_append (p, s)
3000     string *p;
3001     const char *s;
3002{
3003  int n;
3004  if (s == NULL || *s == '\0')
3005    return;
3006  n = strlen (s);
3007  string_need (p, n);
3008  memcpy (p->p, s, n);
3009  p->p += n;
3010}
3011
3012static void
3013string_appends (p, s)
3014     string *p, *s;
3015{
3016  int n;
3017
3018  if (s->b != s->p)
3019    {
3020      n = s->p - s->b;
3021      string_need (p, n);
3022      memcpy (p->p, s->b, n);
3023      p->p += n;
3024    }
3025}
3026
3027static void
3028string_appendn (p, s, n)
3029     string *p;
3030     const char *s;
3031     int n;
3032{
3033  if (n != 0)
3034    {
3035      string_need (p, n);
3036      memcpy (p->p, s, n);
3037      p->p += n;
3038    }
3039}
3040
3041static void
3042string_prepend (p, s)
3043     string *p;
3044     const char *s;
3045{
3046  if (s != NULL && *s != '\0')
3047    {
3048      string_prependn (p, s, strlen (s));
3049    }
3050}
3051
3052static void
3053string_prepends (p, s)
3054     string *p, *s;
3055{
3056  if (s->b != s->p)
3057    {
3058      string_prependn (p, s->b, s->p - s->b);
3059    }
3060}
3061
3062static void
3063string_prependn (p, s, n)
3064     string *p;
3065     const char *s;
3066     int n;
3067{
3068  char *q;
3069
3070  if (n != 0)
3071    {
3072      string_need (p, n);
3073      for (q = p->p - 1; q >= p->b; q--)
3074	{
3075	  q[n] = q[0];
3076	}
3077      memcpy (p->b, s, n);
3078      p->p += n;
3079    }
3080}
3081
3082/* To generate a standalone demangler program for testing purposes,
3083   just compile and link this file with -DMAIN and libiberty.a.  When
3084   run, it demangles each command line arg, or each stdin string, and
3085   prints the result on stdout.  */
3086
3087#ifdef MAIN
3088
3089#include "getopt.h"
3090
3091static char *program_name;
3092static char *program_version = VERSION;
3093static int flags = DMGL_PARAMS | DMGL_ANSI;
3094
3095static void demangle_it PARAMS ((char *));
3096static void usage PARAMS ((FILE *, int));
3097static void fatal PARAMS ((char *));
3098
3099static void
3100demangle_it (mangled_name)
3101     char *mangled_name;
3102{
3103  char *result;
3104
3105  result = cplus_demangle (mangled_name, flags);
3106  if (result == NULL)
3107    {
3108      printf ("%s\n", mangled_name);
3109    }
3110  else
3111    {
3112      printf ("%s\n", result);
3113      free (result);
3114    }
3115}
3116
3117static void
3118usage (stream, status)
3119     FILE *stream;
3120     int status;
3121{
3122  fprintf (stream, "\
3123Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3124      [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3125      [--help] [--version] [arg...]\n",
3126	   program_name);
3127  exit (status);
3128}
3129
3130#define MBUF_SIZE 512
3131char mbuffer[MBUF_SIZE];
3132
3133/* Defined in the automatically-generated underscore.c.  */
3134extern int prepends_underscore;
3135
3136int strip_underscore = 0;
3137
3138static struct option long_options[] = {
3139  {"strip-underscores", no_argument, 0, '_'},
3140  {"format", required_argument, 0, 's'},
3141  {"help", no_argument, 0, 'h'},
3142  {"java", no_argument, 0, 'j'},
3143  {"no-strip-underscores", no_argument, 0, 'n'},
3144  {"version", no_argument, 0, 'v'},
3145  {0, no_argument, 0, 0}
3146};
3147
3148int
3149main (argc, argv)
3150     int argc;
3151     char **argv;
3152{
3153  char *result;
3154  int c;
3155
3156  program_name = argv[0];
3157
3158  strip_underscore = prepends_underscore;
3159
3160  while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3161    {
3162      switch (c)
3163	{
3164	case '?':
3165	  usage (stderr, 1);
3166	  break;
3167	case 'h':
3168	  usage (stdout, 0);
3169	case 'n':
3170	  strip_underscore = 0;
3171	  break;
3172	case 'v':
3173	  printf ("GNU %s version %s\n", program_name, program_version);
3174	  exit (0);
3175	case '_':
3176	  strip_underscore = 1;
3177	  break;
3178	case 'j':
3179	  flags |= DMGL_JAVA;
3180	  break;
3181	case 's':
3182	  if (strcmp (optarg, "gnu") == 0)
3183	    {
3184	      current_demangling_style = gnu_demangling;
3185	    }
3186	  else if (strcmp (optarg, "lucid") == 0)
3187	    {
3188	      current_demangling_style = lucid_demangling;
3189	    }
3190	  else if (strcmp (optarg, "arm") == 0)
3191	    {
3192	      current_demangling_style = arm_demangling;
3193	    }
3194	  else
3195	    {
3196	      fprintf (stderr, "%s: unknown demangling style `%s'\n",
3197		       program_name, optarg);
3198	      exit (1);
3199	    }
3200	  break;
3201	}
3202    }
3203
3204  if (optind < argc)
3205    {
3206      for ( ; optind < argc; optind++)
3207	{
3208	  demangle_it (argv[optind]);
3209	}
3210    }
3211  else
3212    {
3213      for (;;)
3214	{
3215	  int i = 0;
3216	  c = getchar ();
3217	  /* Try to read a label.  */
3218	  while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3219	    {
3220	      if (i >= MBUF_SIZE-1)
3221		break;
3222	      mbuffer[i++] = c;
3223	      c = getchar ();
3224	    }
3225	  if (i > 0)
3226	    {
3227	      int skip_first = 0;
3228
3229	      if (mbuffer[0] == '.')
3230		++skip_first;
3231	      if (strip_underscore && mbuffer[skip_first] == '_')
3232		++skip_first;
3233
3234	      if (skip_first > i)
3235		skip_first = i;
3236
3237	      mbuffer[i] = 0;
3238
3239	      result = cplus_demangle (mbuffer + skip_first, flags);
3240	      if (result)
3241		{
3242		  if (mbuffer[0] == '.')
3243		    putc ('.', stdout);
3244		  fputs (result, stdout);
3245		  free (result);
3246		}
3247	      else
3248		fputs (mbuffer, stdout);
3249
3250	      fflush (stdout);
3251	    }
3252	  if (c == EOF)
3253	    break;
3254	  putchar (c);
3255	}
3256    }
3257
3258  exit (0);
3259}
3260
3261static void
3262fatal (str)
3263     char *str;
3264{
3265  fprintf (stderr, "%s: %s\n", program_name, str);
3266  exit (1);
3267}
3268
3269char * malloc ();
3270char * realloc ();
3271
3272char *
3273xmalloc (size)
3274     unsigned size;
3275{
3276  register char *value = (char *) malloc (size);
3277  if (value == 0)
3278    fatal ("virtual memory exhausted");
3279  return value;
3280}
3281
3282char *
3283xrealloc (ptr, size)
3284     char *ptr;
3285     unsigned size;
3286{
3287  register char *value = (char *) realloc (ptr, size);
3288  if (value == 0)
3289    fatal ("virtual memory exhausted");
3290  return value;
3291}
3292#endif	/* main */
3293