cplus-dem.c revision 36a20fa5f779a0a6fb7b4a90dcaa6376481f1faa
14255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* Demangler for GNU C++
24255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
34255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   2000, 2001 Free Software Foundation, Inc.
44255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Written by James Clark (jjc@jclark.uucp)
54255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
64255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
74255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
84255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardThis file is part of the libiberty library.
94255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardLibiberty is free software; you can redistribute it and/or
104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardmodify it under the terms of the GNU Library General Public
114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardLicense as published by the Free Software Foundation; either
124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardversion 2 of the License, or (at your option) any later version.
134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
144255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardLibiberty is distributed in the hope that it will be useful,
154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardbut WITHOUT ANY WARRANTY; without even the implied warranty of
164255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
174255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardLibrary General Public License for more details.
184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
194255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardYou should have received a copy of the GNU Library General Public
204255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardLicense along with libiberty; see the file COPYING.LIB.  If
2196a4b2524590c4c8fe776dfcbf4574737f6206b6Daniel Veillardnot, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
2296a4b2524590c4c8fe776dfcbf4574737f6206b6Daniel VeillardBoston, MA 02111-1307, USA.  */
234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   This file imports xmalloc and xrealloc, which are like malloc and
274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   realloc except that they generate a fatal error if there is no
28070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   available memory.  */
29070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
30070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* This file lives in both GCC and libiberty.  When making changes, please
31070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   try not to break either.  */
324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define __NO_STRING_INLINES
34d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard
35d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#ifdef HAVE_CONFIG_H
36d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#include "config.h"
37d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#endif
38d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard
39d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#include "safe-ctype.h"
404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "core.h"
414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "pub_core_libcbase.h"
424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "pub_tool_libcprint.h"
434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/*#include <sys/types.h>
454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <string.h>
464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <stdio.h>*/
474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/*#ifdef HAVE_STDLIB_H
496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik#include <stdlib.h>
506e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik#else
516e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikchar * malloc ();
526e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikchar * realloc ();
534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif*/
545f704afe98c584b7188aa0e4fbc9d9e68e0d7b1bDaniel Veillard
554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <demangle.h>
564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "dyn-string.h"
574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#undef CURRENT_DEMANGLING_STYLE
584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CURRENT_DEMANGLING_STYLE work->options
5901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
60070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/*#include "libiberty.h"*/
61070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
62070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic char *ada_demangle  PARAMS ((const char *, int));
63070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
64070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
65070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
66070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* A value at least one greater than the maximum number of characters
67070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   that will be output when using the `%d' format with `printf'.  */
68070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define INTBUF_SIZE 32
69070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
70a77cf71f453249f224d609f2f20789a897c5bdebDaniel Veillard#ifndef ARRAY_SIZE
71070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
72070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#endif
73070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
74070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#ifndef STANDALONE
75070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define size_t  Int
76070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
77070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define xstrdup(ptr)        VG_(arena_strdup) (VG_AR_DEMANGLE, ptr)
78070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define free(ptr)           VG_(arena_free)   (VG_AR_DEMANGLE, ptr)
79070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define xmalloc(size)       VG_(arena_malloc) (VG_AR_DEMANGLE, size)
80070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define xrealloc(ptr, size) VG_(arena_realloc)(VG_AR_DEMANGLE, ptr, size)
81070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
82070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define abort() vg_assert(0)
834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#undef strstr
844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define strstr  VG_(strstr)
854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define sprintf VG_(sprintf)
864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define strcpy  VG_(strcpy)
87e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard#define strncpy VG_(strncpy)
88e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard#define strncat VG_(strncat)
89e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard#define strchr  VG_(strchr)
904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define strpbrk VG_(strpbrk)
915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define strlen  VG_(strlen)
92c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack#define strcmp  VG_(strcmp)
93c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack#define strncmp VG_(strncmp)
944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define memcpy  VG_(memcpy)
954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define memset  VG_(memset)
96e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard#define memcmp  VG_(memcmp)
97e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard#endif
98e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
99e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillardextern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
100e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
101e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard/* In order to allow a single demangler executable to demangle strings
102e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard   using various common values of CPLUS_MARKER, as well as any specific
10370bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   one set at compile time, we maintain a string containing all the
10470bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   commonly used ones, and check to see if the marker we are looking for
10570bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   is in that string.  CPLUS_MARKER is usually '$' on systems where the
10670bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   assembler can deal with that.  Where the assembler can't, it's usually
10770bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   '.' (but on many systems '.' is used for other things).  We put the
10870bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   current defined CPLUS_MARKER first (which defaults to '$'), followed
10970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard   by the next most common value, followed by an explicit '$' in case
1101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   the value of CPLUS_MARKER is not '$'.
1111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
1121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   We could avoid this if we could just get g++ to tell us what the actual
1131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   cplus marker character is as part of the debug information, perhaps by
1141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   ensuring that it is the character that terminates the gcc<n>_compiled
1151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   marker symbol (FIXME).  */
1161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
1174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if !defined (CPLUS_MARKER)
1184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CPLUS_MARKER '$'
1194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
1205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
121070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardenum demangling_styles current_demangling_style = auto_demangling;
122070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
123e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillardstatic char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
12470bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard
1251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic char char_str[2] = { '\000', '\000' };
12684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard
12784d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard/*
128c5a70f264550ee39da267e81dccd95508ed367ddDaniel Veillardvoid
129c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillardset_cplus_marker_for_demangling (ch)
1304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     int ch;
1314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{
1324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  cplus_markers[0] = ch;
1334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
1344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard*/
1354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
136c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillardtypedef struct string		/* Beware: these aren't required to be */
137c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard{				/*  '\0' terminated.  */
138c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  char *b;			/* pointer to start of string */
1394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  char *p;			/* pointer after last character */
1404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  char *e;			/* pointer after end of allocated space */
1414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} string;
1424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
143070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Stuff that is shared between sub-routines.
1444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Using a shared structure allows cplus_demangle to be reentrant.  */
145070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
146070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstruct work_stuff
147070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
148070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int options;
149070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char **typevec;
150070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char **ktypevec;
151070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char **btypevec;
15284d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard  int numk;
153c5a70f264550ee39da267e81dccd95508ed367ddDaniel Veillard  int numb;
15484d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard  int ksize;
155560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  int bsize;
1561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int ntypes;
157e5b110b3844d58ff4bea56bcb699144f6fbe0b83Daniel Veillard  int typevec_size;
1584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  int constructor;
1594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  int destructor;
160c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int static_type;	/* A static member function */
161c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int temp_start;       /* index in demangled to start of template args */
162c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int type_quals;       /* The type qualifiers.  */
163c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int dllimported;	/* Symbol imported from a PE DLL */
164c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  char **tmpl_argvec;   /* Template function arguments. */
165c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int ntmpl_args;       /* The number of template function arguments. */
166c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int forgetting_types; /* Nonzero if we are not remembering the types
167c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard			   we see.  */
168c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  string* previous_argument; /* The last function argument demangled.  */
169c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  int nrepeats;         /* The number of times to repeat the previous
170c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard			   argument.  */
171c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard};
172c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
173c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
174c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard#define PRINT_ARG_TYPES       (work -> options & DMGL_PARAMS)
1758bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
1768bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstatic const struct optable
1778bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard{
1788bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  const char *const in;
1798bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  const char *const out;
180e5b110b3844d58ff4bea56bcb699144f6fbe0b83Daniel Veillard  const int flags;
1818bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard} optable[] = {
1828bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {"nw",	  " new",	DMGL_ANSI},	/* new (1.92,	 ansi) */
1838bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {"dl",	  " delete",	DMGL_ANSI},	/* new (1.92,	 ansi) */
184a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard  {"new",	  " new",	0},		/* old (1.91,	 and 1.x) */
185a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard  {"delete",	  " delete",	0},		/* old (1.91,	 and 1.x) */
186e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  {"vn",	  " new []",	DMGL_ANSI},	/* GNU, pending ansi */
1878bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {"vd",	  " delete []",	DMGL_ANSI},	/* GNU, pending ansi */
1888bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {"as",	  "=",		DMGL_ANSI},	/* ansi */
189c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  {"ne",	  "!=",		DMGL_ANSI},	/* old, ansi */
190d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"eq",	  "==",		DMGL_ANSI},	/* old,	ansi */
191d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"ge",	  ">=",		DMGL_ANSI},	/* old,	ansi */
192d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"gt",	  ">",		DMGL_ANSI},	/* old,	ansi */
193d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"le",	  "<=",		DMGL_ANSI},	/* old,	ansi */
194d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"lt",	  "<",		DMGL_ANSI},	/* old,	ansi */
195d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"plus",	  "+",		0},		/* old */
196d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"pl",	  "+",		DMGL_ANSI},	/* ansi */
197d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"apl",	  "+=",		DMGL_ANSI},	/* ansi */
198d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"minus",	  "-",		0},		/* old */
199d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"mi",	  "-",		DMGL_ANSI},	/* ansi */
200d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"ami",	  "-=",		DMGL_ANSI},	/* ansi */
201d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"mult",	  "*",		0},		/* old */
202d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"ml",	  "*",		DMGL_ANSI},	/* ansi */
203d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"amu",	  "*=",		DMGL_ANSI},	/* ansi (ARM/Lucid) */
204d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"aml",	  "*=",		DMGL_ANSI},	/* ansi (GNU/g++) */
205d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"convert",	  "+",		0},		/* old (unary +) */
206d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"negate",	  "-",		0},		/* old (unary -) */
207d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"trunc_mod",	  "%",		0},		/* old */
208d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"md",	  "%",		DMGL_ANSI},	/* ansi */
209d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"amd",	  "%=",		DMGL_ANSI},	/* ansi */
210d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"trunc_div",	  "/",		0},		/* old */
211d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"dv",	  "/",		DMGL_ANSI},	/* ansi */
212c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard  {"adv",	  "/=",		DMGL_ANSI},	/* ansi */
2134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"truth_andif", "&&",		0},		/* old */
2144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"aa",	  "&&",		DMGL_ANSI},	/* ansi */
2158bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {"truth_orif",  "||",		0},		/* old */
2164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"oo",	  "||",		DMGL_ANSI},	/* ansi */
21701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"truth_not",	  "!",		0},		/* old */
2184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"nt",	  "!",		DMGL_ANSI},	/* ansi */
2194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"postincrement","++",	0},		/* old */
22001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"pp",	  "++",		DMGL_ANSI},	/* ansi */
22101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"postdecrement","--",	0},		/* old */
2224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"mm",	  "--",		DMGL_ANSI},	/* ansi */
2234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"bit_ior",	  "|",		0},		/* old */
2244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"or",	  "|",		DMGL_ANSI},	/* ansi */
2254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"aor",	  "|=",		DMGL_ANSI},	/* ansi */
226d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard  {"bit_xor",	  "^",		0},		/* old */
2274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"er",	  "^",		DMGL_ANSI},	/* ansi */
2284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"aer",	  "^=",		DMGL_ANSI},	/* ansi */
2294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"bit_and",	  "&",		0},		/* old */
230be9c6320d4ed8d5622322014310555bb88b02a85Daniel Veillard  {"ad",	  "&",		DMGL_ANSI},	/* ansi */
2314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"aad",	  "&=",		DMGL_ANSI},	/* ansi */
23201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"bit_not",	  "~",		0},		/* old */
23301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"co",	  "~",		DMGL_ANSI},	/* ansi */
23401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"call",	  "()",		0},		/* old */
23501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"cl",	  "()",		DMGL_ANSI},	/* ansi */
23601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"alshift",	  "<<",		0},		/* old */
23701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"ls",	  "<<",		DMGL_ANSI},	/* ansi */
23801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"als",	  "<<=",	DMGL_ANSI},	/* ansi */
23901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"arshift",	  ">>",		0},		/* old */
2402f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack  {"rs",	  ">>",		DMGL_ANSI},	/* ansi */
2412f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack  {"ars",	  ">>=",	DMGL_ANSI},	/* ansi */
24201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"component",	  "->",		0},		/* old */
2434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {"pt",	  "->",		DMGL_ANSI},	/* ansi; Lucid C++ form */
24401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"rf",	  "->",		DMGL_ANSI},	/* ansi; ARM/GNU form */
24501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"indirect",	  "*",		0},		/* old */
24601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"method_call",  "->()",	0},		/* old */
24701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"addr",	  "&",		0},		/* old (unary &) */
24801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"array",	  "[]",		0},		/* old */
24901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"vc",	  "[]",		DMGL_ANSI},	/* ansi */
25001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"compound",	  ", ",		0},		/* old */
25101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"cm",	  ", ",		DMGL_ANSI},	/* ansi */
25201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"cond",	  "?:",		0},		/* old */
25301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"cn",	  "?:",		DMGL_ANSI},	/* pseudo-ansi */
25401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"max",	  ">?",		0},		/* old */
25501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"mx",	  ">?",		DMGL_ANSI},	/* pseudo-ansi */
25601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"min",	  "<?",		0},		/* old */
25701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"mn",	  "<?",		DMGL_ANSI},	/* pseudo-ansi */
25801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"nop",	  "",		0},		/* old (for operator=) */
25901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"rm",	  "->*",	DMGL_ANSI},	/* ansi */
26001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {"sz",          "sizeof ",    DMGL_ANSI}      /* pseudo-ansi */
26101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard};
26201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
26301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* These values are used to indicate the various type varieties.
26401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   They are all non-zero so that they can be used as `success'
26596d2effc735fb45cfa363b6a876ff23a862f87a5William M. Brack   values.  */
26696d2effc735fb45cfa363b6a876ff23a862f87a5William M. Bracktypedef enum type_kind_t
26701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
26801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  tk_none,
2694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  tk_pointer,
2704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  tk_reference,
27101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  tk_integral,
2724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  tk_bool,
2734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  tk_char,
2744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  tk_real
2754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} type_kind_t;
2764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardconst struct demangler_engine libiberty_demanglers[] =
2784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{
2794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {
2804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NO_DEMANGLING_STYLE_STRING,
2816560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard    no_demangling,
2826560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard    "Demangling disabled"
2834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  }
2846560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard  ,
2854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  {
2866560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard    AUTO_DEMANGLING_STYLE_STRING,
28701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      auto_demangling,
288c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard      "Automatic selection based on executable"
28901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
29001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  ,
2918bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  {
2922f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack    GNU_DEMANGLING_STYLE_STRING,
29301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      gnu_demangling,
29401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      "GNU (g++) style demangling"
29501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
29601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  ,
29701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
29801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    LUCID_DEMANGLING_STYLE_STRING,
29901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      lucid_demangling,
30001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      "Lucid (lcc) style demangling"
3012f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack  }
30201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  ,
30301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
30401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    ARM_DEMANGLING_STYLE_STRING,
30501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      arm_demangling,
30601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      "ARM style demangling"
30701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
30801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  ,
30901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
31001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    HP_DEMANGLING_STYLE_STRING,
31101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      hp_demangling,
3122f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack      "HP (aCC) style demangling"
31301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
31401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  ,
31501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
31601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    EDG_DEMANGLING_STYLE_STRING,
31701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      edg_demangling,
31801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      "EDG style demangling"
31901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
3208bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  ,
32101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
32201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    GNU_V3_DEMANGLING_STYLE_STRING,
3238bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    gnu_v3_demangling,
32401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    "GNU (g++) V3 ABI-style demangling"
32501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
3268bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  ,
32701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
32801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    JAVA_DEMANGLING_STYLE_STRING,
3298bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    java_demangling,
33001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    "Java style demangling"
33101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
3328bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  ,
33301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
33401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    GNAT_DEMANGLING_STYLE_STRING,
3358bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    gnat_demangling,
33601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    "GNAT style demangling"
33701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  }
3388bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  ,
33901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  {
34001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    NULL, unknown_demangling, NULL
3418bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  }
34201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard};
34301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
3448bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard#define STRING_EMPTY(str)	((str) -> b == (str) -> p)
34501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define PREPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
34601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    string_prepend(str, " ");}
3478bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard#define APPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
34801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    string_append(str, " ");}
34901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define LEN_STRING(str)         ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
3508bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
35101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* The scope separator appropriate for the language being demangled.  */
35201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
3538bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
35401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
35501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define ARM_VTABLE_STRING "__vtbl__"	/* Lucid/ARM virtual table prefix */
3568bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard#define ARM_VTABLE_STRLEN 8		/* strlen (ARM_VTABLE_STRING) */
35701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
35801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* Prototypes for local functions */
3598bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
36001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
36101fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddelete_work_stuff PARAMS ((struct work_stuff *));
362560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard
36301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
36401fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddelete_non_B_K_work_stuff PARAMS ((struct work_stuff *));
3651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
36601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic char *
36701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardmop_up PARAMS ((struct work_stuff *, string *, int));
36801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
36901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
37001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardsquangle_mop_up PARAMS ((struct work_stuff *));
37101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
37201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
37301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardwork_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
3744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
375c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard#if 0
376c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillardstatic int
377c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillarddemangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
3788bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard#endif
37901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
38001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic char *
3816560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillardinternal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
3826560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard
38301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
38401fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_template_template_parm PARAMS ((struct work_stuff *work,
3856560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard					 const char **, string *));
38601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
38701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
3886560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_template PARAMS ((struct work_stuff *work, const char **, string *,
38901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard			   string *, int, int));
39001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
39101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
39201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardarm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
3938bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard		const char **));
39401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
39501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
3968bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillarddemangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
39701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
39801fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
3996560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
4006560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard			    int, int));
40101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
40201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4036560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_class PARAMS ((struct work_stuff *, const char **, string *));
40401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
40501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4066560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
40701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
40801fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4096560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_signature PARAMS ((struct work_stuff *, const char **, string *));
41001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
41101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4126560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillarddemangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
41301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
41401fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4156560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillardgnu_special PARAMS ((struct work_stuff *, const char **, string *));
41601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
41701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
4188bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardarm_special PARAMS ((const char **, string *));
41901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
42001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
4218bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstring_need PARAMS ((string *, int));
42201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
42301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
4248bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstring_delete PARAMS ((string *));
42501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
42601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
42701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstring_init PARAMS ((string *));
42801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
42901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
43001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstring_clear PARAMS ((string *));
43101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
43201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#if 0
43301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
43401fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstring_empty PARAMS ((string *));
43501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#endif
43601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
43701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
4388bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstring_append PARAMS ((string *, const char *));
43901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
44001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
4418bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstring_appends PARAMS ((string *, string *));
44201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
44301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
44401fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstring_appendn PARAMS ((string *, const char *, int));
44501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
44601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
447a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillardstring_prepend PARAMS ((string *, const char *));
44801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
44901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
450a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillardstring_prependn PARAMS ((string *, const char *, int));
45101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
45201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
4534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstring_append_template_idx PARAMS ((string *, int));
4544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
4564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardget_count PARAMS ((const char **, int *));
4574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
4594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardconsume_count PARAMS ((const char **));
4604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
4624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardconsume_count_with_underscores PARAMS ((const char**));
4634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
46501fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_args PARAMS ((struct work_stuff *, const char **, string *));
4664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
4684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillarddemangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
4694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
4716927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillarddo_type PARAMS ((struct work_stuff *, const char **, string *));
47201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
47301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
47401fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddo_arg PARAMS ((struct work_stuff *, const char **, string *));
47501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
47601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
47701fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
47801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				const char *));
47901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
48001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
48101fa6156e51259229470f40619af93e915b4bc94Daniel Veillarditerate_demangle_function PARAMS ((struct work_stuff *,
48201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				   const char **, string *, const char *));
48301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
484ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillardstatic void
485ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillardremember_type PARAMS ((struct work_stuff *, const char *, int));
48601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
48701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
48801fa6156e51259229470f40619af93e915b4bc94Daniel Veillardremember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
48901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
49001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
49101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardregister_Btype PARAMS ((struct work_stuff *));
49201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
49301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
49401fa6156e51259229470f40619af93e915b4bc94Daniel Veillardremember_Ktype PARAMS ((struct work_stuff *, const char *, int));
49501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
49601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
49701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardforget_types PARAMS ((struct work_stuff *));
49801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
49901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
50001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardforget_B_and_K_types PARAMS ((struct work_stuff *));
50101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
50201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
50301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstring_prepends PARAMS ((string *, string *));
50401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
50501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
50601fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
50701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				      string*, type_kind_t));
50801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
50901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
51001fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddo_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
51101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
51201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
51301fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddo_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
51401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
51501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
51601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardsnarf_numeric_literal PARAMS ((const char **, string *));
51701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
51801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* There is a TYPE_QUAL value for each type qualifier.  They can be
51901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   combined by bitwise-or to form the complete set of qualifiers for a
52001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   type.  */
52101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
52201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define TYPE_UNQUALIFIED   0x0
52301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define TYPE_QUAL_CONST    0x1
52401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define TYPE_QUAL_VOLATILE 0x2
52501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard#define TYPE_QUAL_RESTRICT 0x4
52601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
52701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
52801fa6156e51259229470f40619af93e915b4bc94Daniel Veillardcode_for_qualifier PARAMS ((int));
52901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
53001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic const char*
53101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardqualifier_string PARAMS ((int));
53201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
53301fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic const char*
53401fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_qualifier PARAMS ((int));
53501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
53601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
53701fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_expression PARAMS ((struct work_stuff *, const char **, string *,
53801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard			     type_kind_t));
53901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
54001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
54101fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_integral_value PARAMS ((struct work_stuff *, const char **,
54201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				 string *));
54301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
54401fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
545c7e3cc49bade82dba0cda4ae7c07ffcd1e32fe25Daniel Veillarddemangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
54601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
54701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
54801fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
54901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				  string *));
55001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
55101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
55201fa6156e51259229470f40619af93e915b4bc94Daniel Veillardrecursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
55301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard			      int));
55401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
55501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic void
55601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardgrow_vect PARAMS ((void **, size_t *, size_t, int));
55701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
55801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* Translate count to integer, consuming tokens in the process.
55901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   Conversion terminates on the first non-digit character.
56001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
56101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   Trying to consume something that isn't a count results in no
56201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   consumption of input and a return of -1.
56301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
56401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   Overflow consumes the rest of the digits, and returns -1.  */
56501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
56601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
56701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardconsume_count (type)
56801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     const char **type;
56901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
57001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  int count = 0;
57101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
57201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  if (! ISDIGIT ((unsigned char)**type))
57301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    return -1;
57401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
57501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  while (ISDIGIT ((unsigned char)**type))
57601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
57701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      count *= 10;
57801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
57901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      /* Check for overflow.
58001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	 We assume that count is represented using two's-complement;
58101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	 no power of two is divisible by ten, so if an overflow occurs
58201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	 when multiplying by ten, the result will not be a multiple of
58301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	 ten.  */
58401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if ((count % 10) != 0)
58501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
58601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  while (ISDIGIT ((unsigned char) **type))
58701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    (*type)++;
58801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  return -1;
58901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	}
59001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
59101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      count += **type - '0';
59201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      (*type)++;
59301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    }
59401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
59501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  if (count < 0)
59601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    count = -1;
59701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
59801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  return (count);
59901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard}
60001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
60101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
60201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* Like consume_count, but for counts that are preceded and followed
60301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   by '_' if they are greater than 10.  Also, -1 is returned for
60401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   failure, since 0 can be a valid value.  */
60501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
60601fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
60701fa6156e51259229470f40619af93e915b4bc94Daniel Veillardconsume_count_with_underscores (mangled)
60801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     const char **mangled;
60901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
61001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  int idx;
61101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
61201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  if (**mangled == '_')
61301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
61401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      (*mangled)++;
61501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (!ISDIGIT ((unsigned char)**mangled))
61601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	return -1;
61701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
61801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      idx = consume_count (mangled);
61901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (**mangled != '_')
62001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	/* The trailing underscore was missing. */
62101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	return -1;
62201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
62301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      (*mangled)++;
62401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    }
62501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  else
62601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
62701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (**mangled < '0' || **mangled > '9')
62801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	return -1;
62901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
63001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      idx = **mangled - '0';
63101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      (*mangled)++;
63201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    }
63301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
63401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  return idx;
63501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard}
63601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
63701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* C is the code for a type-qualifier.  Return the TYPE_QUAL
63801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   corresponding to this qualifier.  */
63901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
64001fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
64101fa6156e51259229470f40619af93e915b4bc94Daniel Veillardcode_for_qualifier (c)
64201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  int c;
64301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
64401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  switch (c)
64501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
64601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    case 'C':
64701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      return TYPE_QUAL_CONST;
64801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
64901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    case 'V':
65001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      return TYPE_QUAL_VOLATILE;
65101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
65201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    case 'u':
65301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      return TYPE_QUAL_RESTRICT;
65401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
65501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    default:
65601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      break;
65701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    }
65801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
65901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  /* C was an invalid qualifier.  */
66001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  abort ();
66101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard}
66201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
66301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* Return the string corresponding to the qualifiers given by
6644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   TYPE_QUALS.  */
6654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic const char*
6674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardqualifier_string (type_quals)
6684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     int type_quals;
6694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{
6704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  switch (type_quals)
6714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    {
6724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case TYPE_UNQUALIFIED:
6734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      return "";
6744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case TYPE_QUAL_CONST:
6764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      return "const";
6774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case TYPE_QUAL_VOLATILE:
6794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      return "volatile";
6804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case TYPE_QUAL_RESTRICT:
6824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      return "__restrict";
6834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
6856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      return "const volatile";
6866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
6876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
6886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      return "const __restrict";
6896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
6906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
6916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      return "volatile __restrict";
6926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
6936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
6946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      return "const volatile __restrict";
6956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
6966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    default:
6976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      break;
6986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
6996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
7006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* TYPE_QUALS was an invalid qualifier set.  */
7016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  abort ();
7026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik}
7036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
7046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/* C is the code for a type-qualifier.  Return the string
7056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   corresponding to this qualifier.  This function should only be
7066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   called with a valid qualifier code.  */
7076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
7086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic const char*
7096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikdemangle_qualifier (c)
7106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int c;
7116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik{
7126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  return qualifier_string (code_for_qualifier (c));
7134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
7144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if 0
7164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint
7174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardcplus_demangle_opname (opname, result, options)
7184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     const char *opname;
7194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     char *result;
7204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     int options;
7214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{
722c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  int len, len1, ret;
723c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string type;
724c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  struct work_stuff work[1];
725c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  const char *tem;
726c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
727c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  len = strlen(opname);
728c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  result[0] = '\0';
729c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  ret = 0;
730c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  memset ((char *) work, 0, sizeof (work));
731c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  work->options = options;
732c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
733c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  if (opname[0] == '_' && opname[1] == '_'
734c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      && opname[2] == 'o' && opname[3] == 'p')
735c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
736c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      /* ANSI.  */
737c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      /* type conversion operator.  */
738c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      tem = opname + 4;
739c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      if (do_type (work, &tem, &type))
740c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	{
741e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  strcat (result, "operator ");
742e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  strncat (result, type.b, type.p - type.b);
743e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  string_delete (&type);
744e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  ret = 1;
745e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	}
746e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
74770bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard  else if (opname[0] == '_' && opname[1] == '_'
74870bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard	   && ISLOWER((unsigned char)opname[2])
74970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard	   && ISLOWER((unsigned char)opname[3]))
75070bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard    {
7511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (opname[4] == '\0')
7521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
7531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* Operator.  */
7541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  size_t i;
755c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  for (i = 0; i < ARRAY_SIZE (optable); i++)
756c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	    {
757c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	      if (strlen (optable[i].in) == 2
7584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  && memcmp (optable[i].in, opname + 2, 2) == 0)
7594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		{
7604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  strcat (result, "operator");
7614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  strcat (result, optable[i].out);
7624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  ret = 1;
7634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  break;
7644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
7654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
7664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
7674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      else
7684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	{
7694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  if (opname[2] == 'a' && opname[5] == '\0')
7704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    {
7714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      /* Assignment.  */
7724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      size_t i;
7734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      for (i = 0; i < ARRAY_SIZE (optable); i++)
7744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		{
7754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  if (strlen (optable[i].in) == 3
7764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		      && memcmp (optable[i].in, opname + 2, 3) == 0)
7774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    {
778070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		      strcat (result, "operator");
77901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		      strcat (result, optable[i].out);
78001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		      ret = 1;
78101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		      break;
78201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		    }
7836927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard		}
7846927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	    }
785c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
786c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
78701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  else if (len >= 3
78801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	   && opname[0] == 'o'
78901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	   && opname[1] == 'p'
79001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	   && strchr (cplus_markers, opname[2]) != NULL)
7914259532303e96e089a185c6f55056cb7c4902d71Daniel Veillard    {
79201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      /* see if it's an assignment expression */
79301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (len >= 10 /* op$assign_ */
79401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  && memcmp (opname + 3, "assign_", 7) == 0)
79501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
79601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  size_t i;
79701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  for (i = 0; i < ARRAY_SIZE (optable); i++)
79801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    {
79901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	      len1 = len - 10;
80001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	      if ((int) strlen (optable[i].in) == len1
80101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		  && memcmp (optable[i].in, opname + 10, len1) == 0)
80201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		{
80301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		  strcat (result, "operator");
80401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		  strcat (result, optable[i].out);
805070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  strcat (result, "=");
806070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  ret = 1;
807070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  break;
808070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		}
809070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
810070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
811070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      else
812070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
813070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  size_t i;
814070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  for (i = 0; i < ARRAY_SIZE (optable); i++)
815070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
816070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      len1 = len - 3;
817070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      if ((int) strlen (optable[i].in) == len1
818070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  && memcmp (optable[i].in, opname + 3, len1) == 0)
819070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		{
820070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  strcat (result, "operator");
821070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  strcat (result, optable[i].out);
822070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  ret = 1;
823070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  break;
824070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		}
825ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	    }
826070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
827ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard    }
828070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else if (len >= 5 && memcmp (opname, "type", 4) == 0
829070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	   && strchr (cplus_markers, opname[4]) != NULL)
8305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
8315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      /* type conversion operator */
8325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      tem = opname + 5;
833070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (do_type (work, &tem, &type))
834070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
835070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  strcat (result, "operator ");
836070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  strncat (result, type.b, type.p - type.b);
837070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_delete (&type);
838070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  ret = 1;
839070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
840070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
841070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  squangle_mop_up (work);
842070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return ret;
843070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
844070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
845070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#endif /* 0 */
846070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
847070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Takes operator name as e.g. "++" and returns mangled
848070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   operator name (e.g. "postincrement_expr"), or NULL if not found.
849070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
850070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
851070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   if OPTIONS & DMGL_ANSI == 0, return the old GNU name.  */
8525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
8535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/*
8545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardconst char *
8555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardcplus_mangle_opname (opname, options)
8565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     const char *opname;
8575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     int options;
8585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
8595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  size_t i;
8605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  int len;
8615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
8625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  len = strlen (opname);
8635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  for (i = 0; i < ARRAY_SIZE (optable); i++)
8645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
8655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if ((int) strlen (optable[i].out) == len
8665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
8675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  && memcmp (optable[i].out, opname, len) == 0)
8685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	return optable[i].in;
8695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
8705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  return (0);
8715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
8725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard*/
8735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
8745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/* Add a routine to set the demangling style to be sure it is valid and
8755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard   allow for any demangler initialization that maybe necessary. */
8765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
8775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/*
8785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardenum demangling_styles
8795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardcplus_demangle_set_style (style)
8805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     enum demangling_styles style;
881070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
882070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  const struct demangler_engine *demangler = libiberty_demanglers;
883070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
884070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (; demangler->demangling_style != unknown_demangling; ++demangler)
885070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    if (style == demangler->demangling_style)
886070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      {
887070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	current_demangling_style = style;
888070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	return current_demangling_style;
889070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      }
890070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
891070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return unknown_demangling;
892070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
893070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard*/
894070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
895070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Do string name to style translation */
896070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
897070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/*
898070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardenum demangling_styles
899070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardcplus_demangle_name_to_style (name)
900070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char *name;
901070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
902070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  const struct demangler_engine *demangler = libiberty_demanglers;
903070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
904070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (; demangler->demangling_style != unknown_demangling; ++demangler)
905070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    if (strcmp (name, demangler->demangling_style_name) == 0)
906070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      return demangler->demangling_style;
907070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
908070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return unknown_demangling;
909070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
910070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard*/
911070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
912070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* char *cplus_demangle (const char *mangled, int options)
913070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
914070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   If MANGLED is a mangled function name produced by GNU C++, then
915070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   a pointer to a @code{malloc}ed string giving a C++ representation
916070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   of the name will be returned; otherwise NULL will be returned.
917070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   It is the caller's responsibility to free the string which
918070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   is returned.
919070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
920070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   The OPTIONS arg may contain one or more of the following bits:
921070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
922070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   	DMGL_ANSI	ANSI qualifiers such as `const' and `void' are
923070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard			included.
924070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	DMGL_PARAMS	Function parameters are included.
925070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
926070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   For example,
927070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
928070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Ai", DMGL_PARAMS)		=> "A::foo(int)"
929070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI)	=> "A::foo(int)"
930070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Ai", 0)			=> "A::foo"
931070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
932070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Afe", DMGL_PARAMS)		=> "A::foo(float,...)"
933070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
934070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   cplus_demangle ("foo__1Afe", 0)			=> "A::foo"
935070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
936070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   Note that any leading underscores, or other such characters prepended by
937070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   the compilation system, are presumed to have already been stripped from
938070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   MANGLED.  */
939070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
940070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardchar *
941070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel VeillardVG_(cplus_demangle) (mangled, options)
942070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char *mangled;
943070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     int options;
944070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
945070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char *ret;
946070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  struct work_stuff work[1];
947070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
948070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (current_demangling_style == no_demangling)
949070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    return xstrdup (mangled);
950070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
951070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  memset ((char *) work, 0, sizeof (work));
952070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->options = options;
953070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if ((work->options & DMGL_STYLE_MASK) == 0)
954070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
955070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
956070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* The V3 ABI demangling is implemented elsewhere.  */
957070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
958070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
959070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      ret = VG_(cplus_demangle_v3) (mangled/*, work->options*/);
960070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (ret || GNU_V3_DEMANGLING)
961070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	return ret;
962070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
963070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
964070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (JAVA_DEMANGLING)
965070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
966070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      ret = VG_(java_demangle_v3) (mangled);
967070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (ret)
968070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard        return ret;
969070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
970070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
971070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (GNAT_DEMANGLING)
972070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    return ada_demangle(mangled,options);
973070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
974070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  ret = internal_cplus_demangle (work, mangled);
975070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  squangle_mop_up (work);
976070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return (ret);
977070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
978070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
979070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
980070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Assuming *OLD_VECT points to an array of *SIZE objects of size
981070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
982070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   updating *OLD_VECT and *SIZE as necessary.  */
983070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
984070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic void
985070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardgrow_vect (old_vect, size, min_size, element_size)
986070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     void **old_vect;
987070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     size_t *size;
988070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     size_t min_size;
989070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     int element_size;
990070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
991070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (*size < min_size)
992070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
993070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      *size *= 2;
994070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (*size < min_size)
995070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	*size = min_size;
996070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      *old_vect = xrealloc (*old_vect, *size * element_size);
997070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
998070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
999070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1000070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Demangle ada names:
1001070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   1. Discard final __{DIGIT}+ or ${DIGIT}+
1002070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   2. Convert other instances of embedded "__" to `.'.
1003070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   3. Discard leading _ada_.
1004070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   4. Remove everything after first ___ if it is followed by 'X'.
1005070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   5. Put symbols that should be suppressed in <...> brackets.
1006070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   The resulting string is valid until the next call of ada_demangle.  */
1007070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1008070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic char *
1009070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardada_demangle (mangled, option)
1010070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char *mangled;
1011070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     int option ATTRIBUTE_UNUSED;
1012070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1013070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int i, j;
1014070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int len0;
1015070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  const char* p;
1016070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char *demangled = NULL;
1017070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int at_start_name;
1018070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int changed;
1019070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char *demangling_buffer = NULL;
1020070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  size_t demangling_buffer_size = 0;
1021070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1022070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  changed = 0;
1023070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1024070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (strncmp (mangled, "_ada_", 5) == 0)
1025070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1026070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      mangled += 5;
1027070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      changed = 1;
1028070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1029070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1030070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (mangled[0] == '_' || mangled[0] == '<')
1031070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    goto Suppress;
1032070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1033070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  p = strstr (mangled, "___");
1034070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (p == NULL)
1035070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    len0 = strlen (mangled);
1036070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else
1037070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1038070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (p[3] == 'X')
1039070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
1040070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  len0 = p - mangled;
1041070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  changed = 1;
1042070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
1043070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      else
1044070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	goto Suppress;
1045070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1046070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1047070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* Make demangled big enough for possible expansion by operator name.  */
1048070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  grow_vect ((void **) &(demangling_buffer),
1049070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     &demangling_buffer_size,  2 * len0 + 1,
1050070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     sizeof (char));
1051070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  demangled = demangling_buffer;
1052070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1053070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
1054070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
1055070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      ;
1056070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
1057070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      {
1058070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	len0 = i - 1;
1059070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	changed = 1;
1060070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      }
1061070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    else if (mangled[i] == '$')
1062070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      {
1063070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	len0 = i;
1064070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	changed = 1;
1065070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      }
1066070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  }
1067070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1068070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
1069070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard       i += 1, j += 1)
1070070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    demangled[j] = mangled[i];
1071070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1072070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  at_start_name = 1;
1073070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  while (i < len0)
1074070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1075070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      at_start_name = 0;
1076070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1077070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
1078070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
1079070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  demangled[j] = '.';
1080070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  changed = at_start_name = 1;
1081070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  i += 2; j += 1;
1082070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
1083070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      else
1084070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
1085070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  demangled[j] = mangled[i];
1086070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  i += 1;  j += 1;
1087070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
1088070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1089070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  demangled[j] = '\000';
1090070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1091070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0; demangled[i] != '\0'; i += 1)
1092070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
1093070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      goto Suppress;
1094070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1095070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (! changed)
1096070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    return NULL;
1097070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else
1098070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    return demangled;
1099070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1100070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard Suppress:
1101070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  grow_vect ((void **) &(demangling_buffer),
1102070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     &demangling_buffer_size,  strlen (mangled) + 3,
1103070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     sizeof (char));
1104070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  demangled = demangling_buffer;
1105070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (mangled[0] == '<')
1106070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     strcpy (demangled, mangled);
1107070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else
1108070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    sprintf (demangled, "<%s>", mangled);
1109070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1110070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return demangled;
1111070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1112070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1113070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* This function performs most of what cplus_demangle use to do, but
1114070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   to be able to demangle a name with a B, K or n code, we need to
1115070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   have a longer term memory of what types have been seen. The original
1116070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   now initializes and cleans up the squangle code info, while internal
1117070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard   calls go directly to this routine to avoid resetting that info. */
1118070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1119070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic char *
1120070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardinternal_cplus_demangle (work, mangled)
1121070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *work;
1122070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char *mangled;
1123070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1124070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1125070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  string decl;
1126070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int success = 0;
1127070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char *demangled = NULL;
1128070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int s1, s2, s3, s4;
1129070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  s1 = work->constructor;
1130070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  s2 = work->destructor;
1131070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  s3 = work->static_type;
1132070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  s4 = work->type_quals;
1133070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->constructor = work->destructor = 0;
1134070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->type_quals = TYPE_UNQUALIFIED;
1135070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->dllimported = 0;
1136070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1137070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if ((mangled != NULL) && (*mangled != '\0'))
1138070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1139070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      string_init (&decl);
11405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
1141070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      /* First check to see if gnu style demangling is active and if the
1142070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 string to be demangled contains a CPLUS_MARKER.  If so, attempt to
1143070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 recognize one of the gnu special forms rather than looking for a
1144070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 standard prefix.  In particular, don't worry about whether there
1145070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 is a "__" string in the mangled string.  Consider "_$_5__foo" for
1146070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 example.  */
1147070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1148070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1149070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
1150070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  success = gnu_special (work, &mangled, &decl);
11511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
11521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (!success)
11531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
11541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = demangle_prefix (work, &mangled, &decl);
11551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
11561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (success && (*mangled != '\0'))
11571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
11581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = demangle_signature (work, &mangled, &decl);
11591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
11601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (work->constructor == 2)
11611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        {
11621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          string_prepend (&decl, "global constructors keyed to ");
11631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          work->constructor = 0;
11641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        }
11651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else if (work->destructor == 2)
11661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        {
11671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          string_prepend (&decl, "global destructors keyed to ");
11681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          work->destructor = 0;
11691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        }
1170070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      else if (work->dllimported == 1)
1171070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard        {
1172070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard          string_prepend (&decl, "import stub for ");
1173070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard          work->dllimported = 0;
1174070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard        }
1175070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      demangled = mop_up (work, &decl, success);
1176070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1177070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->constructor = s1;
1178070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->destructor = s2;
1179070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->static_type = s3;
1180070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  work->type_quals = s4;
1181070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return demangled;
1182070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1183070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1184070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1185070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Clear out and squangling related storage */
1186070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic void
1187070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardsquangle_mop_up (work)
1188070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *work;
1189070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1190070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* clean up the B and K type mangling types. */
1191070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  forget_B_and_K_types (work);
1192070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (work -> btypevec != NULL)
1193070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1194070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      free ((char *) work -> btypevec);
1195070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1196070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (work -> ktypevec != NULL)
1197070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1198070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      free ((char *) work -> ktypevec);
1199070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1200070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1201070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1202070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1203070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Copy the work state and storage.  */
1204070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1205070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic void
1206070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardwork_stuff_copy_to_from (to, from)
1207070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *to;
1208070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *from;
1209070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1210070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int i;
1211070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1212070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  delete_work_stuff (to);
1213070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1214070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* Shallow-copy scalars.  */
1215070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  memcpy (to, from, sizeof (*to));
1216070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1217070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* Deep-copy dynamic storage.  */
1218070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (from->typevec_size)
1219070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    to->typevec
1220070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0]));
1221070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1222070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0; i < from->ntypes; i++)
1223070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1224070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      int len = strlen (from->typevec[i]) + 1;
1225070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1226070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      to->typevec[i] = xmalloc (len);
12275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      memcpy (to->typevec[i], from->typevec[i], len);
1228455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard    }
1229070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1230070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (from->ksize)
1231070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    to->ktypevec
1232070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0]));
1233070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1234070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0; i < from->numk; i++)
1235070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1236070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      int len = strlen (from->ktypevec[i]) + 1;
1237070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1238070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      to->ktypevec[i] = xmalloc (len);
1239455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard      memcpy (to->ktypevec[i], from->ktypevec[i], len);
1240118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    }
1241070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1242070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (from->bsize)
1243070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    to->btypevec
1244070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0]));
1245070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1246070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0; i < from->numb; i++)
1247070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1248070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      int len = strlen (from->btypevec[i]) + 1;
1249070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1250070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      to->btypevec[i] = xmalloc (len);
1251070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      memcpy (to->btypevec[i], from->btypevec[i], len);
1252455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard    }
1253070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1254070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (from->ntmpl_args)
1255070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    to->tmpl_argvec
1256070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      = xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0]));
1257070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1258070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  for (i = 0; i < from->ntmpl_args; i++)
1259070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1260070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      int len = strlen (from->tmpl_argvec[i]) + 1;
1261070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1262070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      to->tmpl_argvec[i] = xmalloc (len);
1263070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1264070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1265070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1266070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (from->previous_argument)
1267070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1268070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      to->previous_argument = (string*) xmalloc (sizeof (string));
1269070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      string_init (to->previous_argument);
1270070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      string_appends (to->previous_argument, from->previous_argument);
1271070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1272070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1273070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1274070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1275455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard/* Delete dynamic stuff in work_stuff that is not to be re-used.  */
1276455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard
1277070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic void
1278070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillarddelete_non_B_K_work_stuff (work)
1279070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *work;
1280070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1281070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* Discard the remembered types, if any.  */
1282070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1283070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  forget_types (work);
1284070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (work -> typevec != NULL)
1285070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1286070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      free ((char *) work -> typevec);
1287070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      work -> typevec = NULL;
1288070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      work -> typevec_size = 0;
1289070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1290070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (work->tmpl_argvec)
1291070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1292070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      int i;
1293070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1294d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      for (i = 0; i < work->ntmpl_args; i++)
1295d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	if (work->tmpl_argvec[i])
1296d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  free ((char*) work->tmpl_argvec[i]);
1297d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1298d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      free ((char*) work->tmpl_argvec);
1299d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      work->tmpl_argvec = NULL;
1300d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard    }
1301d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard  if (work->previous_argument)
1302d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard    {
1303d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      string_delete (work->previous_argument);
1304d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      free ((char*) work->previous_argument);
1305d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard      work->previous_argument = NULL;
1306d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard    }
1307d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard}
1308d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1309d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1310d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard/* Delete all dynamic storage in work_stuff.  */
1311d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillardstatic void
1312d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillarddelete_work_stuff (work)
1313d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard     struct work_stuff *work;
1314d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard{
1315d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard  delete_non_B_K_work_stuff (work);
1316d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard  squangle_mop_up (work);
1317070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1318d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1319d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1320d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard/* Clear out any mangled storage */
1321d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1322d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillardstatic char *
1323d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillardmop_up (work, declp, success)
1324d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard     struct work_stuff *work;
1325d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard     string *declp;
1326d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard     int success;
1327d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard{
1328d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard  char *demangled = NULL;
1329d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1330070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  delete_non_B_K_work_stuff (work);
1331070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1332070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  /* If demangling was successful, ensure that the demangled string is null
1333070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     terminated and return it.  Otherwise, free the demangling decl.  */
1334070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1335070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (!success)
1336070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1337070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      string_delete (declp);
1338070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1339070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else
1340070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1341070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      string_appendn (declp, "", 1);
1342070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      demangled = declp->b;
1343070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
1344070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  return (demangled);
1345070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}
1346070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1347070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/*
1348070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1349070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel VeillardLOCAL FUNCTION
1350070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1351070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	demangle_signature -- demangle the signature part of a mangled name
1352070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1353070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel VeillardSYNOPSIS
1354070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1355070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	static int
1356070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	demangle_signature (struct work_stuff *work, const char **mangled,
1357070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard			    string *declp);
1358070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1359070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel VeillardDESCRIPTION
1360070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1361070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	Consume and demangle the signature portion of the mangled name.
1362070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1363070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	DECLP is the string where demangled output is being built.  At
1364070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	entry it contains the demangled root name from the mangled name
1365070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	prefix.  I.E. either a demangled operator name or the root function
1366070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	name.  In some special cases, it may contain nothing.
1367070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1368070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	*MANGLED points to the current unconsumed location in the mangled
1369070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	name.  As tokens are consumed and demangling is performed, the
1370070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	pointer is updated to continuously point at the next token to
1371070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	be consumed.
1372070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1373070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	Demangling GNU style mangled names is nasty because there is no
1374070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	explicit token that marks the start of the outermost function
1375070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	argument list.  */
1376070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1377070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int
1378070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillarddemangle_signature (work, mangled, declp)
1379070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *work;
1380070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char **mangled;
1381070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     string *declp;
1382070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
1383070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int success = 1;
1384070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int func_done = 0;
1385070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int expect_func = 0;
1386070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int expect_return_type = 0;
1387070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  const char *oldmangled = NULL;
1388070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  string trawname;
1389070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  string tname;
1390070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1391455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard  while (success && (**mangled != '\0'))
1392070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
1393070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      switch (**mangled)
1394455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard	{
1395d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	case 'Q':
1396d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  oldmangled = *mangled;
1397d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  success = demangle_qualified (work, mangled, declp, 1, 0);
1398d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  if (success)
1399d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    remember_type (work, oldmangled, *mangled - oldmangled);
1400d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1401d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    expect_func = 1;
1402d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  oldmangled = NULL;
1403d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  break;
1404d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1405d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard        case 'K':
1406d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  oldmangled = *mangled;
1407d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  success = demangle_qualified (work, mangled, declp, 1, 0);
1408d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1409d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    {
1410d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	      expect_func = 1;
1411d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    }
1412d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  oldmangled = NULL;
1413d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  break;
1414d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1415d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	case 'S':
1416d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  /* Static member function */
1417d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  if (oldmangled == NULL)
1418d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    {
1419d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	      oldmangled = *mangled;
1420d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    }
1421d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  (*mangled)++;
1422d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  work -> static_type = 1;
1423d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  break;
1424d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard
1425d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	case 'C':
1426455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard	case 'V':
1427455cc07308c673b6714e2f5670c2091a1dab95dcDaniel Veillard	case 'u':
1428070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  work->type_quals |= code_for_qualifier (**mangled);
1429070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
143080b19092f24410a6b869abf519227686e8f207caDaniel Veillard	  /* a qualified member function */
143180b19092f24410a6b869abf519227686e8f207caDaniel Veillard	  if (oldmangled == NULL)
1432070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    oldmangled = *mangled;
1433070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  (*mangled)++;
1434070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1435070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1436070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case 'L':
1437070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* Local class name follows after "Lnnn_" */
1438070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (HP_DEMANGLING)
1439070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1440070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      while (**mangled && (**mangled != '_'))
1441070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		(*mangled)++;
14425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      if (!**mangled)
1443070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		success = 0;
1444070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      else
1445070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		(*mangled)++;
1446070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1447070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  else
1448070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    success = 0;
1449070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1450070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1451070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case '0': case '1': case '2': case '3': case '4':
1452070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case '5': case '6': case '7': case '8': case '9':
1453070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (oldmangled == NULL)
1454dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel Veillard	    {
1455118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	      oldmangled = *mangled;
1456070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1457070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard          work->temp_start = -1; /* uppermost call to demangle_class */
1458070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  success = demangle_class (work, mangled, declp);
1459070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (success)
1460d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    {
1461d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	      remember_type (work, oldmangled, *mangled - oldmangled);
1462d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	    }
1463d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard	  if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1464070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1465070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard              /* EDG and others will have the "F", so we let the loop cycle
1466070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard                 if we are looking at one. */
1467070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard              if (**mangled != 'F')
1468070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard                 expect_func = 1;
1469070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1470070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  oldmangled = NULL;
1471070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1472070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1473070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case 'B':
1474070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  {
1475070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    string s;
1476070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    success = do_type (work, mangled, &s);
147780b19092f24410a6b869abf519227686e8f207caDaniel Veillard	    if (success)
147880b19092f24410a6b869abf519227686e8f207caDaniel Veillard	      {
147980b19092f24410a6b869abf519227686e8f207caDaniel Veillard		string_append (&s, SCOPE_STRING (work));
1480070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		string_prepends (declp, &s);
1481070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      }
1482070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    oldmangled = NULL;
1483070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    expect_func = 1;
1484070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  }
1485070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1486070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1487070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case 'F':
1488070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* Function */
1489070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* ARM/HP style demangling includes a specific 'F' character after
1490070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     the class name.  For GNU style, it is just implied.  So we can
1491070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     safely just consume any 'F' at this point and be compatible
1492070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     with either style.  */
1493070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1494070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  oldmangled = NULL;
1495070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  func_done = 1;
1496070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  (*mangled)++;
1497070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1498070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* For lucid/ARM/HP style we have to forget any types we might
1499070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     have remembered up to this point, since they were not argument
1500070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     types.  GNU style considers all types seen as available for
1501070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     back references.  See comment in demangle_args() */
1502070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1503070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1504070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1505070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      forget_types (work);
1506070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1507070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  success = demangle_args (work, mangled, declp);
1508070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* After picking off the function args, we expect to either
1509070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     find the function return type (preceded by an '_') or the
1510070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	     end of the string. */
1511070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1512070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1513070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      ++(*mangled);
1514070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard              /* At this level, we do not care about the return type. */
1515070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard              success = do_type (work, mangled, &tname);
1516070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard              string_delete (&tname);
1517070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard            }
1518070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1519070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1520070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1521070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case 't':
1522070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  /* G++ Template */
1523070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_init(&trawname);
1524070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_init(&tname);
1525070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (oldmangled == NULL)
1526070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1527070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      oldmangled = *mangled;
1528070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1529070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  success = demangle_template (work, mangled, &tname,
1530070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard				       &trawname, 1, 1);
1531070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (success)
1532070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1533070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      remember_type (work, oldmangled, *mangled - oldmangled);
1534070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1535070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_append (&tname, SCOPE_STRING (work));
1536070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1537070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_prepends(declp, &tname);
1538070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (work -> destructor & 1)
1539070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
1540070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      string_prepend (&trawname, "~");
1541070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      string_appends (declp, &trawname);
1542070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      work->destructor -= 1;
1543070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1544070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if ((work->constructor & 1) || (work->destructor & 1))
154580b19092f24410a6b869abf519227686e8f207caDaniel Veillard	    {
154680b19092f24410a6b869abf519227686e8f207caDaniel Veillard	      string_appends (declp, &trawname);
1547070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      work->constructor -= 1;
1548070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
1549070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_delete(&trawname);
1550070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_delete(&tname);
1551070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  oldmangled = NULL;
1552070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  expect_func = 1;
1553070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  break;
1554070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
1555070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	case '_':
1556a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	  if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1557a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	    {
1558a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      /* Read the return type. */
1559a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      string return_type;
1560a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      string_init (&return_type);
1561a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard
1562a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      (*mangled)++;
1563a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      success = do_type (work, mangled, &return_type);
1564a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      APPEND_BLANK (&return_type);
1565a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard
1566a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      string_prepends (declp, &return_type);
1567a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      string_delete (&return_type);
1568a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      break;
156976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	    }
1570a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	  else
1571a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	    /* At the outermost level, we cannot have a return type specified,
1572a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	       so if we run into another '_' at this point we are dealing with
1573a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	       a mangled name that is either bogus, or has been mangled by
157476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	       some algorithm we don't know how to deal with.  So just
1575a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	       reject the entire demangling.  */
1576a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard            /* However, "_nnn" is an expected suffix for alternate entry point
1577a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard               numbered nnn for a function, with HP aCC, so skip over that
1578a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard               without reporting failure. pai/1997-09-04 */
157996a4b2524590c4c8fe776dfcbf4574737f6206b6Daniel Veillard            if (HP_DEMANGLING)
158096a4b2524590c4c8fe776dfcbf4574737f6206b6Daniel Veillard              {
158191feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik                (*mangled)++;
158291feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik                while (**mangled && ISDIGIT ((unsigned char)**mangled))
158391feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik                  (*mangled)++;
158491feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik              }
158591feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik            else
158691feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      success = 0;
158791feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	  break;
158891feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik
158991feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	case 'H':
159091feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
159191feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    {
159291feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      /* A G++ template function.  Read the template arguments. */
159391feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      success = demangle_template (work, mangled, declp, 0, 0,
159491feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik					   0);
159591feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      if (!(work->constructor & 1))
159691feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik		expect_return_type = 1;
159791feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      (*mangled)++;
159891feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      break;
159991feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    }
160091feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	  else
160191feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    /* fall through */
160291feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    {;}
160391feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik
160491feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	default:
160591feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
160691feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    {
160791feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      /* Assume we have stumbled onto the first outermost function
160891feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik		 argument token, and start processing args.  */
160991feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      func_done = 1;
161091feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	      success = demangle_args (work, mangled, declp);
161191feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    }
161291feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	  else
161391feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik	    {
1614b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	      /* Non-GNU demanglers use a specific token to mark the start
1615b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		 of the outermost function argument tokens.  Typically 'F',
1616b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		 for ARM/HP-demangling, for example.  So if we find something
1617b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		 we are not prepared for, it must be an error.  */
1618b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	      success = 0;
1619b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	    }
1620b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  break;
162101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	}
1622b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      /*
1623b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	if (AUTO_DEMANGLING || GNU_DEMANGLING)
1624b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	*/
1625b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      {
1626b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	if (success && expect_func)
1627b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  {
162876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	    func_done = 1;
1629b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard              if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1630b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard                {
163176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack                  forget_types (work);
1632b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard                }
1633b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	    success = demangle_args (work, mangled, declp);
1634b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	    /* Since template include the mangling of their return types,
1635b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	       we must set expect_func to 0 so that we don't try do
1636b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	       demangle more arguments the next time we get here.  */
1637b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	    expect_func = 0;
1638b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  }
1639b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      }
1640b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    }
1641b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (success && !func_done)
1642b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    {
164376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack      if (AUTO_DEMANGLING || GNU_DEMANGLING)
1644b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
1645b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1646b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	     bar__3fooi is 'foo::bar(int)'.  We get here when we find the
1647b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	     first case, and need to ensure that the '(void)' gets added to
1648b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	     the current declp.  Note that with ARM/HP, the first case
1649b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	     represents the name of a static data member 'foo::bar',
1650b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	     which is in the current declp, so we leave it alone.  */
1651b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  success = demangle_args (work, mangled, declp);
1652b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	}
165376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    }
1654b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (success && PRINT_ARG_TYPES)
165576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    {
1656b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      if (work->static_type)
1657b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	string_append (declp, " static");
1658b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      if (work->type_quals != TYPE_UNQUALIFIED)
1659b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
1660b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  APPEND_BLANK (declp);
1661b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  string_append (declp, qualifier_string (work->type_quals));
1662b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	}
1663b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    }
1664b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
1665b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  return (success);
166628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard}
166728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
166828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard#if 0
166928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
167028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillardstatic int
167128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillarddemangle_method_args (work, mangled, declp)
167228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     struct work_stuff *work;
167328c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     const char **mangled;
167428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     string *declp;
1675a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard{
1676a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard  int success = 0;
167728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
167828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  if (work -> static_type)
167928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    {
168028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard      string_append (declp, *mangled + 1);
168128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard      *mangled += strlen (*mangled);
168228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard      success = 1;
1683580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    }
168428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  else
168528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    {
168628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard      success = demangle_args (work, mangled, declp);
168728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    }
168828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  return (success);
168928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard}
169028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
169128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard#endif
16926fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillard
16936fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillardstatic int
16946fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillarddemangle_template_template_parm (work, mangled, tname)
169528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     struct work_stuff *work;
169628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     const char **mangled;
169728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard     string *tname;
169828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard{
169976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack  int i;
170028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  int r;
170176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack  int need_comma = 0;
170228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  int success = 1;
170328c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  string temp;
170476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack
170528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  string_append (tname, "template <");
170628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  /* get size of template parameter list */
170728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard  if (get_count (mangled, &r))
170876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    {
170928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard      for (i = 0; i < r; i++)
171028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	{
171128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	  if (need_comma)
171228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    {
1713a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      string_append (tname, ", ");
171428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    }
171528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
171628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    /* Z for type parameters */
171728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    if (**mangled == 'Z')
171828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	      {
171928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard		(*mangled)++;
172028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard		string_append (tname, "class");
172128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	      }
172228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	      /* z for template parameters */
172328c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    else if (**mangled == 'z')
172428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	      {
17256fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillard		(*mangled)++;
172628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard		success =
172728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard		  demangle_template_template_parm (work, mangled, tname);
17286fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillard		if (!success)
17296fc5db0090e7639a78cedee824cd4af8670b7210Daniel Veillard		  {
1730a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard		    break;
1731a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard		  }
1732a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard	      }
173328c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	    else
173428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard	      {
173528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard		/* temp is initialized in do_type */
1736e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		success = do_type (work, mangled, &temp);
1737e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		if (success)
1738e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		  {
1739e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		    string_appends (tname, &temp);
1740e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		  }
1741e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		string_delete(&temp);
1742e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		if (!success)
1743e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		  {
1744e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		    break;
1745e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		  }
1746e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	      }
1747e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  need_comma = 1;
1748e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	}
1749e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1750e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
1751e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  if (tname->p[-1] == '>')
1752e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    string_append (tname, " ");
1753e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  string_append (tname, "> class");
1754e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  return (success);
1755e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard}
1756e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1757e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillardstatic int
1758e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillarddemangle_expression (work, mangled, s, tk)
1759e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     struct work_stuff *work;
1760e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     const char** mangled;
1761e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     string* s;
1762e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     type_kind_t tk;
1763e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard{
1764e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  int need_operator = 0;
1765e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  int success;
1766e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1767e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  success = 1;
1768e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  string_appendn (s, "(", 1);
1769e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  (*mangled)++;
1770e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  while (success && **mangled != 'W' && **mangled != '\0')
1771e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    {
1772e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      if (need_operator)
1773e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	{
1774e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  size_t i;
1775e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  size_t len;
1776e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1777e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  success = 0;
1778e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1779e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  len = strlen (*mangled);
1780e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1781e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  for (i = 0; i < (size_t)ARRAY_SIZE (optable); ++i)
1782e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	    {
1783e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	      size_t l = strlen (optable[i].in);
1784e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
1785e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	      if (l <= len
1786b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		  && memcmp (optable[i].in, *mangled, l) == 0)
17874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		{
17884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  string_appendn (s, " ", 1);
17894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  string_append (s, optable[i].out);
1790c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard		  string_appendn (s, " ", 1);
1791b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		  success = 1;
17924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		  (*mangled) += l;
1793b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard		  break;
17944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
179501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    }
17964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  if (!success)
17984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
17994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
1800b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      else
18011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	need_operator = 1;
18021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      success = demangle_template_value_parm (work, mangled, s, tk);
18044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
1805b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
1806d3b9cd88d5d76e44ca54965d651d486485fced0dDaniel Veillard  if (**mangled != 'W')
18074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    success = 0;
18084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  else
180901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
18104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      string_appendn (s, ")", 1);
18111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled)++;
18125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
1813eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillard
1814eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillard  return success;
1815eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillard}
1816eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillard
1817eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillardstatic int
1818eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillarddemangle_integral_value (work, mangled, s)
1819eebd633b916b99bd1f0e6e038afdc1d933eeef60Daniel Veillard     struct work_stuff *work;
18204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     const char** mangled;
18211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string* s;
1822b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard{
182391feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik  int success;
182401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
182591feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik  if (**mangled == 'E')
182691feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik    success = demangle_expression (work, mangled, s, tk_integral);
182791feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik  else if (**mangled == 'Q' || **mangled == 'K')
182891feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik    success = demangle_qualified (work, mangled, s, 0, 1);
182991feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik  else
183091feaf847728bed1b1d2c3cee37e9b88fe1a8da3Kasimier T. Buchcik    {
18311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      int value;
18321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* By default, we let the number decide whether we shall consume an
1834b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	 underscore.  */
1835b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      int consume_following_underscore = 0;
183601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      int leave_following_underscore = 0;
18372f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack
18381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      success = 0;
18392f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack
18402f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack      /* Negative numbers are indicated with a leading `m'.  */
18412f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack      if (**mangled == 'm')
1842b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
18431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, "-", 1);
18441516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  (*mangled)++;
18451516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	}
18461516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard      else if (mangled[0][0] == '_' && mangled[0][1] == 'm')
18471516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	{
18481516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  /* Since consume_count_with_underscores does not handle the
18491516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	     `m'-prefix we must do it here, using consume_count and
18501516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	     adjusting underscores: we have to consume the underscore
18511516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	     matching the prepended one.  */
18521516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  consume_following_underscore = 1;
18531516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  string_appendn (s, "-", 1);
18541516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  (*mangled) += 2;
18551516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	}
18561516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard      else if (**mangled == '_')
18571516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	{
18581516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  /* Do not consume a following underscore;
18591516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	     consume_following_underscore will consume what should be
18601516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	     consumed.  */
18611516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	  leave_following_underscore = 1;
18621516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard	}
18631516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard
18641516d5b3478e90e35ac7e94fea9b2ab5156dfb0bDaniel Veillard      /* We must call consume_count if we expect to remove a trailing
18651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	 underscore, since consume_count_with_underscores expects
18661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	 the leading underscore (that we consumed) if it is to handle
18671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	 multi-digit numbers.  */
18681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (consume_following_underscore)
18691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	value = consume_count (mangled);
18701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
18711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	value = consume_count_with_underscores (mangled);
18721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (value != -1)
18741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
18751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  char buf[INTBUF_SIZE];
18761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  sprintf (buf, "%d", value);
18771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_append (s, buf);
18781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* Numbers not otherwise delimited, might have an underscore
18801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	     appended as a delimeter, which we should skip.
18811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	     ??? This used to always remove a following underscore, which
18831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	     is wrong.  If other (arbitrary) cases are followed by an
18841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	     underscore, we need to do something more radical.  */
18851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if ((value > 9 || consume_following_underscore)
18871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      && ! leave_following_underscore
18881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      && **mangled == '_')
18891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    (*mangled)++;
18901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* All is well.  */
18921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = 1;
18931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
18941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
18951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return success;
18971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
18981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
18991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/* Demangle the real value in MANGLED.  */
19001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
19011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
19021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_real_value (work, mangled, s)
19031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
19041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
19051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string* s;
19061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
1907b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (**mangled == 'E')
1908b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    return demangle_expression (work, mangled, s, tk_real);
1909b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
1910b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (**mangled == 'm')
1911b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    {
1912b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_appendn (s, "-", 1);
1913b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
1914b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    }
191501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  while (ISDIGIT ((unsigned char)**mangled))
19161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
1917b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_appendn (s, *mangled, 1);
19181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled)++;
19191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
1920b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (**mangled == '.') /* fraction */
19211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
19221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appendn (s, ".", 1);
19231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled)++;
19241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (ISDIGIT ((unsigned char)**mangled))
19251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
19261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, *mangled, 1);
19271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
19281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
19291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
19301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (**mangled == 'e') /* exponent */
19311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
19321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appendn (s, "e", 1);
19331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled)++;
19341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (ISDIGIT ((unsigned char)**mangled))
19351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
19361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, *mangled, 1);
19371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
19381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
19391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
19401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
19411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return 1;
19421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
19431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
19441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
19451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_template_value_parm (work, mangled, s, tk)
19461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
19471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
19481ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string* s;
19491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     type_kind_t tk;
19501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
19511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 1;
19521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
19531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (**mangled == 'Y')
19541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
19551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* The next argument is a template parameter. */
19561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      int idx;
19571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
19581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled)++;
19591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      idx = consume_count_with_underscores (mangled);
19601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (idx == -1
19611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  || (work->tmpl_argvec && idx >= work->ntmpl_args)
19621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  || consume_count_with_underscores (mangled) == -1)
19631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	return -1;
19641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (work->tmpl_argvec)
19651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_append (s, work->tmpl_argvec[idx]);
19661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
19671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_append_template_idx (s, idx);
19681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
19691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (tk == tk_integral)
19701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    success = demangle_integral_value (work, mangled, s);
19711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (tk == tk_char)
19721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
19731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      char tmp[2];
19741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      int val;
19751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (**mangled == 'm')
19761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
19771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, "-", 1);
19781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
19791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
19801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appendn (s, "'", 1);
19811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      val = consume_count(mangled);
19821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (val <= 0)
19831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	success = 0;
19841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
19851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
19861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  tmp[0] = (char)val;
19871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  tmp[1] = '\0';
19881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, &tmp[0], 1);
19891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_appendn (s, "'", 1);
19901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
19911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
19921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (tk == tk_bool)
19931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
19941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      int val = consume_count (mangled);
19951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (val == 0)
19961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_appendn (s, "false", 5);
19971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else if (val == 1)
19981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_appendn (s, "true", 4);
19991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
20001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	success = 0;
20011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
20021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (tk == tk_real)
20031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    success = demangle_real_value (work, mangled, s);
20041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (tk == tk_pointer || tk == tk_reference)
20051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
20061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (**mangled == 'Q')
20071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	success = demangle_qualified (work, mangled, s,
20081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard				      /*isfuncname=*/0,
20091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard				      /*append=*/1);
20101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
20111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
20121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  int symbol_len  = consume_count (mangled);
20131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (symbol_len == -1)
2014d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard	    return -1;
20151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (symbol_len == 0)
201601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    string_appendn (s, "0", 1);
20171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  else
20181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
20191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      char *p = xmalloc (symbol_len + 1), *q;
20201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      strncpy (p, *mangled, symbol_len);
20211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      p [symbol_len] = '\0';
20221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      /* We use cplus_demangle here, rather than
20231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		 internal_cplus_demangle, because the name of the entity
20241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		 mangled here does not make use of any of the squangling
20251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		 or type-code information we have built up thus far; it is
20261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		 mangled independently.  */
2027d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard	      q = VG_(cplus_demangle) (p, work->options);
20281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (tk == tk_pointer)
20291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		string_appendn (s, "&", 1);
20301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      /* FIXME: Pointer-to-member constants should get a
20311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		 qualifying class name here.  */
20321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (q)
20331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		{
20341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  string_append (s, q);
20351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  free (q);
20361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		}
20371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      else
20381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		string_append (s, p);
20391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      free (p);
20401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
20411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  *mangled += symbol_len;
20421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
20431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
20441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return success;
20461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
20471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20481ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/* Demangle the template name in MANGLED.  The full name of the
20491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   template (e.g., S<int>) is placed in TNAME.  The name without the
20501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
20511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   non-NULL.  If IS_TYPE is nonzero, this template is a type template,
20521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   not a function template.  If both IS_TYPE and REMEMBER are nonzero,
20531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   the template is remembered in the list of back-referenceable
20541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   types.  */
20551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
20571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_template (work, mangled, tname, trawname, is_type, remember)
20581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
20591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
20601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *tname;
20611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *trawname;
20621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     int is_type;
20631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     int remember;
20641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
20651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int i;
20661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int r;
20671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int need_comma = 0;
20681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 0;
20691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *start;
20701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int is_java_array = 0;
20711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string temp;
207276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack  int bindex = 0;
20731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  (*mangled)++;
20751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (is_type)
20761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
20771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (remember)
20781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	bindex = register_Btype (work);
20791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      start = *mangled;
20801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* get template name */
20811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (**mangled == 'z')
20821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
20831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  int idx;
20841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
20851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
20861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  idx = consume_count_with_underscores (mangled);
20881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (idx == -1
20891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      || (work->tmpl_argvec && idx >= work->ntmpl_args)
20901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      || consume_count_with_underscores (mangled) == -1)
20911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    return (0);
20921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
20931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (work->tmpl_argvec)
20941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
20951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_append (tname, work->tmpl_argvec[idx]);
20961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (trawname)
20971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		string_append (trawname, work->tmpl_argvec[idx]);
20981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
2099b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  else
21001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_append_template_idx (tname, idx);
21021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (trawname)
21031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		string_append_template_idx (trawname, idx);
21041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
21061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
21071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
21081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if ((r = consume_count (mangled)) <= 0
21091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      || (int) strlen (*mangled) < r)
21101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      return (0);
21121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
2113b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  is_java_array = (work -> options & DMGL_JAVA)
21141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    && strncmp (*mangled, "JArray1Z", 8) == 0;
21151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (! is_java_array)
21161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_appendn (tname, *mangled, r);
21181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (trawname)
21201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    string_appendn (trawname, *mangled, r);
21211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  *mangled += r;
21221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
21231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
21241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (!is_java_array)
21251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    string_append (tname, "<");
21261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* get size of template parameter list */
2127b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (!get_count (mangled, &r))
21281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
21291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      return (0);
21301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
21311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (!is_type)
21321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
21331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* Create an array for saving the template argument values. */
21341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
2135b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      work->ntmpl_args = r;
21361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      for (i = 0; i < r; i++)
2137df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	work->tmpl_argvec[i] = 0;
2138df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard    }
2139df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard  for (i = 0; i < r; i++)
2140df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard    {
2141df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard      if (need_comma)
2142df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	{
2143df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	  string_append (tname, ", ");
2144df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	}
2145df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard      /* Z for type parameters */
2146df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard      if (**mangled == 'Z')
2147df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	{
2148df292f7aa9fe80ce61109871df002aa2a64e2939Daniel Veillard	  (*mangled)++;
21491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* temp is initialized in do_type */
21501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = do_type (work, mangled, &temp);
21511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (success)
21521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_appends (tname, &temp);
21541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
21551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (!is_type)
21561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		{
21571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  /* Save the template argument. */
21581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  int len = temp.p - temp.b;
21591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  work->tmpl_argvec[i] = xmalloc (len + 1);
21601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  memcpy (work->tmpl_argvec[i], temp.b, len);
21611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  work->tmpl_argvec[i][len] = '\0';
21621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		}
21631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_delete(&temp);
21651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!success)
21661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      break;
21681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
21701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* z for template parameters */
21711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else if (**mangled == 'z')
21721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
21731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  int r2;
21741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  (*mangled)++;
21751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = demangle_template_template_parm (work, mangled, tname);
21761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
21771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (success
21781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      && (r2 = consume_count (mangled)) > 0
21791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      && (int) strlen (*mangled) >= r2)
21801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
21811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_append (tname, " ");
21821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_appendn (tname, *mangled, r2);
21831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (!is_type)
21841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		{
21851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  /* Save the template argument. */
21861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  int len = r2;
21871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  work->tmpl_argvec[i] = xmalloc (len + 1);
21881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  memcpy (work->tmpl_argvec[i], *mangled, len);
21891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		  work->tmpl_argvec[i][len] = '\0';
21901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		}
21911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      *mangled += r2;
21921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!success)
21941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
2195b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	      break;
21961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
21971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
21981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
21991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
22001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string  param;
22011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string* s;
22021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* otherwise, value parameter */
22041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* temp is initialized in do_type */
22061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = do_type (work, mangled, &temp);
2207b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  string_delete(&temp);
22081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!success)
22091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    break;
22101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!is_type)
22121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
22131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      s = &param;
22141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_init (s);
22151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
22161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  else
22171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    s = tname;
22181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  success = demangle_template_value_parm (work, mangled, s,
22201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard						  (type_kind_t) success);
22211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!success)
22231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
22241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (!is_type)
22251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		string_delete (s);
22261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      success = 0;
22271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      break;
22281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
22291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (!is_type)
22311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
22321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      int len = s->p - s->b;
22331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      work->tmpl_argvec[i] = xmalloc (len + 1);
22341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      memcpy (work->tmpl_argvec[i], s->b, len);
22351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      work->tmpl_argvec[i][len] = '\0';
22361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_appends (tname, s);
22381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_delete (s);
22391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
22401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
22411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      need_comma = 1;
22421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
2243b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (is_java_array)
22441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
22451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (tname, "[]");
22466e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
22476e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  else
22486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
22496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (tname->p[-1] == '>')
22506e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	string_append (tname, " ");
22511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (tname, ">");
22521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
22531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (is_type && remember)
22551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
22561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /*
22581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    if (work -> static_type)
22591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
22601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    string_append (declp, *mangled + 1);
22611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    *mangled += strlen (*mangled);
22621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    success = 1;
22631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
22641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    else
22651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
2266b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    success = demangle_args (work, mangled, declp);
22671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
22681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
22691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    */
22701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return (success);
22711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
22721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
22731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
22741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardarm_pt (work, mangled, n, anchor, args)
22751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
2276249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard     const char *mangled;
22771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     int n;
22781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **anchor, **args;
22791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
22801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Check if ARM template with "__pt__" in it ("parameterized type") */
22811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
22821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
22831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
22841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      int len;
22851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      *args = *anchor + 6;
22861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      len = consume_count (args);
22871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (len == -1)
22881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	return 0;
22891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (*args + len == mangled + n && **args == '_')
22901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
22911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  ++*args;
22921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  return 1;
22931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
22941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
22951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (AUTO_DEMANGLING || EDG_DEMANGLING)
22961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
22971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if ((*anchor = strstr (mangled, "__tm__"))
22981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          || (*anchor = strstr (mangled, "__ps__"))
22991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          || (*anchor = strstr (mangled, "__pt__")))
23001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        {
23011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          int len;
23021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          *args = *anchor + 6;
23031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          len = consume_count (args);
23041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (len == -1)
23051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    return 0;
23061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          if (*args + len == mangled + n && **args == '_')
2307a1a9d0410000cc69874e53e438b250037d3e14cdDaniel Veillard            {
23081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              ++*args;
23091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              return 1;
23101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            }
23111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        }
2312b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      else if ((*anchor = strstr (mangled, "__S")))
23131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        {
23141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard 	  int len;
23151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard 	  *args = *anchor + 3;
23161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard 	  len = consume_count (args);
23171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (len == -1)
23181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    return 0;
23191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard 	  if (*args + len == mangled + n && **args == '_')
23201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            {
23211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              ++*args;
23221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard 	      return 1;
23231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            }
23241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        }
23251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
23261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return 0;
23281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
23291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic void
23311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_arm_hp_template (work, mangled, n, declp)
23321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
23331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
23341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     int n;
23351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *declp;
23361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
23371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *p;
23381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *args;
23391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *e = *mangled + n;
23401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string arg;
23411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
23431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     template args */
23441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
23451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
23461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      char *start_spec_args = NULL;
23471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23481ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* First check for and omit template specialization pseudo-arguments,
23491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard         such as in "Spec<#1,#1.*>" */
23501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      start_spec_args = strchr (*mangled, '<');
23511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (start_spec_args && (start_spec_args - *mangled < n))
23521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        string_appendn (declp, *mangled, start_spec_args - *mangled);
23531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      else
23541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        string_appendn (declp, *mangled, n);
23551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled) += n + 1;
23561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_init (&arg);
23571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (work->temp_start == -1) /* non-recursive call */
23581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        work->temp_start = declp->p - declp->b;
23591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (declp, "<");
23601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (1)
23611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        {
23621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          string_clear (&arg);
23631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          switch (**mangled)
23641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            {
23651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              case 'T':
23661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                /* 'T' signals a type parameter */
23671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                (*mangled)++;
23681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                if (!do_type (work, mangled, &arg))
23691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                  goto hpacc_template_args_done;
23701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                break;
23711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              case 'U':
23731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              case 'S':
23741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                /* 'U' or 'S' signals an integral value */
23751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                if (!do_hpacc_template_const_value (work, mangled, &arg))
23761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                  goto hpacc_template_args_done;
23771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                break;
23781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
23791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              case 'A':
2380560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard                /* 'A' signals a named constant expression (literal) */
23811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                if (!do_hpacc_template_literal (work, mangled, &arg))
238211c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard                  goto hpacc_template_args_done;
238311c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard                break;
238411c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard
238511c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard              default:
238611c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard                /* Today, 1997-09-03, we have only the above types
238711c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard                   of template parameters */
2388560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard                /* FIXME: maybe this should fail and return null */
23891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                goto hpacc_template_args_done;
239011c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard            }
239111c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard          string_appends (declp, &arg);
239211c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard         /* Check if we're at the end of template args.
239311c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard             0 if at end of static member of template class,
239411c466abe481325aac9572cae8ca0b9040c58820Daniel Veillard             _ if done with template args for a function */
23951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          if ((**mangled == '\000') || (**mangled == '_'))
23961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            break;
23971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          else
23981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            string_append (declp, ",");
23991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        }
24001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    hpacc_template_args_done:
24011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (declp, ">");
2402560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      string_delete (&arg);
2403f34a20e69dc675cd23d3eb558cad135ea280f472Daniel Veillard      if (**mangled == '_')
24041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        (*mangled)++;
2405560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      return;
24061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
24071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* ARM template? (Also handles HP cfront extensions) */
24081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (arm_pt (work, *mangled, n, &p, &args))
24091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
24101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string type_str;
24111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
2412560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      string_init (&arg);
24131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appendn (declp, *mangled, p - *mangled);
24141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (work->temp_start == -1)  /* non-recursive call */
24151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	work->temp_start = declp->p - declp->b;
241670bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard      string_append (declp, "<");
2417560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      /* should do error checking here */
24181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (args < e) {
24191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_clear (&arg);
24201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
24211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	/* Check for type or literal here */
24221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	switch (*args)
24231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  {
24241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    /* HP cfront extensions to ARM for template args */
24251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2426d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard	    /* FIXME: We handle only numeric literals for HP cfront */
24271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          case 'X':
24281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            /* A typed constant value follows */
24291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            args++;
24301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            if (!do_type (work, &args, &type_str))
24311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      goto cfront_template_args_done;
243270bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard            string_append (&arg, "(");
24331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            string_appends (&arg, &type_str);
24341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            string_append (&arg, ")");
24351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            if (*args != 'L')
24361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              goto cfront_template_args_done;
24371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            args++;
24381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            /* Now snarf a literal value following 'L' */
243970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard            if (!snarf_numeric_literal (&args, &arg))
24401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      goto cfront_template_args_done;
24411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            break;
24421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
24431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          case 'L':
24441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            /* Snarf a literal following 'L' */
24451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            args++;
24461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            if (!snarf_numeric_literal (&args, &arg))
24471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      goto cfront_template_args_done;
24481ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            break;
24491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          default:
24501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            /* Not handling other HP cfront stuff */
24511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            if (!do_type (work, &args, &arg))
24521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              goto cfront_template_args_done;
24531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  }
24541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_appends (declp, &arg);
24551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	string_append (declp, ",");
24561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      }
24571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    cfront_template_args_done:
24581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_delete (&arg);
24591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (args >= e)
24601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	--declp->p; /* remove extra comma */
24611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (declp, ">");
24621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
24631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
24641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	   && (*mangled)[9] == 'N'
24651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	   && (*mangled)[8] == (*mangled)[10]
24661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	   && strchr (cplus_markers, (*mangled)[8]))
24671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
24681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* A member of the anonymous namespace.  */
24691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (declp, "{anonymous}");
24701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
24711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else
24721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
24731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (work->temp_start == -1) /* non-recursive call only */
24741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	work->temp_start = 0;     /* disable in recursive calls */
24751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appendn (declp, *mangled, n);
24761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
24771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  *mangled += n;
24781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
24791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
24801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/* Extract a class name, possibly a template with arguments, from the
24811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   mangled string; qualifiers, local class indicators, etc. have
24821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   already been dealt with */
24831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
24841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
24851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_class_name (work, mangled, declp)
24861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
24871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
24881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *declp;
24891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
24901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int n;
24911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 0;
24921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
24931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  n = consume_count (mangled);
24941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (n == -1)
24951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    return 0;
24961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if ((int) strlen (*mangled) >= n)
24971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
24981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      demangle_arm_hp_template (work, mangled, n, declp);
24991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      success = 1;
25001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
25011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return (success);
25031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
25041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/*
25061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25071ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardLOCAL FUNCTION
25081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	demangle_class -- demangle a mangled class sequence
25101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25111ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardSYNOPSIS
25121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	static int
25141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	demangle_class (struct work_stuff *work, const char **mangled,
25151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard			strint *declp)
25161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25171ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardDESCRIPTION
25181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	DECLP points to the buffer into which demangling is being done.
25201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	*MANGLED points to the current token to be demangled.  On input,
25221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
25231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	On exit, it points to the next token after the mangled class on
25241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	success, or the first unconsumed token on failure.
25251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
25271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	we are demangling a constructor or destructor.  In this case
25281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	we prepend "class::class" or "class::~class" to DECLP.
25291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	Otherwise, we prepend "class::" to the current DECLP.
25311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	Reset the constructor/destructor flags once they have been
25331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	"consumed".  This allows demangle_class to be called later during
25341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	the same demangling, to do normal class demangling.
25351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	Returns 1 if demangling is successful, 0 otherwise.
25371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard*/
25391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
25411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_class (work, mangled, declp)
25421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
25431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
25441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *declp;
25451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
25461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 0;
25471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int btype;
25481ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string class_name;
25491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  char *save_class_name_end = 0;
25501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string_init (&class_name);
25521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  btype = register_Btype (work);
25531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (demangle_class_name (work, mangled, &class_name))
2554d0c9c32f64c09c699c54dc9ffb8558c297f9e08eDaniel Veillard    {
25551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      save_class_name_end = class_name.p;
25561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if ((work->constructor & 1) || (work->destructor & 1))
25571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
25581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          /* adjust so we don't include template args */
25591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          if (work->temp_start && (work->temp_start != -1))
25601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            {
25611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              class_name.p = class_name.b + work->temp_start;
25621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard            }
25631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  string_prepends (declp, &class_name);
25641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if (work -> destructor & 1)
25651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
25661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      string_prepend (declp, "~");
25671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard              work -> destructor -= 1;
25681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
256970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard	  else
2570e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	    {
2571e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	      work -> constructor -= 1;
2572e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	    }
2573e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	}
25741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      class_name.p = save_class_name_end;
25751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
25761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
25771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_prepend (declp, SCOPE_STRING (work));
25781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_prepends (declp, &class_name);
25791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      success = 1;
25801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
25811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string_delete (&class_name);
25821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return (success);
25831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
25841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/* Called when there's a "__" in the mangled name, with `scan' pointing to
25871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   the rightmost guess.
25881ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
25891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   Find the correct "__"-sequence where the function name ends and the
25901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   signature starts, which is ambiguous with GNU mangling.
259101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   Call demangle_signature here, so we can make sure we found the right
25921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   one; *mangled will be consumed so caller will not make further calls to
25931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard   demangle_signature.  */
25941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
259501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
25961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarditerate_demangle_function (work, mangled, declp, scan)
25971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
25981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char **mangled;
25991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string *declp;
260001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     const char *scan;
26011ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
26021ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *mangle_init = *mangled;
26031ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 0;
26041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string decl_init;
260501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  struct work_stuff work_init;
26061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (*(scan + 2) == '\0')
26081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    return 0;
26091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Do not iterate for some demangling modes, or if there's only one
26111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     "__"-sequence.  This is the normal case.  */
26121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
26131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      || strstr (scan + 2, "__") == NULL)
261401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
26151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      demangle_function_name (work, mangled, declp, scan);
26161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      return 1;
26171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
26181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Save state so we can restart if the guess at the correct "__" was
26201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     wrong.  */
26211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string_init (&decl_init);
26221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string_appends (&decl_init, declp);
26231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  memset (&work_init, 0, sizeof work_init);
26241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  work_stuff_copy_to_from (&work_init, work);
26251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Iterate over occurrences of __, allowing names and types to have a
2627e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     "__" sequence in them.  We must start with the first (not the last)
2628e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     occurrence, since "__" most often occur between independent mangled
2629e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     parts, hence starting at the last occurrence inside a signature
26301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     might get us a "successful" demangling of the signature.  */
26311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  while (scan[2])
26331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
26341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      demangle_function_name (work, mangled, declp, scan);
26351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      success = demangle_signature (work, mangled, declp);
26361ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (success)
26371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	break;
26381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* Reset demangle state for the next round.  */
26401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      *mangled = mangle_init;
26411ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_clear (declp);
26421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_appends (declp, &decl_init);
26431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      work_stuff_copy_to_from (work, &work_init);
26441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* Leave this underscore-sequence.  */
26461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      scan += 2;
26471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
264801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      /* Scan for the next "__" sequence.  */
26491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (*scan && (scan[0] != '_' || scan[1] != '_'))
26501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	scan++;
26511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* Move to last "__" in this sequence.  */
26531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (*scan && *scan == '_')
26541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	scan++;
26551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      scan -= 2;
26561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
26571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /* Delete saved state.  */
26591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  delete_work_stuff (&work_init);
26601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  string_delete (&decl_init);
266101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
26621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  return success;
26631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
26641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/*
26661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26671ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardLOCAL FUNCTION
26681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	demangle_prefix -- consume the mangled name prefix and find signature
26701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26711ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardSYNOPSIS
267201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
26731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	static int
26741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	demangle_prefix (struct work_stuff *work, const char **mangled,
26751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard			 string *declp);
26761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26771ac24d36b12487995b659a8fc23a02b9460edb36Daniel VeillardDESCRIPTION
26781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
267901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	Consume and demangle the prefix of the mangled name.
26801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	While processing the function name root, arrange to call
26811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	demangle_signature if the root is ambiguous.
26821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26831ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	DECLP points to the string buffer into which demangled output is
26841ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	placed.  On entry, the buffer is empty.  On exit it contains
26851ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	the root function name, the demangled operator name, or in some
26861ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	special cases either nothing or the completely demangled result.
26871ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
268801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	MANGLED points to the current pointer into the mangled name.  As each
26891ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	token of the mangled name is consumed, it is updated.  Upon entry
26901ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	the current mangled name pointer points to the first character of
26911ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	the mangled name.  Upon exit, it should point to the first character
26921ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	of the signature if demangling was successful, or to the first
26931ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	unconsumed character if demangling of the prefix was unsuccessful.
26941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26951ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	Returns 1 on success, 0 otherwise.
26961ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard */
26971ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
26981ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
26991ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillarddemangle_prefix (work, mangled, declp)
27001ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     struct work_stuff *work;
2701e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     const char **mangled;
2702e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard     string *declp;
2703e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard{
27041ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int success = 1;
27051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  const char *scan;
27061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  int i;
27071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27081ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (strlen(*mangled) > 6
27091ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      && (strncmp(*mangled, "_imp__", 6) == 0
27101ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard          || strncmp(*mangled, "__imp_", 6) == 0))
27111ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
27121ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* it's a symbol imported from a PE dynamic library. Check for both
27131ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard         new style prefix _imp__ and legacy __imp_ used by older versions
27141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	 of dlltool. */
27151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled) += 6;
271601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      work->dllimported = 1;
27171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
27181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
27191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
27201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      char *marker = strchr (cplus_markers, (*mangled)[8]);
27211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (marker != NULL && *marker == (*mangled)[10])
27221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
27231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  if ((*mangled)[9] == 'D')
27241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
27251ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      /* it's a GNU global destructor to be executed at program exit */
27261ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      (*mangled) += 11;
272701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	      work->destructor = 2;
27281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      if (gnu_special (work, mangled, declp))
27291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		return success;
27301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
27311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  else if ((*mangled)[9] == 'I')
27321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    {
27331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      /* it's a GNU global constructor to be executed at program init */
27341ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      (*mangled) += 11;
27351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	      work->constructor = 2;
273601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	      if (gnu_special (work, mangled, declp))
27371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard		return success;
27381ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
27391ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
27401ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
274101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
27421ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
27431ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* it's a ARM global destructor to be executed at program exit */
27441ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled) += 7;
27451ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      work->destructor = 2;
27461ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
27471ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
274801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
27491ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* it's a ARM global constructor to be executed at program initial */
27501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*mangled) += 7;
27511ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      work->constructor = 2;
27521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
27531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  /*  This block of code is a reduction in strength time optimization
27551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      of:
27561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      scan = strstr (*mangled, "__"); */
27571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  {
27591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    scan = *mangled;
27601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    do {
2762b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      scan = strchr (scan, '_');
27631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    } while (scan != NULL && *++scan != '_');
27641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    if (scan != NULL) --scan;
27661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  }
27671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (scan != NULL)
27691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
27701ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* We found a sequence of two or more '_', ensure that we start at
27711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	 the last pair in the sequence.  */
27721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      /* i = strspn (scan, "_"); */
27731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      i = 0;
27741ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      while (scan[i] == '_') i++;
27751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      if (i > 2)
27761ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	{
27771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  scan += (i - 2);
27781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	}
27791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
27801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
27811ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (scan == NULL)
27821ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
2783b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      success = 0;
2784b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    }
2785b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  else if (work -> static_type)
2786b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    {
2787b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2788b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
2789b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  success = 0;
2790b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	}
2791b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    }
2792b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  else if ((scan == *mangled)
2793b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	   && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2794b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	       || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2795b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    {
2796b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      /* The ARM says nothing about the mangling of local variables.
2797b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	 But cfront mangles local variables by prepending __<nesting_level>
2798b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	 to them. As an extension to ARM demangling we handle this case.  */
2799b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2800b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  && ISDIGIT ((unsigned char)scan[2]))
2801b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
28024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  *mangled = scan + 2;
28034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  consume_count (mangled);
28044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  string_append (declp, *mangled);
2805c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  *mangled += strlen (*mangled);
2806c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  success = 1;
2807c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
2808c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      else
2809c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	{
2810c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2811c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	     names like __Q2_3foo3bar for nested type names.  So don't accept
2812c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	     this style of constructor for cfront demangling.  A GNU
2813c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	     style member-template constructor starts with 'H'. */
2814c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2815c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	    work -> constructor += 1;
2816c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  *mangled = scan + 2;
2817c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
2818c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
2819c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2820c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    {
2821c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      /* Cfront-style parameterized type.  Handled later as a signature. */
2822c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      success = 1;
2823c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
2824c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      /* ARM template? */
2825c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2826c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    }
2827c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard  else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2828c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard                              || (scan[2] == 'p' && scan[3] == 's')
2829c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard                              || (scan[2] == 'p' && scan[3] == 't')))
2830c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    {
2831c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      /* EDG-style parameterized type.  Handled later as a signature. */
2832c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      success = 1;
2833c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
2834c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      /* EDG template? */
2835c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2836c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    }
2837c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard  else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2838c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard	   && (scan[2] != 't'))
2839c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    {
2840c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard      /* Mangled name starts with "__".  Skip over any leading '_' characters,
2841c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard	 then find the next "__" that separates the prefix from the signature.
2842c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard	 */
28434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
28444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  || (arm_special (mangled, declp) == 0))
28454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	{
28464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  while (*scan == '_')
28474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    {
28484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      scan++;
28494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
28504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
28514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    {
28524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      /* No separator (I.E. "__not_mangled"), or empty signature
28534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 (I.E. "__not_mangled_either__") */
28544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	      success = 0;
2855e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	    }
28564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  else
28574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return iterate_demangle_function (work, mangled, declp, scan);
2858e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	}
2859e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
2860e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  else if (*(scan + 2) != '\0')
2861e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    {
2862e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      /* Mangled name does not start with "__" but does have one somewhere
2863e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	 in there with non empty stuff after it.  Looks like a global
2864e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	 function name.  Iterate over all "__":s until the right
2865e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	 one is found.  */
286680b19092f24410a6b869abf519227686e8f207caDaniel Veillard      return iterate_demangle_function (work, mangled, declp, scan);
286780b19092f24410a6b869abf519227686e8f207caDaniel Veillard    }
286880b19092f24410a6b869abf519227686e8f207caDaniel Veillard  else
2869e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    {
2870e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      /* Doesn't look like a mangled name */
2871e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      success = 0;
2872e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
28734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
287480b19092f24410a6b869abf519227686e8f207caDaniel Veillard  if (!success && (work->constructor == 2 || work->destructor == 2))
28754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    {
2876e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      string_append (declp, *mangled);
2877e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard      *mangled += strlen (*mangled);
287801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      success = 1;
2879e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
2880e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  return (success);
2881e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard}
288201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
2883e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard/*
2884e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
288580b19092f24410a6b869abf519227686e8f207caDaniel VeillardLOCAL FUNCTION
2886e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
288780b19092f24410a6b869abf519227686e8f207caDaniel Veillard	gnu_special -- special handling of gnu mangled strings
288880b19092f24410a6b869abf519227686e8f207caDaniel Veillard
28894255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardSYNOPSIS
28904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
28914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	static int
28924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	gnu_special (struct work_stuff *work, const char **mangled,
28934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     string *declp);
28944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
28954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2896e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel VeillardDESCRIPTION
2897e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
2898e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	Process some special GNU style mangling forms that don't fit
28994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	the normal pattern.  For example:
2900e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
29014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		_$_3foo		(destructor for class foo)
2902e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		_vt$foo		(foo virtual table)
2903e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		_vt$foo$bar	(foo::bar virtual table)
29044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		__vt_foo	(foo virtual table, new style with thunks)
2905e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard		_3foo$varname	(static data member)
29064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		_Q22rs2tu$vw	(static data member)
29074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		__t6vector1Zii	(constructor with template)
29084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		__thunk_4__$_7ostream (virtual function thunk)
29094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
29104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2911070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int
2912070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardgnu_special (work, mangled, declp)
2913070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     struct work_stuff *work;
2914070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     const char **mangled;
2915070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard     string *declp;
2916070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{
2917070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int n;
2918070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int success = 1;
2919070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  const char *p;
2920070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
2921070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if ((*mangled)[0] == '_'
2922070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      && strchr (cplus_markers, (*mangled)[1]) != NULL
2923070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      && (*mangled)[2] == '_')
2924070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
292580b19092f24410a6b869abf519227686e8f207caDaniel Veillard      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
292680b19092f24410a6b869abf519227686e8f207caDaniel Veillard      (*mangled) += 3;
2927070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      work -> destructor += 1;
2928070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    }
2929070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  else if ((*mangled)[0] == '_'
2930070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	   && (((*mangled)[1] == '_'
2931070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		&& (*mangled)[2] == 'v'
29325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		&& (*mangled)[3] == 't'
2933070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		&& (*mangled)[4] == '_')
2934070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	       || ((*mangled)[1] == 'v'
2935070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		   && (*mangled)[2] == 't'
2936070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2937070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
2938070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2939070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard         and create the decl.  Note that we consume the entire mangled
2940070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 input string, which means that demangle_signature has no work
2941070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 to do.  */
2942070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      if ((*mangled)[2] == 'v')
2943070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	(*mangled) += 5; /* New style, with thunks: "__vt_" */
2944070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      else
2945070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2946070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      while (**mangled != '\0')
2947070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
2948070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  switch (**mangled)
2949070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    {
2950070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    case 'Q':
2951070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    case 'K':
2952070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      success = demangle_qualified (work, mangled, declp, 0, 1);
2953070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      break;
2954070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    case 't':
2955070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      success = demangle_template (work, mangled, declp, 0, 1,
2956070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard					   1);
2957070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      break;
2958070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    default:
2959070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      if (ISDIGIT((unsigned char)*mangled[0]))
2960070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		{
2961070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  n = consume_count(mangled);
2962070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  /* We may be seeing a too-large size, or else a
2963070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		     ".<digits>" indicating a static local symbol.  In
2964070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		     any case, declare victory and move on; *don't* try
2965070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		     to use n to allocate.  */
2966070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  if (n > (int) strlen (*mangled))
2967070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		    {
2968070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		      success = 1;
2969070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		      break;
297080b19092f24410a6b869abf519227686e8f207caDaniel Veillard		    }
2971070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		}
2972070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      else
2973070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		{
2974070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  /*n = strcspn (*mangled, cplus_markers);*/
2975070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  const char *check = *mangled;
297680b19092f24410a6b869abf519227686e8f207caDaniel Veillard		  n = 0;
297780b19092f24410a6b869abf519227686e8f207caDaniel Veillard		  while (*check)
297880b19092f24410a6b869abf519227686e8f207caDaniel Veillard		    if (strchr (cplus_markers, *check++) == NULL)
297980b19092f24410a6b869abf519227686e8f207caDaniel Veillard		      n++;
298080b19092f24410a6b869abf519227686e8f207caDaniel Veillard		    else
298180b19092f24410a6b869abf519227686e8f207caDaniel Veillard		      break;
298280b19092f24410a6b869abf519227686e8f207caDaniel Veillard		}
298380b19092f24410a6b869abf519227686e8f207caDaniel Veillard	      string_appendn (declp, *mangled, n);
298480b19092f24410a6b869abf519227686e8f207caDaniel Veillard	      (*mangled) += n;
2985070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
2986070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
2987070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  p = strpbrk (*mangled, cplus_markers);
2988070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (success && ((p == NULL) || (p == *mangled)))
298980b19092f24410a6b869abf519227686e8f207caDaniel Veillard	    {
299080b19092f24410a6b869abf519227686e8f207caDaniel Veillard	      if (p != NULL)
2991070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		{
299280b19092f24410a6b869abf519227686e8f207caDaniel Veillard		  string_append (declp, SCOPE_STRING (work));
299380b19092f24410a6b869abf519227686e8f207caDaniel Veillard		  (*mangled)++;
299480b19092f24410a6b869abf519227686e8f207caDaniel Veillard		}
2995070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
2996070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  else
29975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
29985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      success = 0;
29995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      break;
30005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
30015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
30025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (success)
30035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	string_append (declp, " virtual table");
30045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
30055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else if ((*mangled)[0] == '_'
30065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
30075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
30085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
3009669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard      /* static data member, "_3foo$varname" for example */
3010669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard      (*mangled)++;
3011669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard      switch (**mangled)
3012669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	{
3013669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	case 'Q':
3014669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	case 'K':
3015669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  success = demangle_qualified (work, mangled, declp, 0, 1);
3016669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  break;
3017669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	case 't':
3018669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  success = demangle_template (work, mangled, declp, 0, 1, 1);
3019669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  break;
3020669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	default:
3021669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  n = consume_count (mangled);
3022669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  if (n < 0 || n > (long) strlen (*mangled))
3023669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	    {
3024669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	      success = 0;
3025669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	      break;
3026669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	    }
3027669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard
3028669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
30295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      && (*mangled)[9] == 'N'
30305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      && (*mangled)[8] == (*mangled)[10]
30315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      && strchr (cplus_markers, (*mangled)[8]))
30325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
30335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      /* A member of the anonymous namespace.  There's information
30345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		 about what identifier or filename it was keyed to, but
3035669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard		 it's just there to make the mangled name unique; we just
3036669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard		 step over it.  */
30375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      string_append (declp, "{anonymous}");
3038669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	      (*mangled) += n;
30395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
30405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      /* Now p points to the marker before the N, so we need to
30415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		 update it to the first marker after what we consumed.  */
30425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      p = strpbrk (*mangled, cplus_markers);
3043669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	      break;
30445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
30455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
30465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  string_appendn (declp, *mangled, n);
30475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  (*mangled) += n;
30485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
30495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (success && (p == *mangled))
30505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	{
30515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  /* Consumed everything up to the cplus_marker, append the
30525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	     variable name.  */
30535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  (*mangled)++;
30545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  string_append (declp, SCOPE_STRING (work));
3055669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  n = strlen (*mangled);
3056669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  string_appendn (declp, *mangled, n);
3057669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  (*mangled) += n;
3058669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	}
3059669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard      else
3060669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	{
3061669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard	  success = 0;
30625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
3063669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard    }
30645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else if (strncmp (*mangled, "__thunk_", 8) == 0)
30655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
30665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      int delta;
30675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
30685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      (*mangled) += 8;
30695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      delta = consume_count (mangled);
30705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (delta == -1)
30715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	success = 0;
30725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      else
30735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	{
30745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  char *method = internal_cplus_demangle (work, ++*mangled);
30755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
30765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  if (method)
30775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
30785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      char buf[50];
30795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3080ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	      string_append (declp, buf);
3081ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	      string_append (declp, method);
30825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      free (method);
30835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      n = strlen (*mangled);
30845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      (*mangled) += n;
30855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
30865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  else
30875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
30885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      success = 0;
30895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
30905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
30915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
30925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else if (strncmp (*mangled, "__t", 3) == 0
30935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
30945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
30955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
30965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      (*mangled) += 4;
30975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      switch (**mangled)
3098ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	{
30995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	case 'Q':
31005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	case 'K':
31015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  success = demangle_qualified (work, mangled, declp, 0, 1);
31025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  break;
31035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	case 't':
31045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  success = demangle_template (work, mangled, declp, 0, 1, 1);
3105ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	  break;
3106ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	default:
31075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  success = do_type (work, mangled, declp);
31085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  break;
31095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
3110ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard      if (success && **mangled != '\0')
3111ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard	success = 0;
31125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (success)
31135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	string_append (declp, p);
31145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
31155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else
31165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
31175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      success = 0;
31185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
31195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  return (success);
31205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
31215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic void
31235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardrecursively_demangle(work, mangled, result, namelength)
31245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     struct work_stuff *work;
31255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     const char **mangled;
31265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     string *result;
31275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     int namelength;
31285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
31295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  char * recurse = (char *)NULL;
3130ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard  char * recurse_dem = (char *)NULL;
3131ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard
31325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  recurse = (char *) xmalloc (namelength + 1);
31335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  memcpy (recurse, *mangled, namelength);
31345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  recurse[namelength] = '\000';
31355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
3136ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard  recurse_dem = VG_(cplus_demangle) (recurse, work->options);
31375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (recurse_dem)
31395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
31405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_append (result, recurse_dem);
31415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      free (recurse_dem);
31425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
3143ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard  else
3144ebe25d492075cb8fa141027e7627dfdfdd0262b8Daniel Veillard    {
31455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_appendn (result, *mangled, namelength);
31465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
31475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  free (recurse);
31485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  *mangled += namelength;
31495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
31505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/*
31525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31535a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardLOCAL FUNCTION
31545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	arm_special -- special handling of ARM/lucid mangled strings
31565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31575a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardSYNOPSIS
31585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	static int
31605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	arm_special (const char **mangled,
31615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		     string *declp);
31625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31645a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardDESCRIPTION
31655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	Process some special ARM style mangling forms that don't fit
31675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	the normal pattern.  For example:
31685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
3169669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard		__vtbl__3foo		(foo virtual table)
31705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		__vtbl__3foo__3bar	(bar::foo virtual table)
31715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */
31735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
31745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic int
31755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardarm_special (mangled, declp)
3176669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard     const char **mangled;
3177669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard     string *declp;
31785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
3179669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard  int n;
3180669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard  int success = 1;
31815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  const char *scan;
3182669adfcd3af5dfda873b10119d44202a7450bb20Daniel Veillard
31835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
31845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
31855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
31865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard         and create the decl.  Note that we consume the entire mangled
31875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	 input string, which means that demangle_signature has no work
31885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	 to do.  */
31895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      scan = *mangled + ARM_VTABLE_STRLEN;
31905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      while (*scan != '\0')        /* first check it can be demangled */
31915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        {
31925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          n = consume_count (&scan);
31935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          if (n == -1)
31945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
31955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      return (0);           /* no good */
31965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
31975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          scan += n;
31985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          if (scan[0] == '_' && scan[1] == '_')
31995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
32005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      scan += 2;
32015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
32025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        }
32035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      (*mangled) += ARM_VTABLE_STRLEN;
32045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      while (**mangled != '\0')
32055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	{
32065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  n = consume_count (mangled);
32075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          if (n == -1
32085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      || n > (long) strlen (*mangled))
32095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    return 0;
32105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  string_prependn (declp, *mangled, n);
32115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  (*mangled) += n;
32125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
32135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
32145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      string_prepend (declp, "::");
32155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      (*mangled) += 2;
32165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
32175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
32185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_append (declp, " virtual table");
32195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
32205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else
32215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
32225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      success = 0;
32235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
32245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  return (success);
32255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
32265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
322749e8963c640865343327c67d4755a1af705717d3Daniel Veillard/*
32285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
322949e8963c640865343327c67d4755a1af705717d3Daniel VeillardLOCAL FUNCTION
323049e8963c640865343327c67d4755a1af705717d3Daniel Veillard
323149e8963c640865343327c67d4755a1af705717d3Daniel Veillard	demangle_qualified -- demangle 'Q' qualified name strings
323249e8963c640865343327c67d4755a1af705717d3Daniel Veillard
32335a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardSYNOPSIS
32345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	static int
323649e8963c640865343327c67d4755a1af705717d3Daniel Veillard	demangle_qualified (struct work_stuff *, const char *mangled,
32375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard			    string *result, int isfuncname, int append);
32385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32395a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardDESCRIPTION
32405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
324149e8963c640865343327c67d4755a1af705717d3Daniel Veillard	Demangle a qualified name, such as "Q25Outer5Inner" which is
32425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	the mangled form of "Outer::Inner".  The demangled output is
32435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	prepended or appended to the result string according to the
32445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	state of the append flag.
32455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	If isfuncname is nonzero, then the qualified name we are building
32475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	is going to be used as a member function name, so if it is a
32485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	constructor or destructor function, append an appropriate
32495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	constructor or destructor name.  I.E. for the above example,
32505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	the result for use as a constructor is "Outer::Inner::Inner"
32515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	and the result for use as a destructor is "Outer::Inner::~Inner".
32525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32535a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardBUGS
32545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	Numeric conversion is ASCII dependent (FIXME).
3256b3721c25237d233832b69ac599cc688eb5dcad62Daniel Veillard
3257b3721c25237d233832b69ac599cc688eb5dcad62Daniel Veillard */
3258b3721c25237d233832b69ac599cc688eb5dcad62Daniel Veillard
32595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic int
32605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillarddemangle_qualified (work, mangled, result, isfuncname, append)
32615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     struct work_stuff *work;
32625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     const char **mangled;
32635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     string *result;
32645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     int isfuncname;
32655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     int append;
32665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
32675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  int qualifiers = 0;
32685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  int success = 1;
32695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string temp;
32705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string last_name;
32715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  int bindex = register_Btype (work);
32725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  /* We only make use of ISFUNCNAME if the entity is a constructor or
32745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     destructor.  */
32755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  isfuncname = (isfuncname
32765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		&& ((work->constructor & 1) || (work->destructor & 1)));
32775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string_init (&temp);
32795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string_init (&last_name);
32805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
32815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if ((*mangled)[0] == 'K')
32825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
32835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    /* Squangling qualified name reuse */
32845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      int idx;
32855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      (*mangled)++;
32865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      idx = consume_count_with_underscores (mangled);
32875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (idx == -1 || idx >= work -> numk)
32885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        success = 0;
3289fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      else
3290fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard        string_append (&temp, work -> ktypevec[idx]);
3291fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    }
32925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else
3293fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    switch ((*mangled)[1])
32945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
32955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '_':
32965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      /* GNU mangled name with more than 9 classes.  The count is preceded
3297fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	 by an underscore (to distinguish it from the <= 9 case) and followed
3298fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	 by an underscore.  */
3299fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      (*mangled)++;
33005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      qualifiers = consume_count_with_underscores (mangled);
3301fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      if (qualifiers == -1)
33024aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	success = 0;
33035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      break;
33045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
33055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '1':
33065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '2':
33074aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard    case '3':
33085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '4':
33095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '5':
33105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '6':
33114aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard    case '7':
33125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '8':
33134aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard    case '9':
33145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      /* The count is in a single digit.  */
33154aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard      qualifiers = (*mangled)[1] - '0';
33164aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard
33174aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard      /* If there is an underscore after the digit, skip it.  This is
33184aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	 said to be for ARM-qualified names, but the ARM makes no
33194aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	 mention of such an underscore.  Perhaps cfront uses one.  */
33205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if ((*mangled)[2] == '_')
3321fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	{
3322fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	  (*mangled)++;
3323fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	}
3324fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      (*mangled) += 2;
33255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      break;
33265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
33275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case '0':
33285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    default:
33295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      success = 0;
33305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
33315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
33325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (!success)
33335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
3334fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      string_delete (&last_name);
3335fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      string_delete (&temp);
3336fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      return success;
33375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
3338fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard
33395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  /* Pick off the names and collect them in the temp buffer in the order
33405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     in which they are found, separated by '::'.  */
33415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
3342fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard  while (qualifiers-- > 0)
3343fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    {
3344fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard      int remember_K = 1;
33455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_clear (&last_name);
3346fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard
33474aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard      if (*mangled[0] == '_')
33485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	(*mangled)++;
33495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
33505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (*mangled[0] == 't')
33515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	{
33526560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard	  /* Here we always append to TEMP since we will want to use
33534aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	     the template name without the template parameters as a
33546560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard	     constructor or destructor name.  The appropriate
33555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	     (parameter-less) value is returned by demangle_template
33565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	     in LAST_NAME.  We do not remember the template type here,
33574aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	     in order to match the G++ mangling algorithm.  */
33585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  success = demangle_template(work, mangled, &temp,
33594aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard				      &last_name, 1, 0);
33605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  if (!success)
33616560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard	    break;
33626560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard	}
33636560a42c7b89e7c5df3d87eedad1f34e94ae53bbDaniel Veillard      else if (*mangled[0] == 'K')
33644aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	{
33654aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard          int idx;
33665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          (*mangled)++;
3367fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard          idx = consume_count_with_underscores (mangled);
3368fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard          if (idx == -1 || idx >= work->numk)
3369fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard            success = 0;
33705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          else
33715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            string_append (&temp, work->ktypevec[idx]);
33725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          remember_K = 0;
33735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
33745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  if (!success) break;
33755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
33765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      else
33774aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	{
33785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  if (EDG_DEMANGLING)
33795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            {
33805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      int namelength;
33815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 	      /* Now recursively demangle the qualifier
33825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 	       * This is necessary to deal with templates in
33835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 	       * mangling styles like EDG */
3384fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	      namelength = consume_count (mangled);
33854aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	      if (namelength == -1)
3386fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard		{
33874aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard		  success = 0;
3388fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard		  break;
33895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		}
33905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 	      recursively_demangle(work, mangled, &temp, namelength);
33915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            }
33925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          else
33934aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard            {
33945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      string temp_last_name;
33954aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	      string_init (&temp_last_name);
33965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard              success = do_type (work, mangled, &temp_last_name);
33975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard              if (!success)
33984aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard	        {
33994aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard		  string_delete (&temp_last_name);
34004aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard                  break;
34015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard		}
34025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard              string_appends (&temp, &temp_last_name);
34035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      string_appends (&last_name, &temp_last_name);
34045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      string_delete (&temp_last_name);
34055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            }
34065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	}
34075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (remember_K)
34095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	remember_Ktype (work, temp.b, LEN_STRING (&temp));
34105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (qualifiers > 0)
34125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	string_append (&temp, SCOPE_STRING (work));
34135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
34145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
34165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  /* If we are using the result as a function name, we need to append
34185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     the appropriate '::' separated constructor or destructor name.
34195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     We do this here because this is the most convenient place, where
34205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     we already have a pointer to the name and the length of the name.  */
34215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (isfuncname)
34235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
34245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_append (&temp, SCOPE_STRING (work));
34255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (work -> destructor & 1)
34265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	string_append (&temp, "~");
34275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_appends (&temp, &last_name);
34285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
34295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  /* Now either prepend the temp buffer to the result, or append it,
34315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     depending upon the state of the append flag.  */
34325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (append)
34345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    string_appends (result, &temp);
34355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else
34365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
34375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (!STRING_EMPTY (result))
34385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	string_append (&temp, SCOPE_STRING (work));
34395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_prepends (result, &temp);
34405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
34415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string_delete (&last_name);
34435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string_delete (&temp);
34445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  return (success);
34455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
34465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/*
34485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34495a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardLOCAL FUNCTION
34505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	get_count -- convert an ascii count to integer, consuming tokens
34525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34535a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardSYNOPSIS
34545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	static int
34565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	get_count (const char **type, int *count)
34575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34585a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardDESCRIPTION
34595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	Assume that *type points at a count in a mangled name; set
34615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	*count to its value, and set *type to the next character after
34625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	the count.  There are some weird rules in effect here.
34635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	If *type does not point at a string of digits, return zero.
34655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	If *type points at a string of digits followed by an
34675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	underscore, set *count to their value as an integer, advance
34685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	*type to point *after the underscore, and return 1.
34695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	If *type points at a string of digits not followed by an
34715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	underscore, consume only the first digit.  Set *count to its
34725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	value as an integer, leave *type pointing after that digit,
34735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	and return 1.
34745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        The excuse for this odd behavior: in the ARM and HP demangling
34765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        styles, a type can be followed by a repeat count of the form
34775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        `Nxy', where:
34785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        `x' is a single digit specifying how many additional copies
34805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            of the type to append to the argument list, and
34815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        `y' is one or more digits, specifying the zero-based index of
34835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            the first repeated argument in the list.  Yes, as you're
34845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            unmangling the name you can figure this out yourself, but
34855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard            it's there anyway.
34865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        So, for example, in `bar__3fooFPiN51', the first argument is a
34885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        pointer to an integer (`Pi'), and then the next five arguments
34895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        are the same (`N5'), and the first repeat is the function's
34905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        second argument (`1').
34915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard*/
34925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
34935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic int
34945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardget_count (type, count)
34955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     const char **type;
34965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard     int *count;
34975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
34985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  const char *p;
34995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  int n;
35005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
35015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  if (!ISDIGIT ((unsigned char)**type))
35025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    return (0);
35035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  else
35045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    {
35055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      *count = **type - '0';
35065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      (*type)++;
35075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if (ISDIGIT ((unsigned char)**type))
35085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	{
35095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  p = *type;
35105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  n = *count;
35115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  do
35125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    {
35135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	      n *= 10;
3514070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      n += *p - '0';
3515070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      p++;
3516070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	    }
3517070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  while (ISDIGIT ((unsigned char)*p));
35186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (*p == '_')
35196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
35206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      *type = p + 1;
35216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      *count = n;
35226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
35236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	}
35246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
35256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  return (1);
35266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik}
35276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/* RESULT will be initialised here; it will be freed on failure.  The
35296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   value returned is really a type_kind_t.  */
35306e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35316e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic int
35326e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikdo_type (work, mangled, result)
35336e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     struct work_stuff *work;
35346e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     const char **mangled;
35356e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     string *result;
35366e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik{
35376e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int n;
35386e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int done;
35396e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int success;
35406e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string decl;
35416e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  const char *remembered_type;
35426e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int type_quals;
35436e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string btype;
35446e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  type_kind_t tk = tk_none;
35456e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35466e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_init (&btype);
35476e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_init (&decl);
35486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_init (result);
35496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35506e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  done = 0;
35516e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  success = 1;
35526e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  while (success && !done)
35536e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
35546e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      int member;
35556e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      switch (**mangled)
35566e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	{
35576e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35586e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* A pointer type */
35596e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'P':
35606e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'p':
35616e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
35626e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (! (work -> options & DMGL_JAVA))
35636e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    string_prepend (&decl, "*");
35646e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (tk == tk_none)
35656e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    tk = tk_pointer;
35666e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
35676e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35686e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* A reference type */
35696e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'R':
35706e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
35716e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  string_prepend (&decl, "&");
35726e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (tk == tk_none)
35736e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    tk = tk_reference;
35746e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
35756e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35766e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* An array */
35776e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'A':
35786e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  {
35796e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    ++(*mangled);
35806e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (!STRING_EMPTY (&decl)
35816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		&& (decl.b[0] == '*' || decl.b[0] == '&'))
35826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
35836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_prepend (&decl, "(");
35846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_append (&decl, ")");
35856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
35866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    string_append (&decl, "[");
35876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (**mangled != '_')
35886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      success = demangle_template_value_parm (work, mangled, &decl,
35896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik						      tk_integral);
35906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (**mangled == '_')
35916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      ++(*mangled);
35926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    string_append (&decl, "]");
35936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    break;
35946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  }
35956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
35966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	/* A back reference to a previously seen type */
35976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'T':
35986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
35996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (!get_count (mangled, &n) || n >= work -> ntypes)
36006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
36016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      success = 0;
36026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
36036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  else
36046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
36056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      remembered_type = work -> typevec[n];
36066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      mangled = &remembered_type;
36076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
36086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
36096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* A function */
36116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'F':
36126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
36136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (!STRING_EMPTY (&decl)
36146e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		&& (decl.b[0] == '*' || decl.b[0] == '&'))
36156e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
36166e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      string_prepend (&decl, "(");
36176e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      string_append (&decl, ")");
36186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
36196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* After picking off the function args, we expect to either find the
36206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	     function return type (preceded by an '_') or the end of the
36216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	     string.  */
36226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (!demangle_nested_args (work, mangled, &decl)
36236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      || (**mangled != '_' && **mangled != '\0'))
36246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
36256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      success = 0;
36266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      break;
36276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
36286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (success && (**mangled == '_'))
36296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    (*mangled)++;
36306e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
36316e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36326e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'M':
36336e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'O':
36346e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  {
36356e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    type_quals = TYPE_UNQUALIFIED;
36366e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36376e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    member = **mangled == 'M';
36386e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    (*mangled)++;
36396e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36406e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    string_append (&decl, ")");
36416e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36426e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    /* We don't need to prepend `::' for a qualified name;
36436e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	       demangle_qualified will do that for us.  */
36446e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (**mangled != 'Q')
36456e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      string_prepend (&decl, SCOPE_STRING (work));
36466e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36476e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (ISDIGIT ((unsigned char)**mangled))
36486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		n = consume_count (mangled);
36506e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		if (n == -1
36516e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    || (int) strlen (*mangled) < n)
36526e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  {
36536e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    success = 0;
36546e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    break;
36556e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  }
36566e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_prependn (&decl, *mangled, n);
36576e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		*mangled += n;
36586e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
36596e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    else if (**mangled == 'X' || **mangled == 'Y')
36606e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36616e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string temp;
36626e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		do_type (work, mangled, &temp);
36636e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_prepends (&decl, &temp);
36646e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
36656e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    else if (**mangled == 't')
36666e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36676e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string temp;
36686e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_init (&temp);
36696e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		success = demangle_template (work, mangled, &temp,
36706e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik					     NULL, 1, 1);
36716e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		if (success)
36726e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  {
36736e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    string_prependn (&decl, temp.b, temp.p - temp.b);
36746e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    string_clear (&temp);
36756e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  }
36766e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		else
36776e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  break;
36786e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
36796e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    else if (**mangled == 'Q')
36806e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		success = demangle_qualified (work, mangled, &decl,
36826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik					      /*isfuncnam=*/0,
36836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik					      /*append=*/0);
36846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		if (!success)
36856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  break;
36866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
36876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    else
36886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		success = 0;
36906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		break;
36916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
36926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
36936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    string_prepend (&decl, "(");
36946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (member)
36956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
36966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		switch (**mangled)
36976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  {
36986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  case 'C':
36996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  case 'V':
37006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  case 'u':
37016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    type_quals |= code_for_qualifier (**mangled);
37026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    (*mangled)++;
37036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    break;
37046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  default:
37066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    break;
37076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  }
37086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		if (*(*mangled)++ != 'F')
37106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  {
37116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    success = 0;
37126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		    break;
37136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		  }
37146e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
37156e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if ((member && !demangle_nested_args (work, mangled, &decl))
37166e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		|| **mangled != '_')
37176e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
37186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		success = 0;
37196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		break;
37206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
37216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    (*mangled)++;
37226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (! PRINT_ANSI_QUALIFIERS)
37236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
37246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		break;
37256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
37266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    if (type_quals != TYPE_UNQUALIFIED)
37276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      {
37286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		APPEND_BLANK (&decl);
37296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_append (&decl, qualifier_string (type_quals));
37306e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      }
37316e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    break;
37326e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  }
37336e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        case 'G':
37346e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
37356e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
37366e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37376e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'C':
37386e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'V':
37396e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	case 'u':
37406e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (PRINT_ANSI_QUALIFIERS)
37416e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
37426e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      if (!STRING_EMPTY (&decl))
37436e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik		string_prepend (&decl, " ");
37446e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37456e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      string_prepend (&decl, demangle_qualifier (**mangled));
37466e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
37476e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  (*mangled)++;
37486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
37496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /*
37506e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    }
37516e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    */
37526e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37536e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  /* fall through */
37546e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	default:
37556e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  done = 1;
37566e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  break;
37576e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	}
37586e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
37596e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37606e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (success) switch (**mangled)
37616e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
37626e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      /* A qualified name, such as "Outer::Inner".  */
37636e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'Q':
37646e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'K':
37656e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      {
37666e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        success = demangle_qualified (work, mangled, result, 0, 1);
37676e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        break;
37686e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      }
37696e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37706e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    /* A back reference to a previously seen squangled type */
37716e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'B':
37726e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      (*mangled)++;
37736e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (!get_count (mangled, &n) || n >= work -> numb)
37746e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	success = 0;
37756e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      else
37766e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	string_append (result, work->btypevec[n]);
37776e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      break;
37786e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37796e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'X':
37806e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'Y':
37816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      /* A template parm.  We substitute the corresponding argument. */
37826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      {
37836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	int idx;
37846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	(*mangled)++;
37866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	idx = consume_count_with_underscores (mangled);
37876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	if (idx == -1
37896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
37906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    || consume_count_with_underscores (mangled) == -1)
37916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  {
37926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    success = 0;
37936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    break;
37946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  }
37956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
37966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	if (work->tmpl_argvec)
37976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  string_append (result, work->tmpl_argvec[idx]);
37986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	else
37996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  string_append_template_idx (result, idx);
38006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	success = 1;
38026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      }
38036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    break;
38046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    default:
38066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      success = demangle_fund_type (work, mangled, result);
38076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (tk == tk_none)
38086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	tk = (type_kind_t) success;
38096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      break;
38106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
38116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (success)
38136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
38146e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (!STRING_EMPTY (&decl))
38156e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	{
38166e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  string_append (result, " ");
38176e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  string_appends (result, &decl);
38186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	}
38196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
38206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  else
38216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    string_delete (result);
38226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_delete (&decl);
38236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (success)
38256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    /* Assume an integral type, if we're not sure.  */
38266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    return (int) ((tk == tk_none) ? tk_integral : tk);
38276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  else
38286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    return 0;
38296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik}
38306e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38316e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/* Given a pointer to a type string that represents a fundamental type
38326e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   argument (int, long, unsigned int, etc) in TYPE, a pointer to the
38336e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   string in which the demangled output is being built in RESULT, and
38346e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   the WORK structure, decode the types and add them to the result.
38356e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38366e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   For example:
38376e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38386e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   	"Ci"	=>	"const int"
38396e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	"Sl"	=>	"signed long"
38406e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	"CUs"	=>	"const unsigned short"
38416e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38426e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   The value returned is really a type_kind_t.  */
38436e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
38446e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic int
3845c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillarddemangle_fund_type (work, mangled, result)
3846c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     struct work_stuff *work;
3847c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     const char **mangled;
3848c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     string *result;
3849c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard{
3850c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  int done = 0;
3851c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  int success = 1;
3852c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  char buf[10];
3853c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  unsigned int dec = 0;
3854c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string btype;
3855c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  type_kind_t tk = tk_integral;
3856c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
3857c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string_init (&btype);
3858c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
3859c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  /* First pick off any type qualifiers.  There can be more than one.  */
3860c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
3861c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  while (!done)
3862c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
3863c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      switch (**mangled)
3864c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	{
386576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	case 'C':
386676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	case 'V':
3867c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	case 'u':
386876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	  if (PRINT_ANSI_QUALIFIERS)
386976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	    {
3870c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard              if (!STRING_EMPTY (result))
3871c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard                string_prepend (result, " ");
3872c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	      string_prepend (result, demangle_qualifier (**mangled));
387376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	    }
387476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	  (*mangled)++;
3875c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  break;
3876c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	case 'U':
3877c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  (*mangled)++;
3878c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  APPEND_BLANK (result);
3879c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  string_append (result, "unsigned");
3880c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  break;
3881c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	case 'S': /* signed char only */
3882c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  (*mangled)++;
3883c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  APPEND_BLANK (result);
388476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	  string_append (result, "signed");
3885c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  break;
3886c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	case 'J':
3887c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  (*mangled)++;
3888c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  APPEND_BLANK (result);
388976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	  string_append (result, "__complex");
3890c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  break;
3891c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	default:
3892c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  done = 1;
3893c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  break;
3894c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	}
3895c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    }
3896c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
3897b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  /* Now pick off the fundamental type.  There can be only one.  */
3898b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
3899b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  switch (**mangled)
3900b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    {
3901b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case '\0':
3902b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case '_':
3903b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3904b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'v':
3905b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3906b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3907b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "void");
3908b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3909b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'x':
3910b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3911b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3912b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "long long");
3913b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3914b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'l':
3915b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3916b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3917b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "long");
3918b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3919b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'i':
3920b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3921b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3922b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "int");
3923b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3924b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 's':
3925b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3926b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3927b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "short");
3928b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3929b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'b':
3930b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3931b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3932b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "bool");
3933b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_bool;
3934b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3935b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'c':
3936b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3937b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3938b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "char");
3939b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_char;
3940b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3941b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'w':
3942b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3943b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3944b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "wchar_t");
3945b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_char;
3946b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3947b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'r':
3948b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3949b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3950b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "long double");
3951b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_real;
3952b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3953b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'd':
3954b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3955b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3956b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "double");
3957b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_real;
3958b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3959b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'f':
3960b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3961b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      APPEND_BLANK (result);
3962b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      string_append (result, "float");
3963b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      tk = tk_real;
3964b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      break;
3965b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard    case 'G':
3966b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      (*mangled)++;
3967b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard      if (!ISDIGIT ((unsigned char)**mangled))
3968b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	{
3969b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard	  success = 0;
39704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  break;
39714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
39726e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    case 'I':
39734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard      (*mangled)++;
39746e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (**mangled == '_')
39754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	{
39764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  int i;
39774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  (*mangled)++;
39785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	  for (i = 0;
39795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	       i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
39804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	       (*mangled)++, i++)
39816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    buf[i] = **mangled;
39826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (**mangled != '_')
39836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    {
39846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      success = 0;
39856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	      break;
39864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
39874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  buf[i] = '\0';
39884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	  (*mangled)++;
39894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
399080b19092f24410a6b869abf519227686e8f207caDaniel Veillard      else
39912f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack	{
39922f2a66324d18afa655d6aa659b2089c36e2c4a92William M. Brack	  strncpy (buf, *mangled, 2);
399380b19092f24410a6b869abf519227686e8f207caDaniel Veillard	  buf[2] = '\0';
399480b19092f24410a6b869abf519227686e8f207caDaniel Veillard	  *mangled += min (strlen (*mangled), 2);
399580b19092f24410a6b869abf519227686e8f207caDaniel Veillard	}
399680b19092f24410a6b869abf519227686e8f207caDaniel Veillard      /*sscanf (buf, "%x", &dec);
399780b19092f24410a6b869abf519227686e8f207caDaniel Veillard      sprintf (buf, "int%u_t", dec);*/
399880b19092f24410a6b869abf519227686e8f207caDaniel Veillard      sprintf (buf, "i_xx_t");
399980b19092f24410a6b869abf519227686e8f207caDaniel Veillard      APPEND_BLANK (result);
400080b19092f24410a6b869abf519227686e8f207caDaniel Veillard      string_append (result, buf);
400180b19092f24410a6b869abf519227686e8f207caDaniel Veillard      break;
400280b19092f24410a6b869abf519227686e8f207caDaniel Veillard
400380b19092f24410a6b869abf519227686e8f207caDaniel Veillard      /* fall through */
400480b19092f24410a6b869abf519227686e8f207caDaniel Veillard      /* An explicit type, such as "6mytype" or "7integer" */
400580b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '0':
400680b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '1':
40074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    case '2':
400880b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '3':
400980b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '4':
401080b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '5':
401180b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '6':
401280b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '7':
401380b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '8':
401480b19092f24410a6b869abf519227686e8f207caDaniel Veillard    case '9':
401580b19092f24410a6b869abf519227686e8f207caDaniel Veillard      {
401680b19092f24410a6b869abf519227686e8f207caDaniel Veillard        int bindex = register_Btype (work);
401780b19092f24410a6b869abf519227686e8f207caDaniel Veillard        string loc_btype;
401880b19092f24410a6b869abf519227686e8f207caDaniel Veillard        string_init (&loc_btype);
401980b19092f24410a6b869abf519227686e8f207caDaniel Veillard        if (demangle_class_name (work, mangled, &loc_btype)) {
402080b19092f24410a6b869abf519227686e8f207caDaniel Veillard          remember_Btype (work, loc_btype.b, LEN_STRING (&loc_btype), bindex);
402180b19092f24410a6b869abf519227686e8f207caDaniel Veillard          APPEND_BLANK (result);
402280b19092f24410a6b869abf519227686e8f207caDaniel Veillard          string_appends (result, &loc_btype);
402380b19092f24410a6b869abf519227686e8f207caDaniel Veillard        }
40244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        else
40255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard          success = 0;
4026070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard        string_delete (&loc_btype);
4027070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard        break;
4028070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard      }
40295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    case 't':
40305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      {
40315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        success = demangle_template (work, mangled, &btype, 0, 1, 1);
40325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        string_appends (result, &btype);
40335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard        break;
40345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      }
40355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    default:
40365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      success = 0;
40375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      break;
40385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard    }
40395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
40405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  string_delete (&btype);
40415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
40425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard  return success ? ((int) tk) : 0;
40435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard}
40445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
40455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
40465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/* Handle a template's value parameter for HP aCC (extension from ARM)
40475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard   **mangled points to 'S' or 'U' */
40486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40496e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic int
405080b19092f24410a6b869abf519227686e8f207caDaniel Veillarddo_hpacc_template_const_value (work, mangled, result)
405180b19092f24410a6b869abf519227686e8f207caDaniel Veillard     struct work_stuff *work ATTRIBUTE_UNUSED;
405280b19092f24410a6b869abf519227686e8f207caDaniel Veillard     const char **mangled;
405380b19092f24410a6b869abf519227686e8f207caDaniel Veillard     string *result;
405480b19092f24410a6b869abf519227686e8f207caDaniel Veillard{
405580b19092f24410a6b869abf519227686e8f207caDaniel Veillard  int unsigned_const;
405680b19092f24410a6b869abf519227686e8f207caDaniel Veillard
405780b19092f24410a6b869abf519227686e8f207caDaniel Veillard  if (**mangled != 'U' && **mangled != 'S')
405880b19092f24410a6b869abf519227686e8f207caDaniel Veillard    return 0;
405980b19092f24410a6b869abf519227686e8f207caDaniel Veillard
40606e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  unsigned_const = (**mangled == 'U');
40616e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40626e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  (*mangled)++;
40636e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40646e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  switch (**mangled)
40656e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
40666e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      case 'N':
40676e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        string_append (result, "-");
40686e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        /* fall through */
4069c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      case 'P':
4070c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        (*mangled)++;
4071c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        break;
4072c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      case 'M':
4073c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        /* special case for -2^31 */
4074c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        string_append (result, "-2147483648");
4075c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        (*mangled)++;
4076c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard        return 1;
4077c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      default:
40786e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik        return 0;
40796e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
40806e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* We have to be looking at an integer now */
40826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (!(ISDIGIT ((unsigned char)**mangled)))
40836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    return 0;
40846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* We only deal with integral values for template
40866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     parameters -- so it's OK to look only for digits */
40876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  while (ISDIGIT ((unsigned char)**mangled))
40886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
40896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      char_str[0] = **mangled;
40906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      string_append (result, char_str);
40916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      (*mangled)++;
40926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
40936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (unsigned_const)
40956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    string_append (result, "U");
40966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
40976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
40986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     with L or LL suffixes. pai/1997-09-03 */
40996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  return 1; /* success */
41016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik}
41026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/* Handle a template's literal parameter for HP aCC (extension from ARM)
41046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   **mangled is pointing to the 'A' */
41056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic int
41076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikdo_hpacc_template_literal (work, mangled, result)
41086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     struct work_stuff *work;
41096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     const char **mangled;
41106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     string *result;
41116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik{
41126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  int literal_len = 0;
41136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  char * recurse;
4114c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  char * recurse_dem;
4115e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
4116e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  if (**mangled != 'A')
4117e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    return 0;
4118e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
4119e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  (*mangled)++;
4120e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
4121e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard  literal_len = consume_count (mangled);
4122e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
4123c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  if (literal_len <= 0)
4124c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    return 0;
4125b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
4126b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  /* Literal parameters are names of arrays, functions, etc.  and the
4127b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard     canonical representation uses the address operator */
4128b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  string_append (result, "&");
4129c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4130b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  /* Now recursively demangle the literal name */
4131b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  recurse = (char *) xmalloc (literal_len + 1);
4132b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  memcpy (recurse, *mangled, literal_len);
4133b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  recurse[literal_len] = '\000';
4134b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
4135b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  recurse_dem = VG_(cplus_demangle) (recurse, work->options);
4136b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard
4137b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard  if (recurse_dem)
4138560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    {
413970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard      string_append (result, recurse_dem);
414070bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard      free (recurse_dem);
414170bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard    }
414270bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard  else
414370bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard    {
414470bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard      string_appendn (result, *mangled, literal_len);
414570bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard    }
414670bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard  (*mangled) += literal_len;
414770bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard  free (recurse);
414870bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard
414970bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard  return 1;
415070bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard}
415170bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard
4152560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillardstatic int
41531ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardsnarf_numeric_literal (args, arg)
41541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     const char ** args;
41551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard     string * arg;
41561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard{
41571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (**args == '-')
41581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    {
41591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      char_str[0] = '-';
41601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      string_append (arg, char_str);
41611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard      (*args)++;
41621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
41631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  else if (**args == '+')
41641ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    (*args)++;
41651ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
41661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard  if (!ISDIGIT ((unsigned char)**args))
41671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    return 0;
41686e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
4169c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  while (ISDIGIT ((unsigned char)**args))
4170c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
4171c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      char_str[0] = **args;
4172c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      string_append (arg, char_str);
4173c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      (*args)++;
41744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
41755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard
41764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  return 1;
41774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
41784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
41796e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik/* Demangle the next argument, given by MANGLED into RESULT, which
41806e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   *should be an uninitialized* string.  It will be initialized here,
41816e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik   and free'd should anything go wrong.  */
41826e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41836e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic int
41846e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikdo_arg (work, mangled, result)
41856e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     struct work_stuff *work;
41866e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     const char **mangled;
41876e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     string *result;
41886e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik{
41896e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* Remember where we started so that we can record the type, for
41906e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     non-squangling type remembering.  */
41916e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  const char *start = *mangled;
41926e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string temp_result;
41936e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41946e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_init (result);
41956e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_init (&temp_result);
41966e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
41976e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (work->nrepeats > 0)
41986e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
41996e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      --work->nrepeats;
42006e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42016e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (work->previous_argument == 0)
42026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	return 0;
42036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      /* We want to reissue the previous type in this argument list.  */
42056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      string_appends (result, work->previous_argument);
42066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      return 1;
42076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
42086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (**mangled == 'n')
42106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
42116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      /* A squangling-style repeat.  */
42126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      (*mangled)++;
42136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      work->nrepeats = consume_count(mangled);
42146e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42156e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (work->nrepeats <= 0)
42166e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	/* This was not a repeat count after all.  */
42176e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	return 0;
42186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      if (work->nrepeats > 9)
42206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	{
42216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  if (**mangled != '_')
42226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    /* The repeat count should be followed by an '_' in this
42236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	       case.  */
42246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    return 0;
42256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	  else
42266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	    (*mangled)++;
42276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik	}
42286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
42296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      /* Now, the repeat is all set up.  */
4230c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      return do_arg (work, mangled, result);
4231c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    }
4232c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4233c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  /* Save the result in WORK->previous_argument so that we can find it
4234c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     if it's repeated.  Note that saving START is not good enough: we
4235c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     do not want to add additional types to the back-referenceable
4236c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     type vector when processing a repeated type.  */
4237c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  if (work->previous_argument)
4238c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    string_clear (work->previous_argument);
4239c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  else
4240c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
4241c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      work->previous_argument = (string*) xmalloc (sizeof (string));
4242c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      string_init (work->previous_argument);
4243c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    }
4244c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
424576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack  if (!do_type (work, mangled, &temp_result))
4246c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
4247c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      string_delete (&temp_result);
4248c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      return 0;
4249c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    }
4250c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string_appends (work->previous_argument, &temp_result);
4251c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string_delete (&temp_result);
4252c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4253c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  string_appends (result, work->previous_argument);
4254c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4255c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  remember_type (work, start, *mangled - start);
4256c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  return 1;
4257c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard}
4258c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4259c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillardstatic void
4260c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillardremember_type (work, start, len)
4261c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     struct work_stuff *work;
4262c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard     const char *start;
426376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack     int len;
426476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack{
4265c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  char *tem;
4266c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4267c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  if (work->forgetting_types)
4268c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    return;
4269c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard
4270c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard  if (work -> ntypes >= work -> typevec_size)
4271c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard    {
4272c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard      if (work -> typevec_size == 0)
4273c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	{
4274c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillard	  work -> typevec_size = 3;
42756927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	  work -> typevec
42766927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	    = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
42776927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	}
42786927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard      else
42796927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	{
42806927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	  work -> typevec_size *= 2;
42816927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	  work -> typevec
42826927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard	    = (char **) xrealloc ((char *)work -> typevec,
4283c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard				  sizeof (char *) * work -> typevec_size);
4284c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
4285c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
4286c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  tem = xmalloc (len + 1);
4287c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  memcpy (tem, start, len);
4288c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  tem[len] = '\0';
4289094dd86c130f3ffb7ec9bc47bb0ed711e0f68994William M. Brack  work -> typevec[work -> ntypes++] = tem;
4290094dd86c130f3ffb7ec9bc47bb0ed711e0f68994William M. Brack}
4291c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4292c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4293c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* Remember a K type class qualifier. */
4294c4c215519fae43487ab55bbe1f923646af40d306Daniel Veillardstatic void
429501fa6156e51259229470f40619af93e915b4bc94Daniel Veillardremember_Ktype (work, start, len)
429601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     struct work_stuff *work;
429701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     const char *start;
429801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     int len;
429901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
430001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  char *tem;
430101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
430201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  if (work -> numk >= work -> ksize)
430301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
430401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (work -> ksize == 0)
430501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
430601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> ksize = 5;
430701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> ktypevec
430801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    = (char **) xmalloc (sizeof (char *) * work -> ksize);
430901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	}
431001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      else
431101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
4312ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard	  work -> ksize *= 2;
4313ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard	  work -> ktypevec
431401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    = (char **) xrealloc ((char *)work -> ktypevec,
431501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard				  sizeof (char *) * work -> ksize);
431601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	}
431701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    }
431801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  tem = xmalloc (len + 1);
431901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  memcpy (tem, start, len);
4320c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  tem[len] = '\0';
4321c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  work -> ktypevec[work -> numk++] = tem;
432201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard}
432301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard
432401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard/* Register a B code, and get an index for it. B codes are registered
432501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   as they are seen, rather than as they are completed, so map<temp<char> >
4326c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   registers map<temp<char> > as B0, and temp<char> as B1 */
4327c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
432801fa6156e51259229470f40619af93e915b4bc94Daniel Veillardstatic int
432901fa6156e51259229470f40619af93e915b4bc94Daniel Veillardregister_Btype (work)
433001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard     struct work_stuff *work;
433101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
4332c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  int ret;
4333c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
433401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  if (work -> numb >= work -> bsize)
433501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard    {
433601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (work -> bsize == 0)
433701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
433801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> bsize = 5;
433901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> btypevec
434001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    = (char **) xmalloc (sizeof (char *) * work -> bsize);
434101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	}
434201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      else
434301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
434401fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> bsize *= 2;
434501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  work -> btypevec
434601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    = (char **) xrealloc ((char *)work -> btypevec,
43476927b10615d4f48fbc3fa0f3b114890275488991Daniel Veillard				  sizeof (char *) * work -> bsize);
4348c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
4349c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
4350c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  ret = work -> numb++;
4351c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  work -> btypevec[ret] = NULL;
4352c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  return(ret);
4353c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard}
4354c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4355c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* Store a value into a previously registered B code type. */
4356c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4357c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardstatic void
4358c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardremember_Btype (work, start, len, ind)
4359c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard     struct work_stuff *work;
4360c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard     const char *start;
4361c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard     int len, ind;
4362c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard{
4363c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  char *tem;
4364c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4365c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  tem = xmalloc (len + 1);
4366c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  memcpy (tem, start, len);
4367c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  tem[len] = '\0';
4368c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  work -> btypevec[ind] = tem;
4369ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard}
4370ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard
4371c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* Lose all the info related to B and K type codes. */
4372c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardstatic void
4373c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardforget_B_and_K_types (work)
4374c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard     struct work_stuff *work;
4375c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard{
4376c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  int i;
4377c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4378c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  while (work -> numk > 0)
4379c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    {
4380c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      i = --(work -> numk);
4381c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      if (work -> ktypevec[i] != NULL)
4382c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	{
4383c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  free (work -> ktypevec[i]);
4384c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  work -> ktypevec[i] = NULL;
4385c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
4386c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
4387c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4388c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  while (work -> numb > 0)
4389c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    {
4390c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      i = --(work -> numb);
4391c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      if (work -> btypevec[i] != NULL)
4392c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	{
4393c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  free (work -> btypevec[i]);
4394c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  work -> btypevec[i] = NULL;
4395c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
4396c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
4397c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard}
4398c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* Forget the remembered types, but not the type vector itself.  */
4399c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4400c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardstatic void
4401c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardforget_types (work)
4402c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard     struct work_stuff *work;
4403c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard{
4404c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  int i;
4405c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4406c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard  while (work -> ntypes > 0)
4407c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    {
4408c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      i = --(work -> ntypes);
4409c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard      if (work -> typevec[i] != NULL)
4410c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	{
4411c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  free (work -> typevec[i]);
4412c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	  work -> typevec[i] = NULL;
4413c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard	}
4414c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard    }
4415c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard}
4416c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4417c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* Process the argument list part of the signature, after any class spec
4418c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   has been consumed, as well as the first 'F' character (if any).  For
4419c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   example:
4420c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4421c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   "__als__3fooRT0"		=>	process "RT0"
4422c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
4423c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4424c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   DECLP must be already initialised, usually non-empty.  It won't be freed
4425c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   on failure.
4426c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard
4427c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard   Note that g++ differs significantly from ARM and lucid style mangling
442801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard   with regards to references to previously seen types.  For example, given
44294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   the source fragment:
44304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     class foo {
44324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard       public:
44334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard       foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
44344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     };
44354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
44374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
44384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4439dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel Veillard   g++ produces the names:
4440118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard
44414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     __3fooiRT0iT2iT2
44424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     foo__FiR3fooiT1iT1
44434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   while lcc (and presumably other ARM style compilers as well) produces:
4445ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard
4446ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard     foo__FiR3fooT1T2T1T2
44474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     __ct__3fooFiR3fooT1T2T1T2
44484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   Note that g++ bases its type numbers starting at zero and counts all
44504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   previously seen types, while lucid/ARM bases its type numbers starting
44514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   at one and only considers types after it has seen the 'F' character
44524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   indicating the start of the function args.  For lucid/ARM style, we
445301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard   account for this difference by discarding any previously seen types when
44544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   we see the 'F' character, and subtracting one from the type number
44554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard   reference.
44564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
44584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
44598bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstatic int
44604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillarddemangle_args (work, mangled, declp)
44614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     struct work_stuff *work;
44624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     const char **mangled;
44634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     string *declp;
44645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{
446501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard  string arg;
4466070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int need_comma = 0;
4467070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int r;
4468070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  int t;
44698bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard  const char *tem;
4470070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  char temptype;
4471070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
4472070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  if (PRINT_ARG_TYPES)
4473070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
44745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      string_append (declp, "(");
447501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard      if (**mangled == '\0')
4476070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	{
4477070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  string_append (declp, "void");
4478070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	}
44798bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    }
4480070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
4481070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard  while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4482070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	 || work->nrepeats > 0)
4483070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard    {
44845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard      if ((**mangled == 'N') || (**mangled == 'T'))
448501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	{
4486070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  temptype = *(*mangled)++;
4487070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard
4488070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	  if (temptype == 'N')
44898bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	    {
4490070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard	      if (!get_count (mangled, &r))
4491070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		{
4492070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		  return (0);
4493070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard		}
44945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard	    }
449501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  else
44968651f5365c182ce5c52fe1cdc2b9d72b2ecc34e2Daniel Veillard	    {
44978bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	      r = 1;
449801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    }
449901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard          if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
450001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard            {
450101fa6156e51259229470f40619af93e915b4bc94Daniel Veillard              /* If we have 10 or more types we might have more than a 1 digit
450201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard                 index so we'll have to consume the whole count here. This
45038651f5365c182ce5c52fe1cdc2b9d72b2ecc34e2Daniel Veillard                 will lose if the next thing is a type name preceded by a
45048bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard                 count but it's impossible to demangle that case properly
45058bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard                 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
45068bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard                 Pc, ...)"  or "(..., type12, char *, ...)" */
45078bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard              if ((t = consume_count(mangled)) <= 0)
450801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard                {
45098bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard                  return (0);
4510e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard                }
45118bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard            }
45128bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard          else
4513e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard	    {
45148bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	      if (!get_count (mangled, &t))
4515e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	    	{
4516e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	          return (0);
45178bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	    	}
45188bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	    }
45198bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4520560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    {
452170bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard	      t--;
45221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	    }
45231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	  /* Validate the type index.  Protect against illegal indices from
45241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard	     malformed type strings.  */
452501fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  if ((t < 0) || (t >= work -> ntypes))
4526560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    {
4527560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      return (0);
4528560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    }
4529560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	  while (work->nrepeats > 0 || --r >= 0)
4530560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    {
4531560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      tem = work -> typevec[t];
4532560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      if (need_comma && PRINT_ARG_TYPES)
4533560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard		{
453470bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard		  string_append (declp, ", ");
453570bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard		}
4536560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      if (!do_arg (work, &tem, &arg))
453701fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		{
453801fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		  return (0);
453901fa6156e51259229470f40619af93e915b4bc94Daniel Veillard		}
454001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	      if (PRINT_ARG_TYPES)
4541fbf2c5eaf550a8e7b94e87d5a4940db53bdffeacWilliam M. Brack		{
4542fbf2c5eaf550a8e7b94e87d5a4940db53bdffeacWilliam M. Brack		  string_appends (declp, &arg);
454370bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard		}
4544560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      string_delete (&arg);
4545560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      need_comma = 1;
454670bcb0ea2464e1619f54dc56334b043767d793dcDaniel Veillard	    }
45478bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	}
45488bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard      else
4549e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	{
455001fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	  if (need_comma && PRINT_ARG_TYPES)
45518bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	    string_append (declp, ", ");
4552e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	  if (!do_arg (work, mangled, &arg))
455301fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    {
45548bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	      string_delete (&arg);
4555e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard	      return (0);
455601fa6156e51259229470f40619af93e915b4bc94Daniel Veillard	    }
4557e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard	  if (PRINT_ARG_TYPES)
45588bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	    string_appends (declp, &arg);
45598bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard	  string_delete (&arg);
4560560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	  need_comma = 1;
4561560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	}
4562560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    }
4563560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard
4564560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  if (**mangled == 'e')
4565560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    {
4566560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      (*mangled)++;
4567560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      if (PRINT_ARG_TYPES)
4568560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	{
4569560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	  if (need_comma)
4570560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    {
4571560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	      string_append (declp, ",");
4572560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	    }
4573560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	  string_append (declp, "...");
4574560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard	}
4575560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    }
4576560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard
4577560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  if (PRINT_ARG_TYPES)
4578560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    {
4579560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard      string_append (declp, ")");
4580560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard    }
4581560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  return (1);
4582560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard}
4583560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard
4584560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard/* Like demangle_args, but for demangling the argument lists of function
4585560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard   and method pointers or references, not top-level declarations.  */
4586560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard
4587560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillardstatic int
458801fa6156e51259229470f40619af93e915b4bc94Daniel Veillarddemangle_nested_args (work, mangled, declp)
4589560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard     struct work_stuff *work;
4590560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard     const char **mangled;
4591560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard     string *declp;
459201fa6156e51259229470f40619af93e915b4bc94Daniel Veillard{
4593560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  string* saved_previous_argument;
4594560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard  int result;
45954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  int saved_nrepeats;
45964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
45974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  /* The G++ name-mangling algorithm does not remember types on nested
45984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     argument lists, unless -fsquangling is used, and in that case the
4599b6c7f415b76d24b72119057688056374e7b062bbDaniel Veillard     type vector updated by remember_type is not used.  So, we turn
46004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     off remembering of types here.  */
46014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard  ++work->forgetting_types;
46026e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46036e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* For the repeat codes used with -fsquangling, we must keep track of
46046e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     the last argument.  */
46056e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  saved_previous_argument = work->previous_argument;
46066e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  saved_nrepeats = work->nrepeats;
46076e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  work->previous_argument = 0;
46086e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  work->nrepeats = 0;
46096e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46106e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* Actually demangle the arguments.  */
46116e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  result = demangle_args (work, mangled, declp);
46126e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46136e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* Restore the previous_argument field.  */
46146e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  if (work->previous_argument)
46156e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    {
46166e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      string_delete (work->previous_argument);
46176e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik      free ((char*) work->previous_argument);
46186e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik    }
46196e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  work->previous_argument = saved_previous_argument;
46206e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  --work->forgetting_types;
46216e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  work->nrepeats = saved_nrepeats;
46226e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46236e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  return result;
46246e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik}
46256e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46266e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikstatic void
46276e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcikdemangle_function_name (work, mangled, declp, scan)
46286e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     struct work_stuff *work;
46296e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     const char **mangled;
46306e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     string *declp;
46316e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     const char *scan;
46326e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik{
46336e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  size_t i;
46346e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string type;
46356e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  const char *tem;
46366e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46376e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_appendn (declp, (*mangled), scan - (*mangled));
46386e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  string_need (declp, 1);
46396e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  *(declp -> p) = '\0';
46406e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46416e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* Consume the function name, including the "__" separating the name
46426e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     from the signature.  We are guaranteed that SCAN points to the
46436e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     separator.  */
46446e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik
46456e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  (*mangled) = scan + 2;
46466e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik  /* We may be looking at an instantiation of a template function:
46476e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
46486e224f1272bc2a7d069b72f70b3ce737caf3cf81Kasimier T. Buchcik     following _F marks the start of the function arguments.  Handle
46494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     the template arguments first. */
4650
4651  if (HP_DEMANGLING && (**mangled == 'X'))
4652    {
4653      demangle_arm_hp_template (work, mangled, 0, declp);
4654      /* This leaves MANGLED pointing to the 'F' marking func args */
4655    }
4656
4657  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4658    {
4659
4660      /* See if we have an ARM style constructor or destructor operator.
4661	 If so, then just record it, clear the decl, and return.
4662	 We can't build the actual constructor/destructor decl until later,
4663	 when we recover the class name from the signature.  */
4664
4665      if (strcmp (declp -> b, "__ct") == 0)
4666	{
4667	  work -> constructor += 1;
4668	  string_clear (declp);
4669	  return;
4670	}
4671      else if (strcmp (declp -> b, "__dt") == 0)
4672	{
4673	  work -> destructor += 1;
4674	  string_clear (declp);
4675	  return;
4676	}
4677    }
4678
4679  if (declp->p - declp->b >= 3
4680      && declp->b[0] == 'o'
4681      && declp->b[1] == 'p'
4682      && strchr (cplus_markers, declp->b[2]) != NULL)
4683    {
4684      /* see if it's an assignment expression */
4685      if (declp->p - declp->b >= 10 /* op$assign_ */
4686	  && memcmp (declp->b + 3, "assign_", 7) == 0)
4687	{
4688	  for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++)
4689	    {
4690	      int len = declp->p - declp->b - 10;
4691	      if ((int) strlen (optable[i].in) == len
4692		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
4693		{
4694		  string_clear (declp);
4695		  string_append (declp, "operator");
4696		  string_append (declp, optable[i].out);
4697		  string_append (declp, "=");
4698		  break;
4699		}
4700	    }
4701	}
4702      else
4703	{
4704	  for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++)
4705	    {
4706	      int len = declp->p - declp->b - 3;
4707	      if ((int) strlen (optable[i].in) == len
4708		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
4709		{
4710		  string_clear (declp);
4711		  string_append (declp, "operator");
4712		  string_append (declp, optable[i].out);
4713		  break;
4714		}
4715	    }
4716	}
4717    }
4718  else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4719	   && strchr (cplus_markers, declp->b[4]) != NULL)
4720    {
4721      /* type conversion operator */
4722      tem = declp->b + 5;
4723      if (do_type (work, &tem, &type))
4724	{
4725	  string_clear (declp);
4726	  string_append (declp, "operator ");
4727	  string_appends (declp, &type);
4728	  string_delete (&type);
4729	}
4730    }
4731  else if (declp->b[0] == '_' && declp->b[1] == '_'
4732	   && declp->b[2] == 'o' && declp->b[3] == 'p')
4733    {
4734      /* ANSI.  */
4735      /* type conversion operator.  */
4736      tem = declp->b + 4;
4737      if (do_type (work, &tem, &type))
4738	{
4739	  string_clear (declp);
4740	  string_append (declp, "operator ");
4741	  string_appends (declp, &type);
4742	  string_delete (&type);
4743	}
4744    }
4745  else if (declp->b[0] == '_' && declp->b[1] == '_'
4746	   && ISLOWER((unsigned char)declp->b[2])
4747	   && ISLOWER((unsigned char)declp->b[3]))
4748    {
4749      if (declp->b[4] == '\0')
4750	{
4751	  /* Operator.  */
4752	  for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++)
4753	    {
4754	      if (strlen (optable[i].in) == 2
4755		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4756		{
4757		  string_clear (declp);
4758		  string_append (declp, "operator");
4759		  string_append (declp, optable[i].out);
4760		  break;
4761		}
4762	    }
4763	}
4764
4765      /* BEGIN hack inserted 20050403 by JRS to deal with apparently
4766         non-cfront compliant new[]/delete[] manglings generated by
4767         the Portland Group's C++ compiler. */
4768      else
4769      if (strcmp (declp -> b, "__nwa") == 0) {
4770         string_clear (declp);
4771         string_append (declp, "operator new[]");
4772      }
4773      else
4774      if (strcmp (declp -> b, "__dla") == 0) {
4775         string_clear (declp);
4776         string_append (declp, "operator delete[]");
4777      }
4778      /* END hack */
4779
4780      else
4781	{
4782	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
4783	    {
4784	      /* Assignment.  */
4785	      for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++)
4786		{
4787		  if (strlen (optable[i].in) == 3
4788		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4789		    {
4790		      string_clear (declp);
4791		      string_append (declp, "operator");
4792		      string_append (declp, optable[i].out);
4793		      break;
4794		    }
4795		}
4796	    }
4797	}
4798    }
4799}
4800
4801/* a mini string-handling package */
4802
4803static void
4804string_need (s, n)
4805     string *s;
4806     int n;
4807{
4808  int tem;
4809
4810  if (s->b == NULL)
4811    {
4812      if (n < 32)
4813	{
4814	  n = 32;
4815	}
4816      s->p = s->b = xmalloc (n);
4817      s->e = s->b + n;
4818    }
4819  else if (s->e - s->p < n)
4820    {
4821      tem = s->p - s->b;
4822      n += tem;
4823      n *= 2;
4824      s->b = xrealloc (s->b, n);
4825      s->p = s->b + tem;
4826      s->e = s->b + n;
4827    }
4828}
4829
4830static void
4831string_delete (s)
4832     string *s;
4833{
4834  if (s->b != NULL)
4835    {
4836      free (s->b);
4837      s->b = s->e = s->p = NULL;
4838    }
4839}
4840
4841static void
4842string_init (s)
4843     string *s;
4844{
4845  s->b = s->p = s->e = NULL;
4846}
4847
4848static void
4849string_clear (s)
4850     string *s;
4851{
4852  s->p = s->b;
4853}
4854
4855#if 0
4856
4857static int
4858string_empty (s)
4859     string *s;
4860{
4861  return (s->b == s->p);
4862}
4863
4864#endif
4865
4866static void
4867string_append (p, s)
4868     string *p;
4869     const char *s;
4870{
4871  int n;
4872  if (s == NULL || *s == '\0')
4873    return;
4874  n = strlen (s);
4875  string_need (p, n);
4876  memcpy (p->p, s, n);
4877  p->p += n;
4878}
4879
4880static void
4881string_appends (p, s)
4882     string *p, *s;
4883{
4884  int n;
4885
4886  if (s->b != s->p)
4887    {
4888      n = s->p - s->b;
4889      string_need (p, n);
4890      memcpy (p->p, s->b, n);
4891      p->p += n;
4892    }
4893}
4894
4895static void
4896string_appendn (p, s, n)
4897     string *p;
4898     const char *s;
4899     int n;
4900{
4901  if (n != 0)
4902    {
4903      string_need (p, n);
4904      memcpy (p->p, s, n);
4905      p->p += n;
4906    }
4907}
4908
4909static void
4910string_prepend (p, s)
4911     string *p;
4912     const char *s;
4913{
4914  if (s != NULL && *s != '\0')
4915    {
4916      string_prependn (p, s, strlen (s));
4917    }
4918}
4919
4920static void
4921string_prepends (p, s)
4922     string *p, *s;
4923{
4924  if (s->b != s->p)
4925    {
4926      string_prependn (p, s->b, s->p - s->b);
4927    }
4928}
4929
4930static void
4931string_prependn (p, s, n)
4932     string *p;
4933     const char *s;
4934     int n;
4935{
4936  char *q;
4937
4938  if (n != 0)
4939    {
4940      string_need (p, n);
4941      for (q = p->p - 1; q >= p->b; q--)
4942	{
4943	  q[n] = q[0];
4944	}
4945      memcpy (p->b, s, n);
4946      p->p += n;
4947    }
4948}
4949
4950static void
4951string_append_template_idx (s, idx)
4952     string *s;
4953     int idx;
4954{
4955  char buf[INTBUF_SIZE + 1 /* 'T' */];
4956  sprintf(buf, "T%d", idx);
4957  string_append (s, buf);
4958}
4959
4960/* To generate a standalone demangler program for testing purposes,
4961   just compile and link this file with -DMAIN and libiberty.a.  When
4962   run, it demangles each command line arg, or each stdin string, and
4963   prints the result on stdout.  */
4964
4965#ifdef MAIN
4966
4967#include "getopt.h"
4968
4969static const char *program_name;
4970static const char *program_version = VERSION;
4971static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
4972
4973static void demangle_it PARAMS ((char *));
4974static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4975static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4976static void print_demangler_list PARAMS ((FILE *));
4977
4978static void
4979demangle_it (mangled_name)
4980     char *mangled_name;
4981{
4982  char *result;
4983
4984  /* For command line args, also try to demangle type encodings.  */
4985  result = cplus_demangle (mangled_name, flags | DMGL_TYPES);
4986  if (result == NULL)
4987    {
4988      printf ("%s\n", mangled_name);
4989    }
4990  else
4991    {
4992      printf ("%s\n", result);
4993      free (result);
4994    }
4995}
4996
4997static void
4998print_demangler_list (stream)
4999     FILE *stream;
5000{
5001  const struct demangler_engine *demangler;
5002
5003  fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
5004
5005  for (demangler = libiberty_demanglers + 1;
5006       demangler->demangling_style != unknown_demangling;
5007       ++demangler)
5008    fprintf (stream, ",%s", demangler->demangling_style_name);
5009
5010  fprintf (stream, "}");
5011}
5012
5013static void
5014usage (stream, status)
5015     FILE *stream;
5016     int status;
5017{
5018  fprintf (stream, "\
5019Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
5020	   program_name);
5021
5022  fprintf (stream, "\
5023       [-s ");
5024  print_demangler_list (stream);
5025  fprintf (stream, "]\n");
5026
5027  fprintf (stream, "\
5028       [--format ");
5029  print_demangler_list (stream);
5030  fprintf (stream, "]\n");
5031
5032  fprintf (stream, "\
5033       [--help] [--version] [arg...]\n");
5034  exit (status);
5035}
5036
5037#define MBUF_SIZE 32767
5038char mbuffer[MBUF_SIZE];
5039
5040/* Defined in the automatically-generated underscore.c.  */
5041extern int prepends_underscore;
5042
5043int strip_underscore = 0;
5044
5045static const struct option long_options[] = {
5046  {"strip-underscores", no_argument, 0, '_'},
5047  {"format", required_argument, 0, 's'},
5048  {"help", no_argument, 0, 'h'},
5049  {"no-strip-underscores", no_argument, 0, 'n'},
5050  {"version", no_argument, 0, 'v'},
5051  {0, no_argument, 0, 0}
5052};
5053
5054/* More 'friendly' abort that prints the line and file.
5055   config.h can #define abort fancy_abort if you like that sort of thing.  */
5056
5057void
5058fancy_abort ()
5059{
5060  fatal ("Internal gcc abort.");
5061}
5062
5063
5064static const char *
5065standard_symbol_characters PARAMS ((void));
5066
5067static const char *
5068hp_symbol_characters PARAMS ((void));
5069
5070static const char *
5071gnu_v3_symbol_characters PARAMS ((void));
5072
5073/* Return the string of non-alnum characters that may occur
5074   as a valid symbol component, in the standard assembler symbol
5075   syntax.  */
5076
5077static const char *
5078standard_symbol_characters ()
5079{
5080  return "_$.";
5081}
5082
5083
5084/* Return the string of non-alnum characters that may occur
5085   as a valid symbol name component in an HP object file.
5086
5087   Note that, since HP's compiler generates object code straight from
5088   C++ source, without going through an assembler, its mangled
5089   identifiers can use all sorts of characters that no assembler would
5090   tolerate, so the alphabet this function creates is a little odd.
5091   Here are some sample mangled identifiers offered by HP:
5092
5093	typeid*__XT24AddressIndExpClassMember_
5094	[Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
5095	__ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
5096
5097   This still seems really weird to me, since nowhere else in this
5098   file is there anything to recognize curly brackets, parens, etc.
5099   I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
5100   this is right, but I still strongly suspect that there's a
5101   misunderstanding here.
5102
5103   If we decide it's better for c++filt to use HP's assembler syntax
5104   to scrape identifiers out of its input, here's the definition of
5105   the symbol name syntax from the HP assembler manual:
5106
5107       Symbols are composed of uppercase and lowercase letters, decimal
5108       digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
5109       underscore (_). A symbol can begin with a letter, digit underscore or
5110       dollar sign. If a symbol begins with a digit, it must contain a
5111       non-digit character.
5112
5113   So have fun.  */
5114static const char *
5115hp_symbol_characters ()
5116{
5117  return "_$.<>#,*&[]:(){}";
5118}
5119
5120
5121/* Return the string of non-alnum characters that may occur
5122   as a valid symbol component in the GNU C++ V3 ABI mangling
5123   scheme.  */
5124
5125static const char *
5126gnu_v3_symbol_characters ()
5127{
5128  return "_$.";
5129}
5130
5131
5132extern int main PARAMS ((int, char **));
5133
5134int
5135main (argc, argv)
5136     int argc;
5137     char **argv;
5138{
5139  char *result;
5140  int c;
5141  const char *valid_symbols;
5142  enum demangling_styles style = auto_demangling;
5143
5144  program_name = argv[0];
5145
5146  strip_underscore = prepends_underscore;
5147
5148  while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
5149    {
5150      switch (c)
5151	{
5152	case '?':
5153	  usage (stderr, 1);
5154	  break;
5155	case 'h':
5156	  usage (stdout, 0);
5157	case 'n':
5158	  strip_underscore = 0;
5159	  break;
5160	case 'v':
5161	  printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
5162	  return (0);
5163	case '_':
5164	  strip_underscore = 1;
5165	  break;
5166	case 's':
5167	  {
5168	    style = cplus_demangle_name_to_style (optarg);
5169	    if (style == unknown_demangling)
5170	      {
5171		fprintf (stderr, "%s: unknown demangling style `%s'\n",
5172			 program_name, optarg);
5173		return (1);
5174	      }
5175	    else
5176	      cplus_demangle_set_style (style);
5177	  }
5178	  break;
5179	}
5180    }
5181
5182  if (optind < argc)
5183    {
5184      for ( ; optind < argc; optind++)
5185	{
5186	  demangle_it (argv[optind]);
5187	}
5188    }
5189  else
5190    {
5191      switch (current_demangling_style)
5192	{
5193	case gnu_demangling:
5194	case lucid_demangling:
5195	case arm_demangling:
5196	case java_demangling:
5197	case edg_demangling:
5198	case gnat_demangling:
5199	case auto_demangling:
5200	  valid_symbols = standard_symbol_characters ();
5201	  break;
5202	case hp_demangling:
5203	  valid_symbols = hp_symbol_characters ();
5204	  break;
5205	case gnu_v3_demangling:
5206	  valid_symbols = gnu_v3_symbol_characters ();
5207	  break;
5208	default:
5209	  /* Folks should explicitly indicate the appropriate alphabet for
5210	     each demangling.  Providing a default would allow the
5211	     question to go unconsidered.  */
5212	  abort ();
5213	}
5214
5215      for (;;)
5216	{
5217	  int i = 0;
5218	  c = getchar ();
5219	  /* Try to read a label.  */
5220	  while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
5221	    {
5222	      if (i >= MBUF_SIZE-1)
5223		break;
5224	      mbuffer[i++] = c;
5225	      c = getchar ();
5226	    }
5227	  if (i > 0)
5228	    {
5229	      int skip_first = 0;
5230
5231	      if (mbuffer[0] == '.' || mbuffer[0] == '$')
5232		++skip_first;
5233	      if (strip_underscore && mbuffer[skip_first] == '_')
5234		++skip_first;
5235
5236	      if (skip_first > i)
5237		skip_first = i;
5238
5239	      mbuffer[i] = 0;
5240	      flags |= (int) style;
5241	      result = cplus_demangle (mbuffer + skip_first, flags);
5242	      if (result)
5243		{
5244		  if (mbuffer[0] == '.')
5245		    putc ('.', stdout);
5246		  fputs (result, stdout);
5247		  free (result);
5248		}
5249	      else
5250		fputs (mbuffer, stdout);
5251
5252	      fflush (stdout);
5253	    }
5254	  if (c == EOF)
5255	    break;
5256	  putchar (c);
5257	  fflush (stdout);
5258	}
5259    }
5260
5261  return (0);
5262}
5263
5264static void
5265fatal (str)
5266     const char *str;
5267{
5268  fprintf (stderr, "%s: %s\n", program_name, str);
5269  exit (1);
5270}
5271
5272PTR
5273xmalloc (size)
5274  size_t size;
5275{
5276  register PTR value = (PTR) malloc (size);
5277  if (value == 0)
5278    fatal ("virtual memory exhausted");
5279  return value;
5280}
5281
5282PTR
5283xrealloc (ptr, size)
5284  PTR ptr;
5285  size_t size;
5286{
5287  register PTR value = (PTR) realloc (ptr, size);
5288  if (value == 0)
5289    fatal ("virtual memory exhausted");
5290  return value;
5291}
5292#endif	/* main */
5293